【问题标题】:HTML 5 canvas getImageData from an externally-loaded image来自外部加载图像的 HTML 5 画布 getImageData
【发布时间】:2013-06-11 00:51:25
【问题描述】:

我知道出于安全原因,无法立即执行此操作。但是,我听说有一些图片托管网站允许以类似的方式使用他们的图片(Google Picasa?)。我可能都错了,但我想知道这是否属实,如果是,我怎样才能从这样的图像中获取图像数据。

提前谢谢你。

【问题讨论】:

    标签: javascript html canvas


    【解决方案1】:

    是的,有一些公共主机提供可用于 canvas 的 getImageData 的图像

    Dropbox 就是其中之一:http://www.dropbox.com

    要使用这些图片,您必须在加载图片时使用 context.crossOrigin='anonymous' 标志:

    var image=document.createElement("img");  // Chrome bug prevents var image=new Image();
    image.onload=function(){
    
            // in Chrome+Mozilla you can use context.getImageData
    
            // but IE still throws the CORS security error
    
    }
    image.crossOrigin = "Anonymous";
    image.src="www.CrossOriginSite.com/anyImage.png";
    

    剩下的一个“陷阱”是 IE 浏览器仍然不支持 crossOrigin 标志,因此 IE 仍然不允许您将这些图像与 getImageData 一起使用。

    Chrome 和 Mozilla 允许 getImageData 访问。

    例如...

    在 Chrome 或 Mozilla 中查看此 Fiddle 会成功,但在 IE 中仍会失败:

    http://jsfiddle.net/m1erickson/czmms/

    代码如下:

    <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 canvasCORS=document.getElementById("canvasCORS");
        var ctxCORS=canvasCORS.getContext("2d");
        var canvasAnonymous=document.getElementById("canvasAnonymous");
        var ctxAnonymous=canvasAnonymous.getContext("2d");
    
        // Using image WITHOUT crossOrigin=anonymous
        // Fails in all browsers
        var externalImage1=document.createElement("img");  // chrome bug prevents new Image();
        externalImage1.onload=function(){
            canvas.width=externalImage1.width;
            canvas.height=externalImage1.height;
            ctx.drawImage(externalImage1,0,0);
            // use getImageData to replace blue with yellow
            var imageData=recolorImage(externalImage1,0,0,255,255,255,0);
            // put the altered data back on the canvas  
            // this will FAIL on a CORS violation
            ctxCORS.putImageData(imageData,0,0);    
        }
        externalImage1.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/colorhouse.png";
    
        // Using image WITH crossOrigin=anonymous
        // Succeeds in Chrome+Mozilla, Still fails in IE
        var externalImage2=new Image();
        externalImage2.onload=function(){
            canvas.width=externalImage2.width;
            canvas.height=externalImage2.height;
            ctx.drawImage(externalImage2,0,0);
            // use getImageData to replace blue with yellow
            var imageData=recolorImage(externalImage2,0,0,255,255,255,0);
            // put the altered data back on the canvas  
            // this will FAIL on a CORS violation
            ctxAnonymous.putImageData(imageData,0,0);    
        }
        externalImage2.crossOrigin = "Anonymous";
        externalImage2.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/colorhouse.png";
    
    
        function recolorImage(img,oldRed,oldGreen,oldBlue,newRed,newGreen,newBlue){
            var c = document.createElement('canvas');
            var ctx=c.getContext("2d");
            var w = img.width;
            var h = img.height;
            c.width = w;
            c.height = h;
    
            // draw the image on the temporary canvas
            ctx.drawImage(img, 0, 0, w, h);
    
            // pull the entire image into an array of pixel data
            var imageData = ctx.getImageData(0, 0, w, h);
    
            // examine every pixel, 
            // change any old rgb to the new-rgb
            for (var i=0;i<imageData.data.length;i+=4)
              {
                  // is this pixel the old rgb?
                  if(imageData.data[i]==oldRed &&
                     imageData.data[i+1]==oldGreen &&
                     imageData.data[i+2]==oldBlue
                  ){
                      // change to your new rgb
                      imageData.data[i]=newRed;
                      imageData.data[i+1]=newGreen;
                      imageData.data[i+2]=newBlue;
                  }
              }
            return(imageData);
        }
    
    
    }); // end $(function(){});
    </script>
    
    </head>
    
    <body>
        <p>Original external image</p>
        <canvas id="canvas" width=140 height=140></canvas>
        <p>.getImageData with .crossOrigin='anonymous'
        <p>[Succeeds in Chrome+Mozilla, still fails in IE]</p>
        <canvas id="canvasAnonymous" width=140 height=140></canvas>
        <p>.getImageData without .crossOrigin='anonymous'
        <p>[Fails on all browsers]</p>
        <canvas id="canvasCORS" width=140 height=140></canvas>
    </body>
    </html>
    

    【讨论】:

    • 使用HTMLImageElement 中的naturalHeight 不是更好吗?
    猜你喜欢
    • 1970-01-01
    • 2014-03-25
    • 1970-01-01
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    • 2020-11-30
    • 2013-12-09
    相关资源
    最近更新 更多