为什么GIF调色板在我的代码中被损坏? [英] Why does the GIF colour palette get corrupted in my code?
问题描述
我制作了为GIF或图片加标题的函数:
I made a function that captions a GIF or image:
import textwrap
from io import BytesIO
from PIL import Image, ImageDraw, ImageFont, ImageOps, ImageSequence
def caption(fn: str, text: str):
old_im = Image.open(fn)
ft = old_im.format
W = old_im.size[0]
font = ImageFont.truetype('BebasNeue.ttf', 50) # replace with your own font
width = 10
while True:
lines = textwrap.wrap(text, width=width)
if (font.getsize(max(lines, key=len))[0]) > (0.9 * W):
break
width += 1
# amount of lines * height of one line
bar_height = len(lines) * (font.getsize(lines[0])[1])
frames = []
for frame in ImageSequence.Iterator(old_im):
frame = ImageOps.expand(
frame,
border=(0, bar_height, 0, 0),
fill='white'
)
draw = ImageDraw.Draw(frame)
for i, line in enumerate(lines):
w, h = draw.multiline_textsize(line, font=font)
# Position is x: centered, y: line number * height of line
draw.text(
((W - w) / 2, i * h),
line,
font=font,
fill='black'
)
del draw
b = BytesIO()
frame.save(b, format=ft)
b.seek(0)
frames.append(Image.open(b))
frames[0].save(
f'out.{ft}',
save_all=True,
append_images=frames[1:],
format=ft,
loop=0,
optimize=True
)
caption(
'in.gif',
'this is a test message this is a test message this is a test message this is a test message this is a test message this is a test message'
)
这会带来一些奇怪的结果,只是不希望有什么变化.
This, with slight variations, is giving weird results, of which none are desired.
这是 in.gif
:
- 不更改上面的代码:
- 将
palette = old_im.palette
传递到frames [0] .save()
:
- 将框架展开后立即将其转换为'RGB'(
.convert('RGB'))
):
- 将
palette = old_im.palette
传递到frames [0] .save(...)
,并将帧转换为'RGB展开后立即使用((.convert('RGB'))
):
- With
palette=old_im.palette
passed intoframes[0].save(...)
and the frame converted to 'RGB' (.convert('RGB'))
) immediately after expanding it:
- 将
palette = old_im.getpalette()
传递到frames [0] .save(...)
:
- 将
palette = old_im.getpalette()
传递到frames [0] .save(...)
,并将帧转换为展开后立即使用'RGB'(.convert('RGB'))
):
- With
palette=old_im.getpalette()
passed intoframes[0].save(...)
and the frame converted to 'RGB' (.convert('RGB'))
) immediately after expanding it:
如您所见,尽管数字5似乎具有最佳效果,但没有一个选项具有理想的输出,除了白色画布上的黑色文本现在突然变成了红色画布上的暗红色文本.是什么原因造成的?如何获得正常的输出?
As you can see none of the options have the desired output, though number 5 seems to have the best results, apart from the black text on white canvas now suddenly being dark red text on a red canvas. What is causing this and how could I get a normal output?
推荐答案
在扩展 frame
之前,先转换为'RGB'
:
Convert to 'RGB'
BEFORE expanding the frame
:
# [...]
for frame in ImageSequence.Iterator(old_im):
frame = frame.convert('RGB') # <--
frame = ImageOps.expand(
frame,
border=(0, bar_height, 0, 0),
fill='white'
)
draw = ImageDraw.Draw(frame)
# [...]
这就是我得到的输出:
我认为,用 white
填充会以某种方式破坏现有的调色板.如果您在展开前转换为'RGB'
,则白色"表示我猜这将是正确的白色".
I assume, that filling with white
somehow corrupts the existing palette. If you convert to 'RGB'
before expanding, "white" will be the "correct white", I guess.
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.9.1
Pillow: 8.1.2
----------------------------------------
这篇关于为什么GIF调色板在我的代码中被损坏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!