Я не знаю, насколько эффективно ваш код, и я могу почти гарантировать, что вы не получите гораздо более эффективно, обернув через ImageData. То, что я хотел бы предложить, используя холст globalCompositeOperation для извлечения канала на другой холст, у меня есть работающий пример на этой ручки:
http://codepen.io/Aeyos/pen/egyEQQ
А также здесь:
var canvas1 = document.querySelector('#canvas1');
var canvas2 = document.querySelector('#canvas2');
var canvas3 = document.querySelector('#canvas3');
var img1 = document.querySelector('#img1');
var ctx1 = canvas1.getContext('2d');
var ctx2 = canvas2.getContext('2d');
var ctx3 = canvas3.getContext('2d');
ctx1.drawImage(img1, 0, 0);
ctx1.fillStyle = "#F00";
ctx1.globalCompositeOperation = 'multiply';
ctx1.fillRect(0, 0, 435, 318);
ctx2.drawImage(img1, 0, 0);
ctx2.fillStyle = "#0F0";
ctx2.globalCompositeOperation = 'multiply';
ctx2.fillRect(0, 0, 435, 318);
ctx3.drawImage(img1, 0, 0);
ctx3.fillStyle = "#00F";
ctx3.globalCompositeOperation = 'multiply';
ctx3.fillRect(0, 0, 435, 318);
//http://wallpaper-gallery.net/single/image/image-13.html
canvas {
border: 1px dashed gray;
}
<img id="img1" src="http://wallpaper-gallery.net/images/image/image-13.jpg" /><canvas width="435" height="318" id="canvas1"></canvas>
<canvas width="435" height="318" id="canvas2"></canvas>
<canvas width="435" height="318" id="canvas3"></canvas>
Вы также можете изменить globalCompositeOperation на любой из них:
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation
Каждый канал занимает около 200 мс для завершения операции, хорошие новости, что, вероятно, одно и то же время для больших изображений.
Поскольку это 1D массив конкатенированных массивов RGBA, нет другого пути, кроме как пройти через него. Я думаю, вы могли бы использовать Array.reduce, хотя, но технически это также цикл. –