ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python – PIL – 抖动所需,但限制调色板会导致问题

2019-08-26 05:00:12  阅读:210  来源: 互联网

标签:python image python-imaging-library dithering


我是Python新手,并尝试使用PIL执行Arduino项目所需的解析任务.这个问题与Image.convert()方法以及调色板,抖动等选项有关.

我有一些硬件能够一次显示只有16种颜色的图像(但它们可以指定RGB三元组).因此,我想自动执行任意色彩PNG图像的任务,选择“最佳”16色调色板来表示它,并将图像转换为仅包含16种颜色的调色图像.

我想用抖动.问题是,image.convert()方法看起来有点时髦.它的论点没有完整记录(PIL documentation for Image.convert())所以我不知道这是我的错还是这个方法是错误的.

我的代码的简单版本如下:

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
    )

根据我做的一些搜索(例如:How to reduce color palette with 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
    )

谢谢!

解决方法:

好吧,你没有正确地调用它,所以它不应该工作……但即使我们正确地调用了东西,我也不确定它是否会起作用.

首先,PIL手册的“官方”免费版本既不完整又过时; http://effbot.org/imagingbook/image.htm的草案版本不完整且已过时.

im.convert(“P”, **options) ⇒ image

Same, but provides better control when converting an “RGB” image to an
8-bit palette image. Available options are:

dither=. Controls dithering. The default is FLOYDSTEINBERG, which
distributes errors to neighboring pixels. To disable dithering, use
NONE.

palette=. Controls palette generation. The default is WEB, which is
the standard 216-color “web palette”. To use an optimized palette, use
ADAPTIVE.

colors=. Controls the number of colors used for the palette when
palette is ADAPTIVE. Defaults to the maximum value, 256 colors.

所以,首先,你不能使用没有ADAPTIVE的颜色 – 显而易见的原因:唯一的另一个选择是WEB,它只处理固定的216色调色板.

第二,你不能将1传递给抖动.如果它碰巧是FLOYDSTEINBERG的值,那可能会有效,但那就是3.所以,你传递的是一个未记录的值;谁知道会怎么做?特别是因为,查看听起来像抖动算法的可能名称的所有常量,它们都没有值1.

所以,您可以尝试将其更改为抖动= Image.FLOYDSTEINBERG(以及palette = Image.ADAPTIVE),看看是否有所作为.

但是,看看代码,看起来这不会有任何好处:

if mode == "P" and palette == ADAPTIVE:
    im = self.im.quantize(colors)
    return self._new(im)

这是在我们到达抖动代码之前发生的.所以它与调用(现在已弃用/私有)方法量化完全相同.

多线程表明高级转换函数仅用于将“抖动到网络调色板”或“映射到最近的N种颜色”.这似乎在1.1.6及更高版本略有改变,但文档和实现仍然不完整.在http://comments.gmane.org/gmane.comp.python.image/2947,其中一个开发者建议阅读PIL / Image.py源.

所以,看起来这就是你需要做的.无论Image.WEB模式中Image.convert做什么,你都希望这样做 – 但是使用由Image.quantize(颜色)生成的调色板,而不是Web调色板.

当然,大多数内容都发生在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))

然后,你可能不会.您可能需要查看C标头甚至来源以查找.或者也许在PIL邮件列表上询问.

PS,如果你不熟悉PIL的内脏,img.im是PIL Image对象img下面的C成像对象.从我过去的经验来看,目前尚不清楚前3次浏览PIL代码,然后突然间一切都变得更有意义.

标签:python,image,python-imaging-library,dithering
来源: https://codeday.me/bug/20190826/1726456.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有