我正在使用PIL创建一个简单的GIF动画:
from PIL import Image, ImageDraw, ImageFont
images = []
for x, i in enumerate(range(10)):
image = Image.new(mode="RGB", size=(320, 60), color="orange")
draw = ImageDraw.Draw(image)
fnt = ImageFont.truetype('font.ttf', size=10)
draw.text((10, 10), ("%s" % x), fill=(0, 0, 255), font=fnt)
images.append(image)
images[0].save("result/pil.gif", save_all=True, append_images=images[1:], duration=1000, loop=0, format="GIF")
问题是,每当我使用Draw.text时,图像的背景都会出现某种白色noze:
我发现一些信息,我必须使用第一帧的getpalette和其他所有帧的putpalette,如下所示:
for x, i in enumerate(range(10)):
image = Image.new(mode="RGB", size=(320, 60), color="orange")
if x == 0:
palette = image.getpalette()
else:
image.putpalette(palette)
但它只给了我:ValueError: illegal image mode
背景噪音的原因是什么?我如何修复它
UPD我可以通过将图像模式更改为“p”来修复背景,但在这种情况下,我的字体变得不可读。以下是RGB模式(字体很好)和P模式(字体很糟糕)的示例:
为什么我要么有好的背景,要么有好的字体,但不是两者都有?有解决办法吗
这就是发生的dithering,因为gif只能包含大小为256的palette中的颜色。最有可能的是,PIL使用非常基本的算法将RGB格式转换为gif所需的索引格式。由于图像包含颜色} 的值为
#ff9900
和#ffcc00
,因此调色板可能由每个字节的十六进制值00, 33, 66, 99, cc, ff
组成,大小为6x6x6=216,正好适合256个可能的值^{#ffa500
,不能用这种调色板表示,因此背景由最近的可用颜色填充您可以尝试使用颜色
'#ff9900'
而不是'orange'
。希望这种颜色可以用调色板来表示,因为它存在于嘈杂的图像中您还可以尝试使用自己的调色板作为
quantize
方法中的参数,将RGB格式转换为索引格式,如this answer中所建议的。添加以下行将导致nice solid background:或者您也可以只保存PNG格式的RGB图像。在这种情况下,它将保存为APNG图像
user13044086给出了问题的一般版本,具体是gif是托盘格式,要将原始RGB转换为调色板,需要将其从“真彩色”限制为仅256色
为此,它将convert图像转换为模式L,正如您在文档中看到的,如果没有给出转换矩阵,那么这只是使用默认参数调用quantize的别名。这里的相关默认参数是
dither
,这意味着如果图像的颜色超过256种,请尝试通过使用附近颜色的单个点来“模拟”缺少的颜色现在,您可能会抱怨没有超过256种颜色,但可能是因为字体抗锯齿,而且算法不一定有“味道”,因此,它不是在字母中抖动,而是在背景中非常明显地抖动
您可以通过显式量化来缓解此问题,如建议的那样提供显式方法,或者只是禁用抖动(这可能会产生较低质量的结果,但肯定会更快):
手动制作自己的调色板并将其传递给
quantize
也可以相关问题 更多 >
编程相关推荐