前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >白夜追凶 :手 Q 图片的显示和发送逻辑

白夜追凶 :手 Q 图片的显示和发送逻辑

原创
作者头像
豆豆的包包
修改2017-10-25 10:21:27
1.9K0
修改2017-10-25 10:21:27
举报
文章被收录于专栏:豆包的专栏豆包的专栏

作者:陈舜尧导语: “这张图片在快捷发图栏背景是黑色的,为啥发到AIO(会话窗口)里背景就变成白的了?” 通过一个bug单,对黑白背景问题跟进的过程中发现了手q中很多奇怪的表现。一层层看代码,整理总结了手q中图片的显示和发送逻辑,以及对透明通道图片的特殊处理。

一、黑背景?白背景?

[1508830592113_5704_1508830632613.gif]
[1508830592113_5704_1508830632613.gif]

这张图片在快捷发图栏背景是黑色的,发到AIO里背景就变成白的了。拿到问题,分析有两种可能原因:展示view的背景色不一致;选中的png图片的透明通道在AIO和快捷发图栏两个不同的场景下过滤规则不一致。

很容易就能发现两个场景处理图片的不同:快捷发图栏将png图片获取为bitmap,再压缩成jpeg,这个过程直接忽略了透明通道,android默认处理的结果就是一张黑色背景的jpeg。快捷发图栏所有图片的字节流持久化到同一个文件里,这样做的目的是下次从本地加载多张图片时,会共用同一个文件IO,提高加载效率;

AIO中的缩略图也是由原图压缩成jpeg,在处理的代码中,我发现了人为加白色背景的逻辑,原来这都是产品的策略,可能考虑到AIO中png图片黑色背景视觉上不太美观,所以进行了特殊处理。然而快捷发图栏和AIO中视觉上没做到统一,有道是 产品拍头一时爽,开发解bug火葬场

[1508830781703_455_1508830820544.png]
[1508830781703_455_1508830820544.png]

二、都是png,怎么有黑又有白!

既然问题找到了,美滋滋的准备加个鸡腿,然而事情并没有那么简单!回归问题的时候我用了另外一张png图片测试,咦,怎么这张图片在AIO中背景是黑色的?

有两个怀疑方向:1、png压缩成jpeg的过程,丢失透明通道导致AIO中这张图片为黑色背景;2、有没有可能是在canvas上绘制白色背景失败导致的该问题?

[1508830825791_6449_1508830868112.gif]
[1508830825791_6449_1508830868112.gif]

先从第一个方向分析,通过BitmapFactory.decode把png输出为bitmap,再把白底、bitmap依次绘到canvas上,期间旋转信息的处理、对长图的特殊处理、subSample这里就不展开了。这里怀疑png输出为bitmap时,透明通道丢失。

我们知道ARGB指的是一种色彩模式,里面A代表Alpha,R表示red,G表示green,B表示blue,其实所有的可见色都是右红绿蓝组成的,所以红绿蓝又称为三原色,每个原色都存储着所表示颜色的信息值,Bitmap.Option中config的值有下面几种,ALPHA_8 代表8位Alpha位图 ,ARGB_4444 代表16位ARGB位图 ,ARGB_8888 代表32位ARGB位图 ,RGB_565 代表16位RGB位图。有没有可能是png输出为bitmap的过程中,有奇葩的策略调整config的值导致ALPHA通道遗失?于是一步步断点跟踪这块的代码,很遗憾没发现异常。

再看看第二个方向,我们review下加白色背景的代码(见上图),Paint设置了Xfermode。PorterDuff.Mode能设置canvas绘图时不同图层的混合方式,下图展示了不同的混合方式。我们处理是将图片bitmap叠加到白色背景上,这里SRC_OVER看上去也没问题。。。

[1508830748267_7786_1508830787049.png]
[1508830748267_7786_1508830787049.png]

啪啪啪打脸,看来不是怀疑的两个方向出了问题。于是病急乱投医把锅甩给了图片。。。。。

“会不会是png格式的问题,png某个参数导致转化过程中bitmap背景不同????”

在查阅资料、用工具分析对比了两张png图片的结构,欣喜得发现问题跟png格式并没有半毛钱关系。冷静下来,还是用老办法,一步一步跟代码!!!!

