canvas RGBA 到 RGB 的转换
canvas RGBA to RGB conversion
我有来自 canvas 的 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。我可以在不进行字节复制的情况下以更优化的方式进行操作吗?
看起来你的解决方案很不错。到目前为止,我提出的至少 none 个替代方案的性能接近。 运行 自己看的片段。
更新 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
过滤器在这里会很好
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)
我有来自 canvas 的 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。我可以在不进行字节复制的情况下以更优化的方式进行操作吗?
看起来你的解决方案很不错。到目前为止,我提出的至少 none 个替代方案的性能接近。 运行 自己看的片段。
更新 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
过滤器在这里会很好
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)