歡迎你們前往騰訊雲社區,獲取更多騰訊海量技術實踐乾貨哦~android
做者:陳舜堯canvas
導語: 「這張圖片在快捷發圖欄背景是黑色的,爲啥發到AIO(會話窗口)裏背景就變成白的了?」 經過一個bug單,對黑白背景問題跟進的過程當中發現了手q中不少奇怪的表現。一層層看代碼,整理總結了手q中圖片的顯示和發送邏輯,以及對透明通道圖片的特殊處理。網絡
這張圖片在快捷發圖欄背景是黑色的,發到AIO裏背景就變成白的了。拿到問題,分析有兩種可能緣由:展現view的背景色不一致;選中的png圖片的透明通道在AIO和快捷發圖欄兩個不一樣的場景下過濾規則不一致。工具
很容易就能發現兩個場景處理圖片的不一樣:快捷發圖欄將png圖片獲取爲bitmap,再壓縮成jpeg,這個過程直接忽略了透明通道,android默認處理的結果就是一張黑色背景的jpeg。快捷發圖欄全部圖片的字節流持久化到同一個文件裏,這樣作的目的是下次從本地加載多張圖片時,會共用同一個文件IO,提升加載效率;性能
AIO中的縮略圖也是由原圖壓縮成jpeg,在處理的代碼中,我發現了人爲加白色背景的邏輯,原來這都是產品的策略,可能考慮到AIO中png圖片黑色背景視覺上不太美觀,因此進行了特殊處理。然而快捷發圖欄和AIO中視覺上沒作到統一,有道是 產品拍頭一時爽,開發解bug火葬場測試
既然問題找到了,美滋滋的準備加個雞腿,然而事情並無那麼簡單!迴歸問題的時候我用了另一張png圖片測試,咦,怎麼這張圖片在AIO中背景是黑色的?優化
有兩個懷疑方向:一、png壓縮成jpeg的過程,丟失透明通道致使AIO中這張圖片爲黑色背景;二、有沒有多是在canvas上繪製白色背景失敗致使的該問題?spa
先從第一個方向分析,經過BitmapFactory.decode把png輸出爲bitmap,再把白底、bitmap依次繪到canvas上,期間旋轉信息的處理、對長圖的特殊處理、subSample這裏就不展開了。這裏懷疑png輸出爲bitmap時,透明通道丟失。code
咱們知道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通道遺失?因而一步步斷點跟蹤這塊的代碼,很遺憾沒發現異常。blog
再看看第二個方向,咱們review下加白色背景的代碼(見上圖),Paint設置了Xfermode。PorterDuff.Mode能設置canvas繪圖時不一樣圖層的混合方式,下圖展現了不一樣的混合方式。咱們處理是將圖片bitmap疊加到白色背景上,這裏SRC_OVER看上去也沒問題。。。
啪啪啪打臉,看來不是懷疑的兩個方向出了問題。因而病急亂投醫把鍋甩給了圖片。。。。。
「會不會是png格式的問題,png某個參數致使轉化過程當中bitmap背景不一樣????」
在查閱資料、用工具分析對比了兩張png圖片的結構,欣喜得發現問題跟png格式並無半毛錢關係。冷靜下來,仍是用老辦法,一步一步跟代碼!!!!
遊戲圖壓縮後P2大於P1(是的你沒看錯,壓縮後圖片反而大,壓縮步驟取bitmap,再繪製,最後質量壓縮成jpeg),因此是拿原始圖片看成大圖P3去生成縮略圖P4,原始圖片有透明通道,因此對應的縮略圖能加上白色背景;骰子圖片壓縮後發現比原圖小,因此用壓縮圖P2看成大圖P3去生成縮略圖P4。P2是質量壓縮png生成的jpeg,已經丟失透明通道,是一張黑色背景的圖。即便在P4加上白色背景也被上層圖層覆蓋,咱們看到的就是黑色骰子縮略圖。
我以前分析的過程當中忽略了壓縮原始圖片生成P2這一步。一葉障目,理清了思路,問題就顯而易見了!
既然理清了流程,那就把全部狀況下的表現分析下吧。咱們看看勾選原圖下的表現。
這裏很好理解,骰子圖勾選原圖後,是把原始圖片生成縮略圖P4,原始圖有透明通道,因此生成的縮略圖也有白色背景。
若是是PC發送PNG圖片,客戶端去接收消息下載圖片呢?PC端發送圖片不存在是否勾選原圖的概念,也不存在壓縮的概念(耿直boy)。客戶端接收方會去下載PC端發送的圖片P5和架生平成的縮略圖P7。
這時我在迴歸過程當中又發現了一塊兒不尋常的現象。客戶端發送遊戲圖後,接收端收到圖片,在AIO中的縮略圖會有一個由黑變白的過程。呵呵,兵來將擋,bug來我解。又滾去熟悉了下接收端的邏輯。
發送的這張遊戲圖是由透明通道的,架平並無爲有透明通道的圖片添加白色背景的策略,因此接收端下載的是一張黑色背景的架平縮略圖。
這裏要提到手q的預下載策略。用戶可能會去點開大圖,若是點擊時再去下載,轉菊花的過程體驗不好,因此手q會綜合網絡狀況、當前已用流量等維度去判斷是否須要提早幫用戶下載大圖。圖中圖片消息命中了預下載策略,手q幫用戶提早下載好了大圖。
這時候問了,大圖明明是黑色背景,爲何AIO中會閃變成白色?哈哈哈,這裏又是手q人性化的一點,因爲下載好了大圖,爲了讓用戶在AIO中能夠直接能夠看到比較清晰的縮略圖,手q不信任架生平成的縮略圖,用已經下載的大圖在本地生成了相對高清的縮略圖。
而下載的大圖是有透明通道的png,根據前面已經提到的產品策略,咱們會給本地生成的縮略圖加上白色背景,因此出現了閃變~
全文告一段落,在跟進問題的過程當中,又完整的走了一遍手Q的圖片發送流程。
除了提升對業務的熟悉程度以外,不由感慨,前輩們爲圖片發送展現流程作了數不清的優化項,前人栽樹後人乘涼,由衷的欽佩!
輕聽變色之謎
高斯模糊效果的幾種實現方案及性能對比
AfterEffect 從零開始 篇一 : 瞭解軟件界面,掌握基礎操做
此文已由做者受權騰訊雲技術社區發佈,轉載請註明原文出處
原文連接:https://cloud.tencent.com/com...