2

当我尝试通过 getImageData 方法获取图像的像素时,出现此错误

“无法从画布获取图像数据,因为画布已被跨域数据污染。未捕获的错误:SecurityError:DOM Exception 18”

图像在标头响应中有Access-Control-Allow-Origin: *。所以,我不明白为什么会出现这个错误。我必须做些什么来解决这个问题?

我尝试将属性 crossOrigin 添加到图像中,但这在 Safari 中不起作用。我正在处理的代码如下。

<html>
<head>
<title>Example</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
    var img = new Image();
    img.onload = function() {
        var ctx = $('#cnv')[0].getContext('2d');
        ctx.drawImage(this, 0, 0);
        var originalImageData = ctx.getImageData(0, 0, 300, 300); // Exception 18
    };
    img.src = 'http://api.thumbr.it/1f86404a001828912f295a74b8a4d337/D-lvXHFIHpY/api.thumbr.it/static/ladies-800.png/400x400c-ebrown-eframe1/thumb.jpg';
    $('body').append(img);
</script>
</head>
<body>
<h1>Example</h1>
<img class="image" id="img-rara" src="http://api.thumbr.it/f4414f15f6d6d2639a17c6e1c025d970/D-lvXHFIHpY/api.thumbr.it/static/ladies-800.png/400x400c-ebarcelona-eframe1/thumb.jpg" />
<canvas id="cnv" width="711" height="400" />
</body>
</html>
4

2 回答 2

2

在客户端,请务必crossOrigin在设置 img.src 之前设置标志

img.crossOrigin='anonymous' 

这是您的跨域访问设置为匿名的代码:

<html>
<head>
<title>Example</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
    var img = new Image();
    img.onload = function() {
        var ctx = $('#cnv')[0].getContext('2d');
        ctx.drawImage(this, 0, 0);
        var originalImageData = ctx.getImageData(0, 0, 300, 300); // Exception 18
    };

    // allow cross-origin access
    img.crossOrigin='anonymous' 

    img.src = 'http://api.thumbr.it/1f86404a001828912f295a74b8a4d337/D-lvXHFIHpY/api.thumbr.it/static/ladies-800.png/400x400c-ebrown-eframe1/thumb.jpg';
    $('body').append(img);
</script>
</head>
<body>
<h1>Example</h1>
<img class="image" id="img-rara" src="http://api.thumbr.it/f4414f15f6d6d2639a17c6e1c025d970/D-lvXHFIHpY/api.thumbr.it/static/ladies-800.png/400x400c-ebarcelona-eframe1/thumb.jpg" />
<canvas id="cnv" width="711" height="400" />
</body>
</html>
于 2013-04-26T15:08:14.373 回答
0

我找到了另一种通过 XMLHttpRequest 解决这个问题的方法。此解决方案适用于 Chrome、Safari、Firefox 和 Opera,但不适用于 IE。访问此页面http://jsperf.com/encoding-xhr-image-data/12了解更多信息。

<html>
<head>
<title>Example</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
    // See: http://jsperf.com/encoding-xhr-image-data/12
    $('body').ready(function(){
        data = getImageData(
            'http://api.thumbr.it/1f86404a001828912f295a74b8a4d337/D-lvXHFIHpY/api.thumbr.it/static/ladies-800.png/400x400c-ebrown-eframe1/thumb.jpg');
    });
    function getImageData(url) {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', url, false);
        xhr.overrideMimeType('text/plain; charset=x-user-defined');
        xhr.send();

        var img = $('<img>');
        img.attr(
            'src',
            'data:image/' + getType(xhr.responseText.slice(0, 4)) + ';base64,' + getDataBase64(xhr.responseText)
        );
        img.load(function() {
            var ctx = $('#cnv')[0].getContext('2d');
            ctx.drawImage(img[0], 0, 0);
            data = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height); // Data!!
        });
    }
    function getDataBase64(data) {
        var binary = '';
        for (var i = 0; i < data.length; i+=4) {
            binary += String.fromCharCode(
                data.charCodeAt(i+0) & 0xff,
                data.charCodeAt(i+1) & 0xff,
                data.charCodeAt(i+2) & 0xff,
                data.charCodeAt(i+3) & 0xff
            );
        }
        for (i-=4; i < data.length; i+=1) {
            binary += String.fromCharCode(data.charCodeAt(i) & 0xff);
        }
        return window.btoa(binary);
    }
    function getType(data) {
        if (data.search('PNG') >= 0) {
            return 'png';
        } else if (data.search('GIF') >= 0) {
            return 'gif';
        } else {
            return 'jpeg';
        }
    }
</script>
</head>
<body>
<h1>Example</h1>
<img class="image" id="img-rara" src="http://api.thumbr.it/f4414f15f6d6d2639a17c6e1c025d970/D-lvXHFIHpY/api.thumbr.it/static/ladies-800.png/400x400c-ebarcelona-eframe1/thumb.jpg" />
<canvas id="cnv" width="400" height="400" />
</body>
</html>
于 2013-04-29T14:57:22.113 回答