关于QQ发送透明图像失败
笔者在用QQ发送透明图像时,常遇到图像出现黑底或白底的情况,心生好奇,便探索了一下,在此记录一番。
原因探索
经过上网查阅资料,较为可信的是以下说法:
qq不能识别png格式的图片,因为它不支持alpha通道。
典型的图像处理bug, 原因是 png 和jpeg 压缩算法的差异造成的。 jpeg 不支持透明色,故转换后会随机地变成黑色或者白色。
解决方案
在PS或其他软件里导出成GIF格式的图片就变成透明背景了。
尝试出来了,web靠色值调整到100%
这两种方案我都试了,可能是我PS不太熟练,最终没有成功。
但即使成功,为了一个简单的功能要启用PS什么的。。我还是敬谢不敏。
解决方案
即拿即用
def img2gif(img_path:str, savename = None):
'''
png转透明背景gif
:author: Lian
:param img_path: 图片路径
:param savename: 保存名称(可选)
:return:
'''
import os
if not os.path.isfile(img_path):
print("wrong file name")
exit()
from PIL import Image
img = Image.open(img_path)
img.putalpha(255)
if not savename:
savename = "{}.gif".format(os.path.splitext(img_path)[0])
# img.show()
img.save(savename, transparency = 0, disposal = 2, loop = 0)
if __name__ == "__main__":
import sys
if(sys.argv.__len__()<2):
print("need arguments")
exit()
img2gif(*tuple(sys.argv[1:]))
这是经过我的一步步测试,得到的最简程序了。
这个程序参考了以下两位博主的文章
Python用PIL将PNG图像合成gif时如果背景为透明时图像出现重影的解决办法_orange_wrj的博客-CSDN博客
并在此基础上,简化了几个不必要的部分,如参数save_all
、append_images
、duration
我查阅了pillow的原文档
disposal
Indicates the way in which the graphic is to be treated after being displayed.
- 0 - No disposal specified.
- 1 - Do not dispose.
- 2 - Restore to background color.
- 3 - Restore to previous content.
这个disposal参数十分有意思,已知0和1无法生成透明背景,但2和3具体有什么差别呢
disposal
An integer (or list or tuple of integers) specifying the APNG disposal operation to be used for this frame before rendering the next frame. Defaults to 0.
- 0 (
OP_NONE
, default) - No disposal is done on this frame before rendering the next frame.- 1 (
PIL.PngImagePlugin.Disposal.OP_BACKGROUND
) - This frame’s modified region is cleared to fully transparent black before rendering the next frame.- 2 (
OP_PREVIOUS
) - This frame’s modified region is reverted to the previous frame’s contents before rendering the next frame.
我参考了png格式saving部分参数的解释,disposal为OP_BACKGROUND时,GIF会在渲染下一帧前使当前帧的修改部分变为完全透明
的。。黑色?
disposal为OP_PREVIOUS时,GIF会在渲染下一帧前使当前帧的修改部分变为上一帧的内容。
我认为对于单帧的GIF来说这似乎是无关紧要的,但在测试时我发现,如果不将disposal参数设为2或3,或者不添加loop参数,表面上可以正常生成透明背景GIF,但在回复发出该图像的消息时,它会奇妙地出现白底。
出现这种情况的原因,笔者也不是很清楚,想来是QQ的图像压缩算法导致的,有兴趣的读者可以自行研究,也可以把你的发现告诉我。
另外
在该问题回答中提到的方法,笔者也进行了尝试。
经测试,这种将图片传输到手机,再以原图发送的方法,确实能在电脑端透明显示,但在手机端看来,还是出现了白底。