我是一个场景,我在其中生成针对特定图像的调色板。然后我想点击任何调色板颜色n并选择一个新颜色放在具有前一颜色代码的所有像素上。我已经完成了,并且它正在工作,但我需要您帮助优化其结果和时间。使用颜色小偷生成调色板的代码是:
function make_pallete(){
var images = document.getElementById('default_img');
colors = colorThief.getPalette(images, 8);
for (var i = 0 ; i < colors.length; i++) {
$('#swatches').append("<div class='swatch' style='background-color:rgb("+ colors[i][0]+ ","+ colors[i][1] + "," + colors[i][2] +")'></div>");
}
}
我正在进行重新着色的Django视图是:
def recolor_image(request):
if request.method == "POST":
pic = request.POST.get("image")
old_rgb = request.POST.getlist("old_rgb[]")
new_rgb = request.POST.getlist("new_rgb[]")
path = "D:/pysofts/flagcarpets" + pic
pic = path
picture = Image.open(pic)
# Get the size of the image
width,height = picture.size
print old_rgb
for x in range(0, width):
for y in range(0, height):
current_color = picture.getpixel((x,y))
r,g,b = current_color
if r in range(int(old_rgb[0]) - 50, int(old_rgb[0]) + 50) and g in range(int(old_rgb[1]) - 50, int(old_rgb[1]) + 50) and b in range(int(old_rgb[2]) - 50, int(old_rgb[2]) + 50):
r = int(new_rgb[0])
g = int(new_rgb[1])
b = int(new_rgb[2])
new_color = (r,g,b)
picture.putpixel((x,y), new_color)
picture.save(path)
return HttpResponse(pic)
正如我所说,它重新着色图像,但效率很差(它没有为每个前一个像素添加新颜色)n重新着色图像大约需要30秒。什么是更精确的算法?
答案 0 :(得分:2)
什么是图像分辨率和颜色?
基于像素的重新着色图像在1024x768左右应该只需要几个[ms]
如果您的色彩数量低至256,则可以使用基于调色板的图像(如GIF,BMP,PCX)来仅更改调色板而不是像素以改变速度。
如果你想要真正的速度,请使用C / C ++
问题:
我看到的第一件事是 GDI getpixel
访问权限,即 SLOW 。 (见bitmap ScanLine property)。因此,创建指向图像行的指针数组并使用它(每行只调用一次ScanLine然后使用数组)这将避免GDI检查减速。
每个getpixel / ScanLine调用调用大约100个子调用来检查类型,格式,分辨率等
如果您访问自己的指针数组,那么您只需访问内存而不会有任何额外的减速(通常比getpixel
快约1000倍)。
在您的平台中找到ScanLine[]
等效项并重写。以下是VCL/C++中的示例,以便您了解要查找的内容以及如何使用它
它应该与GDI接口几乎相同。
如果您想使用索引颜色(调色板)
您可以使用OpenGL和索引颜色进行可视化。通过这种方式,您只需更改调色板,并且opengl可以自行重新调整其余部分 这个过程在编辑时有利于速度,它只在保存时重新着色。
另一种选择是使用256色调色板图像文件格式(GIF,BMP,PCX) 为此,您必须将颜色限制为256 您可以使用任何方法。这是我的:Effective gif/image color quantization,但这会改变颜色动态范围,看那里的图像。
<强>重着色强>
如果您对调色板进行了排序,则可以使用二分搜索来加快处理速度
颜色太多,最好使用词典
例如,创建列表:List<DWORD> r0[256],g0[256],b0[256];
。每个颜色都包含以r
,g
或b
值开头的所有颜色
例如,r0[55]
将使用red=55
保留所有使用的颜色
这样,您可以在O(n^2)
而不是O(n^3)
中搜索不计算二进制搜索
请参阅上面的GIF链接,了解我如何重新着色以获得更多创意。