首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >加速画布的getImageData

加速画布的getImageData
EN

Stack Overflow用户
提问于 2017-10-21 13:23:17
回答 2查看 3.4K关注 0票数 5

我需要从画布中提取像素块并对它们进行处理。目前,我在嵌套循环中多次调用getImageData

代码语言:javascript
复制
_getBinaryStringFromCanvas(canvas) {
  let ctx = canvas.getContext('2d')
  let { xMaxBlock, yMaxBlock, blockSize } = this.metrics;
  let results = '';
  for (let y = 0; y < yMaxBlock; y++) {
    for (let x = 0; x < xMaxBlock; x++) {
      let data = ctx.getImageData(x * blockSize, y * blockSize, blockSize, blockSize);
      let digit = this._somehowProcessTheData(data);
      binaryString += digit;
    }
  }
  return binaryString;
}

这是非常慢的,因为xMaxBlock和yMaxBlock可能非常大。理想情况下,我想做这样的事-

代码语言:javascript
复制
_getChunkFromCache(cache, x, y, width, height){
  // need help implementing this function
}

_getBinaryStringFromCanvas(canvas) {
  let ctx = canvas.getContext('2d')
  let { xMaxBlock, yMaxBlock, blockSize } = this.metrics;
  let results = '';
  let cache = ctx.getImageData(0, 0, xMaxBlock * blockSize, yMaxBlock * blockSize);
  for (let y = 0; y < yMaxBlock; y++) {
    for (let x = 0; x < xMaxBlock; x++) {
      let data = this._getChunkFromCache(cache, x * blockSize, y * blockSize, blockSize, blockSize);
      let digit = this._somehowProcessTheData(data);
      binaryString += digit;
    }
  }
  return binaryString;
}

但我似乎无法理解getImageData返回的平面数组中由x、y、宽度、高度指定的区域所需的逻辑。

任何实现_getChunkFromCache的帮助都将受到高度赞赏。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-21 13:55:48

不要复制,直接索引数组。

获取原始数据数组的一个子部分需要一个副本,因为类型数组( ImageData.data中的数组是类型化数组Uint8ClampedArray)只是一维的,不能索引另一个数组的2D部分。创建一个副本只会增加更多的工作,增加内存使用量,从而进一步减缓应用程序的运行速度。

最好的选择是somehowProcessTheData函数直接处理图像数据,并将数组索引到所提供的边界。

代码语言:javascript
复制
function somehowProcessTheData(imageData, x, y, w, h){
    var i,j;
    var result = ""; 
    var r,g,b,a;
    const data = imageData.data;

    for(j = 0; j < h; j++){
        var idx = (x + (y + j) * imageData.width) * 4;  // get left most byte index for row at y + j
        for(i = 0; i < w; i++){
             r = data[idx ++];
             g = data[idx ++];
             b = data[idx ++];
             a = data[idx ++];
             // do the processing
        }
     }
     return result;
 }

代码语言:javascript
复制
function somehowProcessTheData(imageData, x, y, w, h){
    var i,j;
    var result = ""; 
    const data = imageData.data;

    for(j = 0; j < h; j++){
        var idx = (x + (y + j) * imageData.width) * 4;  
        for(i = 0; i < w; i++){
             // get the red green blue values
             var blah = data[idx] + data[idx + 1] + data[idx + 2];
             // do the processing
             // ...
             // increment the index to the next pixel.
             idx += 4;

        }
     }
     return result;
 }

然后在调用循环中

代码语言:javascript
复制
 let data = this.processTheData(cache, x * blockSize, y * blockSize, blockSize, blockSize);
票数 6
EN

Stack Overflow用户

发布于 2019-02-07 18:02:38

你可以把你工作的整个区域都藏起来。它仍然很慢,但希望你不需要经常这样做。下面是一个示例,用于获取每个像素的int值,而不是4个字节。

代码语言:javascript
复制
const pixels = new Int32Array(ctx.getImageData(0, 0, w, h).data.buffer)
pixels[x + y * w]
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46863683

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档