canvas has been tainted by cross-origin data work

2019-01-14 08:51发布

问题:

im writing a script (or editing and hacking things together) to edit the look of images on a page. I know the basics of javascript but this is my first time looking at canvas. so bear with me

I'm getting this error:

Unable to get image data from canvas because the canvas has been tainted by cross-origin data.

so heres my code snippet throwing the error:

var canvas = document.createElement('canvas'),
            context = canvas.getContext('2d'),
            height = img.naturalHeight || img.offsetHeight || img.height,
            width = img.naturalWidth || img.offsetWidth || img.width,
            imgData;


        canvas.height = height;
        canvas.width = width;
        context.drawImage(img, 0, 0);

        console.log(context);
        try {
            imgData = context.getImageData(0, 0, width, height);
        } catch(e) {}

now i found this post :

http://bolsterweb.com/2012/06/grabbing-image-data-external-source-canvas-element/

but i have no idea how to make it fit my needs..

I know its all due to security and all that - but is there a work around to make it all happen?

Thanks

EDIT

Oh wait.. the error is because you can't getImageData.. so is there away to make it 'local'

回答1:

To satisfy CORS, you can host your images on a CORS friendly site like dropbox.com

Then the security error will not be triggered if you speify image.crossOrigin="anonymous":

    var image=new Image();
    image.onload=function(){
    }
    image.crossOrigin="anonymous";
    image.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/colorhouse.png";

Here is code and a Fiddle: http://jsfiddle.net/m1erickson/4djSr/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; }
    #canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    var image=new Image();
    image.onload=function(){
        ctx.drawImage(image,0,0);

        // desaturation colors
        var imgData=ctx.getImageData(0,0,canvas.width,canvas.height);
        var data=imgData.data;

        for(var i = 0; i < data.length; i += 4) {
          var grayscale= 0.33*data[i]+0.5*data[i+1]+0.15*data[i+2];
          data[i]=grayscale;
          data[i+1]=grayscale;
          data[i+2]=grayscale;
        }

        // write the modified image data
        ctx.putImageData(imgData,0,0);

    }
    image.crossOrigin="anonymous";
    image.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/colorhouse.png";



}); // end $(function(){});
</script>

</head>

<body>
    <canvas id="canvas" width=140 height=140></canvas>
</body>
</html>


回答2:

I don't have enough reputation to actually add a comment (but I do have enough to respond to the question, huh??), I just wanted to add to markE's answer that I had to capitalize Anonymous.

image.crossOrigin = "Anonymous"


回答3:

I found it works with chrome if you create a windows shortcut like this:

"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --allow-file-access-from-files

Shut down chrome and start it via your shortcut.

Source: https://github.com/mrdoob/three.js/wiki/How-to-run-things-locally

Related post: Cross-origin image load denied on a local image with THREE.js on Chrome

I assume you are working with a local file without any web server.



回答4:

Try adding crossorigin="anonymous" to the image element. For example

<img src="http://example.com/foo.jpg" crossorigin="anonymous"/>


回答5:

Enabling CORS on the server side is a way out, But that's if you have access to the server side. That way the server serves CORS enabled images.