qq透明图像问题#13

关于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博客

python制作gif动图_PIL生成透明GIF动图_weixin_39973410的博客-CSDN博客

并在此基础上,简化了几个不必要的部分,如参数save_allappend_imagesduration
我查阅了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的图像压缩算法导致的,有兴趣的读者可以自行研究,也可以把你的发现告诉我。

另外

手机QQ怎么发透明底的图? - 知乎 (zhihu.com)

在该问题回答中提到的方法,笔者也进行了尝试。
经测试,这种将图片传输到手机,再以原图发送的方法,确实能在电脑端透明显示,但在手机端看来,还是出现了白底。

参考

探索qq发送png透明通道丢失的问题

QQ怎么做透明表情包

怎样将图片背景变透明

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值