Canvas中RGBA转RGB的转换

3

我从画布中得到了RGBA图像,并使用了typedArray来移除alpha通道。

// data - arr from canvas. 

// [1,2,3,255, 1,2,3,255, 1,2,3,255,]
//  R G B  A   R G B  A   R G B  A

  const delta = 4;
  const length = data.length;
  const newLength = length - length / delta;

  const rgbArr = new Uint8Array(newLength);

  let j = 0;

  for (i = 0; i < data.length; i = i + delta) {
    rgbArr[j] = data[i]; // R
    rgbArr[j + 1] = data[i + 1]; // G
    rgbArr[j + 2] = data[i + 2]; // B
    j = j + 3;
  }
 
  // rgbArr [1,2,3, 1,2,3, 1,2,3]

我将每3个字节复制到新的Uint8Array中。有没有更优化的方法可以避免字节拷贝?

2个回答

2

看起来你的解决方案相当不错。至少在性能方面,我目前想到的任何替代方案都无法与之媲美。运行片段以自行查看。

使用 Justin 的建议更新,使用 .filter -- 省略但不更快。

const data = new Uint8Array(1e8);

const delta = 4;
const length = data.length;
const newLength = length - length / delta;

const rgbArr = new Uint8Array(newLength);

let j = 0;

console.time('first');
for (i = 0; i < data.length; i = i + delta) {
  rgbArr[j] = data[i]; // R
  rgbArr[j + 1] = data[i + 1]; // G
  rgbArr[j + 2] = data[i + 2]; // B
  j = j + 3;
}
console.timeEnd('first');

j = 0;
console.time('set');
const rgbArr2 = new Uint8Array(newLength);
for (i = 0; i < data.length; i = i + delta) {
  rgbArr2.set(data.slice(i, i+2), j);
  j = j + 3;
}
console.timeEnd('set');

console.time('filter');
data.filter((el,i) => {
  return i % 4 !== 4 - 1
})
console.timeEnd('filter');

j = 0;
console.time('copyWithin');
for (i = 0; i < data.length; i = i + delta) {
  data.copyWithin(j, i, i+2);
  j = j + 3;
}
console.timeEnd('copyWithin');

结果:

first: 102.900ms
set: 1185.700ms
filter: 2779.800ms
copyWithin: 415.100ms

谢谢!也许可以使用Uint32Array和位运算符来提高速度,就像这里https://jsfiddle.net/Fnx2w/467/一样,但我找不到方法。 - Alexufo
我感到困惑,因为Uint32Array数组元素的4个字节始终是4个字节。也许可以将4字节元素填充为当前3字节+下一个元素的1字节?并且向后移动字节,元素之间没有零。 - Alexufo
1
是的,这就是copyWithin解决方案所做的事情——而且不会在末尾截断尾巴,因为它太慢了。 - Christian Fritz

1
过滤器在这里很合适。

let array = new Uint8Array([1,2,3,255,1,2,3,255,1,2,3,255,1,2,3,255])

let filtered = array.filter((el,i) => {
  return i % 4 !== 4 - 1
})

console.log(filtered)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接