我需要分析图像以查找PNG或GIF图像中的所有颜色。我目前将图像加载到画布上,然后获取图像数据,然后遍历每个像素并检查调色板中的每种颜色。这需要永远,浏览器认为脚本已停止,有时只会崩溃。希望有更好的方法。
h5
答案 0 :(得分:0)
这会加速一点。
如果找不到条目,函数indexof将搜索所有数组。这可能非常慢,您可以通过添加到向下移动的数组顶部然后从最顶部的条目中搜索索引来提高搜索速度。这样可以确保搜索仅覆盖整个数组的添加条目。
同样使用32位字而不是8位字节,使用类型化数组,因为它们显着更快,因为它们推入数组并且不会在循环内转换为十六进制,这是冗余的,可以在较小的数据集之后完成
请参阅逻辑评论。
//draw the image onto the canvas
ctx.drawImage(image, 0, 0);
// get size
const size = image.width * image.height;
// create pallete buffer
const colors32 = new Uint32Array(256);
// current pos of palette entry
var palettePos = colors32.length - 1; // Start from top as this will speed up indexOf function
// pixel data as 32 bit words so you can handle a pixel at a time rather than bytes.
const imgData = new Uint32Array(ctx.getImageData(0, 0, image.width, image.height).data.buffer);;
// hold the color. If the images are low colour (less 256) it is highly probable that many pixels will
// be the same as the previous. You can avoid the index search if this is the case.
var color= colors32[palettePos --] = imgData[0]; // assign first pixels to ease logic in loop
for (var i = 1; i < size && palettePos >= 0; i += 1) { // loop till al pixels read if palette full
if(color !== imgData[i]){ // is different than previouse
if (colors32.indexOf(imgData[i], palettePos) === -1) { // is in the pallet
color = colors32[palettePos --] = imgData[i]; // add it
}
}
}
// all the performance issues are over so now convert to the palette format you wanted.
const colorPalette = [];
colors32.reverse();
const paletteSize = (255 - palettePos) * 4;
const colors8 = new Uint8Array(colors32.buffer);
for(i = 0; i < paletteSize; i += 4){
colorPalette.push(rgbToHex(colors8[i],colors8[i + 1],colors8[i + 2]));
}