Kev*_*vin 3 python image dithering python-imaging-library
我是Python新手,并尝试使用PIL执行Arduino项目所需的解析任务.这个问题涉及Image.convert()调色板,抖动等的方法和选项.
我有一次能够显示只有16色图像的一些硬件(但他们可以指定RGB三胞胎).因此,我想自动执行任意色彩PNG图像的任务,选择"最佳"16色调色板来表示它,并将图像转换为仅包含16种颜色的调色图像.
我想用抖动.问题是,这种image.convert()方法看起来有点时髦.它的参数没有完整记录(Image.convert()的PIL文档)所以我不知道这是我的错还是该方法是错误的.
我的代码的简单版本如下:
import Image
MyImageTrueColor = Image.new('RGB',100,100) # or whatever dimension...
# I paste some images from several other PNG files in using MyImageTrueColor.paste()
MyImageDithered = MyImageTrueColor.convert(mode='P',
colors=16,
dither=1
)
Run Code Online (Sandbox Code Playgroud)
根据我做的一些搜索(例如:如何用PIL减少调色板)我认为这种方法应该做我想要的,但没有运气.它会抖动图像,但会产生超过16种颜色的图像.
为了确保,我删除了"抖动"参数.相同的输出.
我重新添加了"dither = 1"参数并抛出了Image.ADAPTIVE参数(如上面的链接所示),只是为了看看发生了什么.这导致图像包含16种颜色,但没有抖动.
我在这里错过了什么吗?是PIL车吗?我想出的解决方案是执行两个步骤,但这似乎是草率和不必要的.我想弄清楚如何做到这一点:-)为了完整性,这里是我的代码版本,产生正确的结果 - 但它以一种草率的方式做到了.(第一步产生带有> 16种颜色的抖动图像,第二步产生仅包含16种颜色的图像.)
MyImage_intermediate = MyImageTrueColor.convert(mode='P',
colors=16
)
MyImageDithered = MyImage_intermediate.convert(mode='P',
colors=16,
dither=1,
palette=Image.ADAPTIVE
)
Run Code Online (Sandbox Code Playgroud)
谢谢!
好吧,你没有正确地调用它,所以它不应该工作......但即使我们正确地调用了东西,我也不确定它是否会起作用.
首先,PIL手册的"官方"免费版本既不完整又过时; http://effbot.org/imagingbook/image.htm上的草案版本不完整且已过时.
im.convert("P",**选项)⇒图像
相同,但在将"RGB"图像转换为8位调色板图像时提供更好的控制.可用选项包括:
抖动=.控制抖动.默认值为FLOYDSTEINBERG,它将错误分配给相邻像素.要禁用抖动,请使用NONE.
调色板=.控制调色板生成.默认为WEB,这是标准的216色"Web调色板".要使用优化的调色板,请使用ADAPTIVE.
颜色=.当调色板为ADAPTIVE时,控制调色板使用的颜色数.默认为最大值,256色.
所以,首先,你不能colors没有ADAPTIVE- 出于明显的原因:唯一的另一个选择是WEB,它只处理一个固定的216色调色板.
第二,你不能传递1给dither.如果恰好是它的价值,那可能会有效FLOYDSTEINBERG,但那就是3.所以,你传递的是无证件的价值; 谁知道会怎么做?特别是因为,查看所有听起来像抖动算法的可能名称的常量,它们都没有值1.
所以,您可以尝试将其更改为dither=Image.FLOYDSTEINBERG(以及palette=Image.ADAPTIVE),看看是否有所作为.
但是,看看代码,看起来这不会有任何好处:
if mode == "P" and palette == ADAPTIVE:
im = self.im.quantize(colors)
return self._new(im)
Run Code Online (Sandbox Code Playgroud)
这是在我们到达抖动代码之前发生的.所以它与调用(现在已弃用/私有)方法量化完全相同.
多线程表明高级convert功能仅用于将"抖动到网络调色板"或"映射到最接近的N种颜色".这似乎在1.1.6及更高版本略有改变,但文档和实现仍然不完整.在http://comments.gmane.org/gmane.comp.python.image/2947上,其中一个开发者建议阅读PIL/Image.py源代码.
所以,看起来这就是你需要做的.无论Image.convert在Image.WEB模式中是什么,你都希望这样做 - 但是使用的是由Image.quantize(colors)网页调色板生成的调色板.
当然,大部分的胆量发生在C代码(下self.im.quantize,self.im.convert等),但你可以做一些这样的伪代码:
dummy = img.convert(mode='P', paletter='ADAPTIVE', colors=16)
intermediate = img.copy()
intermediate.setpalette(dummy.palette)
dithered = intermediate._new(intermediate.im.convert('P', Image.FLOYDSTEINBERG))
Run Code Online (Sandbox Code Playgroud)
然后,你可能不会.您可能需要查看C标头甚至来源以查找.或者也许在PIL邮件列表上询问.
PS,如果你不熟悉PIL的胆量,那img.im就是PIL Image对象下面的C成像对象img.从我过去的经验来看,目前尚不清楚前3次浏览PIL代码,然后突然间一切都变得更有意义.