【问题标题】:Getting data from multiple images with one canvas使用一张画布从多个图像中获取数据
【发布时间】:2018-07-25 11:08:44
【问题描述】:

这是一个具体的问题,所以我会尽力解释它。

我的页面上有一个画布。用户上传一批从同一摄像机角度拍摄的文件。画布显示其中一个图像,并且用户以描绘感兴趣区域的方式在图像上绘制。然后程序会遍历这个感兴趣的区域,并从该区域内的像素中提取相关的 RGB 数据。

现在,我遇到的问题是将画布切换到下一张图像以处理该图像。我仍然将感兴趣的区域指定为该区域内的索引数组。但是,当尝试从其余图像中获取 RGB 数据时,它只会给我关于第一张图像的信息。

下面是一些相关的sn-ps代码及其功能。

这个函数加载文件中的下一张图片上传到画布

function readNextImage(i) {
  if (fileUpload.files && fileUpload.files[i]) {
    var FR = new FileReader();
    FR.onload = function(e) {
      fabric.Image.fromURL(e.target.result, function(img) {
        img.set({
          left: 0,
          top: 0,
          evented: false
        });
        img.scaleToWidth(canvas.width);
        img.setCoords();
        canvas.add(img);
      })
    };
    FR.readAsDataURL(fileUpload.files[i]);
  }
}

这个 sn-p 加载一个包含图像数据的数组。

var imgData = context.getImageData(0,0,canvas.width,canvas.height);
var data = imgData.data;

所以目前,我能够第一次浏览“数据”并获得我需要的相关 RGB 信息。在我这样做之后,我调用 readNextImage() 函数,它将它加载到画布中,然后我再次调用

var imgData = context.getImageData(0,0,canvas.width,canvas.height);
var data = imgData.data;

希望用新值加载数组。这似乎是失败的地方,因为值与之前的迭代相同。

在用新图像加载画布和尝试获取新数据值之间,程序是否有足够的时间?画布上是否还有其他我不知道的情况?

这里是我实际调用 readNextImage() 函数的地方

for (var image_num=0; image_num<fileUpload.files.length; image_num+=1){
    imgData = context.getImageData(0,0,canvas.width,canvas.height);
    data = imgData.data;

    /*Lines of code that parses through the data object specified above*/

    readNextImage(image_num);
}

我希望问题很清楚,如果有什么令人困惑的地方,请告诉我。

【问题讨论】:

    标签: javascript canvas


    【解决方案1】:

    编辑 2:

    关于承诺的文章链接:promises 1promises 2promises 3

    编辑:不要使用全局画布,而是使用为每个图像实例创建的本地画布:

        for (var image_num=0; image_num<fileUpload.files.length; image_num+=1){
        var canvas = document.createElement("canvas");
        var context = canvas.getContext("2d");
        readNextImage(image_num,canvas);
        imgData = context.getImageData(0,0,canvas.width,canvas.height);
        data = imgData.data;
    
        /*Lines of code that parses through the data object specified above*/
        }
    
    
    function readNextImage(i,canvas) {
      if (fileUpload.files && fileUpload.files[i]) {
        var FR = new FileReader();
        FR.onload = function(e) {
          fabric.Image.fromURL(e.target.result, function(img) {
            img.set({
              left: 0,
              top: 0,
              evented: false
            });
            img.scaleToWidth(canvas.width);
            img.setCoords();
            canvas.add(img);
          })
        };
        FR.readAsDataURL(fileUpload.files[i]);
      }
    }
    

    问题可能出在这里(之前的图像仍然附加在画布上):

    canvas.add(img);
    

    尝试删除前一个子项,然后再添加另一个子项,方法是将该行替换为:

    while (canvas.firstChild) {
      canvas.removeChild(canvas.firstChild);
    }
    canvas.add(img);
    canvas.getContext("2d").drawImage(img, 0, 0);
    

    【讨论】:

    • 刚刚试了一下,似乎没有用。做var imgData = context.getImageData(0,0,canvas.width,canvas.height); var data = imgData.data; 应该只是抓取画布内容,而不应该关心是否存在哪些图层。不过,值得一试。谢谢。
    • 您是否调试并检查过图像文件的文件名是否不同?
    • 当我运行该函数时,我可以看到画布在我上传的各种图像之间快速循环,因此我相当有信心各个图像都正确上传。
    • 你能编辑和显示更多的源代码吗?特别是您调用 readNextImage() 的部分
    • 我刚刚用调用函数的部分编辑了原始帖子
    猜你喜欢
    • 2012-01-14
    • 1970-01-01
    • 2014-02-08
    • 2016-05-02
    • 2012-08-22
    • 2014-11-06
    • 1970-01-01
    • 2013-06-23
    • 2021-04-13
    相关资源
    最近更新 更多