getImageData() 返回全零

getImageData() returning all zeros

我正在尝试输出图像的像素值。图片加载正确;此处的另一个答案表明浏览器正在尝试在图像加载完成之前读取像素,但我可以看到它在 alert() 触发时已加载。

function initContext(canvasID, contextType)
{
   var canvas = document.getElementById(canvasID);
   var context = canvas.getContext(contextType);
   return context;
}

function loadImage(imageSource, context)
{
    var imageObj = new Image();
    imageObj.onload = function()
    {
        context.drawImage(imageObj, 0, 0);
    };
    imageObj.src = imageSource;
    return imageObj;
}

function readImage(imageData)
{
    console.log();
    console.log(imageData.data[0]);
}

var context = initContext('canvas','2d');
var imageObj = loadImage('images/color-test.png',context);
var imageData = context.getImageData(0,0,10,10);
alert();
readImage(imageData);

Image.onload() 在图像加载后异步调用。这可能发生在您当前的代码调用 context.getImageData().

之后

以下代码应该有效:

function initContext(canvasID, contextType)
{
   var canvas = document.getElementById(canvasID);
   var context = canvas.getContext(contextType);
   return context;
}

function loadImage(imageSource, context)
{
    var imageObj = new Image();
    imageObj.onload = function()
    {
        context.drawImage(imageObj, 0, 0);
        var imageData = context.getImageData(0,0,10,10);
        readImage(imageData);
    };
    imageObj.src = imageSource;
    return imageObj;
}

function readImage(imageData)
{
    console.log();
    console.log(imageData.data[0]);
}

var context = initContext('canvas','2d');
var imageObj = loadImage('images/color-test.png',context);

如果您想访问 loadImage() 之外的 imageData 值,您有 2 个基本选择:

  1. imageData 存储在函数外部声明的变量中。在这种情况下,在调用 onload() 之前,该值将被取消设置,因此外部代码必须在调用 readImage(imageData).
  2. 之前测试它的合理性
  3. 让外部代码注册一个回调函数,并让您的 onload() 使用 imageData 值调用该函数。

您也可能正在评估图像的透明部分。我在扫描 PNG 时遇到了这个问题。

分享一下我遇到的一个情况,我用循环同时请求多张图片,分别获取它们的像素点。然后我遇到了这个问题。

//my code looks like this
for(let i = 0; i < urls.length; ++i){
    let img = new Image() // it will be destoryed every loop begin, even if use keyword 'var' insteads of 'let'.  
    img.onload = ()=>{
      let canvas = document.createElement('canvas')
      let ctx = canvas.getContext('2d')
      ctx.drawImage(img, 0, 0)
      let imgData = ctx.getImageData(0, 0, 1024, 1024) // imgData will be all 0 or some other unexpected result.
    }
    img.src = urls[i]
}

// fixed bug
window.imgs = []
for(let i = 0; i < urls.length; ++i)
    window.imgs[i] = new Image()
for(let i = 0; i < urls.length; ++i){
    let img = window.imgs[i]
    img.onload = ()=>{
      let canvas = document.createElement('canvas')
      let ctx = canvas.getContext('2d')
      ctx.drawImage(img, 0, 0)
      let imgData = ctx.getImageData(0, 0, 1024, 1024) 
    }
    img.src = urls[i]
}

原因可能是对象引用、垃圾回收等问题。我不知道。因为我是js初学者