Tengo una imagen RGBA del lienzo y uso typedArray para eliminar el canal alfa.
// data - arr from canvas. // [1,2,3,255, 1,2,3,255, 1,2,3,255,] // RGBARGBARGBA 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]Copio cada 3 bytes al nuevo Uint8Array. ¿Puedo hacerlo de una manera más optimizada sin copiar bytes?
Parece que tu solución es bastante buena. Al menos ninguna de las alternativas que se me ocurrió hasta ahora se acerca en rendimiento. Ejecute el fragmento para verlo usted mismo.
Actualizado con la sugerencia de Justin usando .filter , elegante pero no más rápido.
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');Resultados:
first: 102.900ms set: 1185.700ms filter: 2779.800ms copyWithin: 415.100msel filtro seria bueno aqui
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)