[1508830936348_2186_1508830975442.png]
[1508830936348_2186_1508830975442.png]

游戏图压缩后P2大于P1(是的你没看错,压缩后图片反而大,压缩步骤取bitmap,再绘制,最后质量压缩成jpeg),所以是拿原始图片当作大图P3去生成缩略图P4,原始图片有透明通道,所以对应的缩略图能加上白色背景;骰子图片压缩后发现比原图小,所以用压缩图P2当作大图P3去生成缩略图P4。P2是质量压缩png生成的jpeg,已经丢失透明通道,是一张黑色背景的图。即使在P4加上白色背景也被上层图层覆盖,我们看到的就是黑色骰子缩略图。

我之前分析的过程中忽略了压缩原始图片生成P2这一步。一叶障目,理清了思路,问题就显而易见了!

三、黑白分明,搞清楚所有情况下的表现

既然理清了流程,那就把所有情况下的表现分析下吧。我们看看勾选原图下的表现。

[1508830961289_4093_1508831003490.gif]
[1508830961289_4093_1508831003490.gif]

这里很好理解,骰子图勾选原图后,是把原始图片生成缩略图P4,原始图有透明通道,所以生成的缩略图也有白色背景。

[1508830984092_4214_1508831022971.png]
[1508830984092_4214_1508831022971.png]

如果是PC发送PNG图片,客户端去接收消息下载图片呢?PC端发送图片不存在是否勾选原图的概念,也不存在压缩的概念(耿直boy)。客户端接收方会去下载PC端发送的图片P5和架平生成的缩略图P7。

四、黑白闪变是什么鬼!

这时我在回归过程中又发现了一起不寻常的现象。客户端发送游戏图后,接收端收到图片,在AIO中的缩略图会有一个由黑变白的过程。呵呵,兵来将挡,bug来我解。又滚去熟悉了下接收端的逻辑。

[1508830998554_6721_1508831038369.gif]
[1508830998554_6721_1508831038369.gif]

发送的这张游戏图是由透明通道的,架平并没有为有透明通道的图片添加白色背景的策略,所以接收端下载的是一张黑色背景的架平缩略图。

这里要提到手q的预下载策略。用户可能会去点开大图,如果点击时再去下载,转菊花的过程体验很差,所以手q会综合网络情况、当前已用流量等维度去判断是否需要提前帮用户下载大图。图中图片消息命中了预下载策略,手q帮用户提前下载好了大图。

这时候问了,大图明明是黑色背景,为什么AIO中会闪变成白色?哈哈哈,这里又是手q人性化的一点,由于下载好了大图,为了让用户在AIO中可以直接可以看到比较清晰的缩略图,手q不信任架平生成的缩略图,用已经下载的大图在本地生成了相对高清的缩略图。

而下载的大图是有透明通道的png,根据前面已经提到的产品策略,我们会给本地生成的缩略图加上白色背景,所以出现了闪变~

[1508831013454_3822_1508831052353.png]
[1508831013454_3822_1508831052353.png]

五、总结

全文告一段落,在跟进问题的过程中,又完整的走了一遍手Q的图片发送流程。

除了提高对业务的熟悉程度之外,不禁感慨,前辈们为图片发送展示流程做了数不清的优化项,前人栽树后人乘凉,由衷的钦佩!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、黑背景?白背景?
  • 二、都是png,怎么有黑又有白!
  • 三、黑白分明,搞清楚所有情况下的表现
  • 四、黑白闪变是什么鬼!
  • 五、总结
相关产品与服务
图片处理
图片处理(Image Processing,IP)是由腾讯云数据万象提供的丰富的图片处理服务,广泛应用于腾讯内部各产品。支持对腾讯云对象存储 COS 或第三方源的图片进行处理,提供基础处理能力(图片裁剪、转格式、缩放、打水印等)、图片瘦身能力(Guetzli 压缩、AVIF 转码压缩)、盲水印版权保护能力,同时支持先进的图像 AI 功能(图像增强、图像标签、图像评分、图像修复、商品抠图等),满足多种业务场景下的图片处理需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档