【问题标题】:possible to use html images like canvas with getImageData / putImageData?可以使用 getImageData / putImageData 之类的 html 图像吗?
【发布时间】:2010-11-29 13:45:04
【问题描述】:

我想知道是否有一种方法可以动态修改/访问 html 图像中包含的数据,就像它们是 html5 画布元素一样。使用画布,您可以在 javascript 中使用 getImageData() 和 putImageData() 访问原始像素数据,但到目前为止我还无法弄清楚如何处理图像。

【问题讨论】:

    标签: image html canvas getimagedata


    【解决方案1】:
        // 1) Create a canvas, either on the page or simply in code
        var canvas = document.createElement('canvas');
        var ctx    = canvas.getContext('2d');
    
        // 2) Copy your image data into the canvas
        var myImgElement = document.getElementById('foo');
        ctx.drawImage( myImgElement, 0, 0 );
    
        // 3) Read your image data
        var w = myImgElement.width, h=myImgElement.height;
        var imgdata = ctx.getImageData(0,0,w,h);
        var rgba = imgdata.data;
        
        // 4) Read or manipulate the rgba as you wish
        for (var px=0,ct=w*h*4;px<ct;px+=4){
          var r = rgba[px  ];
          var g = rgba[px+1];
          var b = rgba[px+2];
          var a = rgba[px+3];
        }
    
        // 5) Update the context with newly-modified data
        ctx.putImageData(imgdata,0,0);
    
        // 6) Draw the image data elsewhere, if you wish
        someOtherContext.drawImage( ctx.canvas, 0, 0 );
    

    请注意,步骤 2 也可以从直接加载到脚本中的图像引入,而不是在页面上:

        // 2b) Load an image from which to get data
        var img = new Image;
        img.onload = function(){
          ctx.drawImage( img, 0, 0 );
          // ...and then steps 3 and on
        };
        img.src = "/images/foo.png"; // set this *after* onload
    

    【讨论】:

    • 你的代码不起作用,someOtherContext.drawImage(ctx,0,0);不断抛出“类型错误”,因为第一个属性必须是图像,而不是上下文(chrome 7,firefox 3.6)
    • 如果要遍历图像中的所有像素,第 4 步应该是 ...ct=w*h*4...,因为每个像素有四个值。
    • @dvh 我认为它是“画布”而不是 ctx。 drawImage 可以采用图像或画布。
    • 请注意,浏览器现在对从canvas 获取数据有一个跨域安全限制,因为它已经将来自域外的图像数据写入其中。例如,Chrome 的消息是 "Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data."
    【解决方案2】:

    在遇到此代码的一些问题后,我想在 Phrogz 的回答中添加一两件事:

    // 1) Create a canvas, either on the page or simply in code
    var myImgElement = document.getElementById('foo');
    var w = myImgElement.width, h=myImgElement.height; // New : you need to set the canvas size if you don't want bug with images that makes more than 300*150
    
    var canvas = document.createElement('canvas');
    canvas.height = h;
    canvas.width = w;
    var ctx    = canvas.getContext('2d');
    
    // 2) Copy your image data into the canvas
    ctx.drawImage( myImgElement, 0, 0, w, h ); // Just in case...
    
    // 3) Read your image data
    var imgdata = ctx.getImageData(0,0,w,h);
    var rgba = imgdata.data;
    
    // And then continue as in the other code !
    

    【讨论】:

      【解决方案3】:

      直接作用于IMG元素也是有效的:

      var image = document.createElement('img'),w,h ;
      
      image.src = "img/test.jpg" ;
      
      $(image).one('load',function(){
      
          w = image.naturalWidth ;
          h = image.naturalHeight ;
      
          var cnv = document.createElement('canvas') ;
          $(cnv).attr("width",w) ;
          $(cnv).attr("height",h) ;
      
          var ctx = cnv.getContext('2d') ;
          ctx.drawImage(image,0,0) ;
      
          var imgdata = ctx.getImageData(0,0,w,h) ;
      
          var rgba = imgdata.data ;
          for (var px=0,ct=w*h*4;px<ct;px+=4){
              var r = rgba[px+0] ;
              var g = rgba[px+1] ;
              var b = rgba[px+2] ;
              var a = rgba[px+3] ;
              // Do something
              rgba[px+0] = r ;
              rgba[px+1] = g ;
              rgba[px+2] = b ;
              rgba[px+3] = a ;
          }
      
          ctx.putImageData(imgdata,0,0) ;
      
          $("body").append(cnv) ;
      
      }) ;
      

      【讨论】:

        【解决方案4】:

        这对我有用(IE10x64,win7 上的 Chromex64,铬 arm linux,...似乎与 firefox 20 arm linux 有错误,但不确定...重新测试)

        --html--

        <canvas id="myCanvas" width="600" height="300"></canvas>
        <canvas id="myCanvasOffscreen" width="1" height="1"></canvas>
        

        -- js--

          // width & height can be used to scale image !!!
          function getImageAsImageData(url, width, height, callack) {
            var canvas = document.getElementById('myCanvasOffscreen');
            canvas.width = width;
            canvas.height = height;
            var context = canvas.getContext('2d');
        
            var imageObj = new Image();
            imageObj.onload = function() {
              context.drawImage(imageObj, 0, 0, width, height);
              imgData = context.getImageData(0,0,width, height);
              canvas.width = 1;
              canvas.height = 1;
        
              callack( imgData );
            };
            imageObj.src = url;
          }
        

        -- 然后--

          var canvas = document.getElementById('myCanvas');
          var ctx = canvas.getContext('2d');
        
          var imgData;
          getImageAsImageData('central_closed.png', IMG_WIDTH, IMG_HEIGHT, 
            function(imgData) {
        
              // do what you want with imgData.data (rgba array)
              // ex.  colorize( imgData, 25, 70, 0);
        
              ctx.putImageData(imgData,0,0);
        
            }
          );
        

        【讨论】:

          【解决方案5】:

          你想先在canvas上画个pic,然后从canvas中获取imageData,这是错误的方式,因为js认为是“跨域访问”,但是getIamgeData方法不允许对图像的“跨域访问”。您可以尝试通过将其放在根位置并通过“localhost”访问它。

          【讨论】:

            【解决方案6】:

            您可以使用drawImage() 将图像绘制到画布元素,然后从画布中获取像素数据。

            【讨论】:

            • 这不允许我自己操作图像数据,这是我想做的。
            • 图像复制到canvas 元素后,您可以按照通常操作canvas 像素数据的任何方式对其进行操作。
            【解决方案7】:

            我不确定这是否可能,但你可以尝试从 PHP 请求像素信息,如果是 GD 库,这将是一件容易的事,但肯定会慢一些。由于您没有指定应用程序,因此如果它们可以是矢量图像,我会建议检查 SVG 以完成此任务,而不是您将能够查询或修改图像。

            【讨论】:

            • 我想完全在浏览器中执行此操作,根本不使用任何服务器端脚本。
            • 您能否提供一些详细信息,这几乎不可能,但可能有其他解决方案。
            • 如果我要在某些软件中实际实现这一点,我可能会更新图像的 DOM 节点。但是,我的问题更多地针对“这可能吗?”的水平。了解有关 html 本身的更多信息。
            猜你喜欢
            • 2021-12-04
            • 2012-06-10
            • 1970-01-01
            • 1970-01-01
            • 2013-12-14
            • 2012-10-13
            • 2022-01-05
            • 1970-01-01
            相关资源
            最近更新 更多