Быстрее массив можно перебрать, если проверять сразу весь цвет, примерно так:
var color32bit = new Uint8Array(new Uint32Array([0x0a0b0c0d]).buffer)[3] === 0x0a ? //LITTLE_ENDIAN
function(r, g, b, a){
return a << 24 | b << 16 | g << 8 | r;
} :
function(r, g, b, a){
return r << 24 | g << 16 | b << 8 | a;
};
function pixelByColor(imageData, color) {
var data = new Uint32Array(imageData.data.buffer),
i = data.length;
while(i-- && data[i] ^ color);
return i
}
pixelByColor(ctx.getImageData(0,0,width,height), color32bit(255,1,2,255))
Однако на самом деле перебор тут не нужен. В нормальном колорпикере используется изображение само по себе сгенерированное алгоритмом, и когда надо узнать цвет под мышкой или положение цвета на изображении само изображение вообще не трогают, а обращаются напрямую к алгоритму его сгенерировавшему и получают прямой ответ. Таким образом колорпикеры делались ещё до канваса.