深入了解安卓圖片優(yōu)化到底是個什么東西

  • 這篇文章相對于以前的理解要深入好多

圖片壓縮

好處:節(jié)約用戶流量,降低服務(wù)器的帶寬,降低App的內(nèi)存使用
分類:質(zhì)量壓縮,尺寸壓縮

尺寸壓縮之鄰近采樣

臨近采樣:是基于鄰近點插值算法實現(xiàn)的,會根據(jù)相對位置取一個像素代替原圖幾個像素

        val option=BitmapFactory.Options()
        //采樣率
        option.inSampleSize=1
        val bitmap=BitmapFactory.decodeResource(resources,R.mipmap.demo,option)
        mImageView.setImageBitmap(bitmap)
  • 領(lǐng)近采樣有個缺陷,如果原圖是一張紅白相間的圖片,如果尺寸合適的話,就會采集成一張紅色的或者是白色的圖片
demo.png

尺寸壓縮之雙線性采樣

雙線性采樣:采用雙線性插值算法,會根據(jù)相對位置取一個像素點替換掉幾個像素,其實就是周圍的 2*2的點

  val bitmap1 = BitmapFactory.decodeResource(resources, R.mipmap.demo)
        val bitmap2 = Bitmap.createScaledBitmap(bitmap1,bitmap1.width/2,bitmap1.height/2,true)
        mImageView.setImageBitmap(bitmap2)
  • 它的效果就是出現(xiàn)一種混合的效果,如果是一張間隔圖,那么他的顏色就是居中取

  • 一般都是鄰近采樣和雙線性采樣一起使用,具體的時候

    image.png

質(zhì)量壓縮:SKia 圖形引擎 libjpeg,這種會把圖片生產(chǎn)新的,同時放在本地,通過BitmapFactory.decodeFile 去加載本地圖片

quality 0-100 ,0代表質(zhì)量越小,100越大,

        //最好把這個圖片copy到本地區(qū),這樣就能夠看到真正質(zhì)量的卻別 
        val byteArrayOutputStream = ByteArrayOutputStream()
        val compress = bitmap1.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream)

假如一張圖片的質(zhì)量在80k,那么通過這種方式的壓縮的結(jié)果 webp-2k png-50k jepg-10k,所以webp是最優(yōu)的結(jié)果,其實如果壓縮的是PNG格式的話,改變quality的時候,壓縮的大小其實不會改變,這點注意

  • 直接調(diào)用的是nativeCompress,其實最底層調(diào)用的是 SKImageEncoder,其實就是SKia
    image.png
  • skia是個2D向量圖形處理函數(shù)庫,包含字型、坐標(biāo)轉(zhuǎn)換,以及點陣圖都有高效能且簡潔的表現(xiàn)。不僅用于Google Chrome瀏覽器,新興的Android開放手機(jī)平臺也采用skia作為繪圖處理,搭配OpenGL/ES與特定的硬件特征,強(qiáng)化顯示的效果,包括現(xiàn)在的Flutter也是使用這個引擎,所以Flutter的打包的出來的ios其實比較大,這點注意

skia

skia 這是開源的

skia 已被應(yīng)用于Android、Google Chrome、Chrome OSChromium OS、Mozilla FirefoxFirefox OS以及Sublime Text。

2012年時Skia有大概80,000行程式碼,以C++開發(fā)而成,所以牛逼呀,我們寫個80000行代碼,都是面向白的CV工程師,哈哈,我寫到這里我自己都笑了

  • skia 在安卓中調(diào)用的過程:
    Java函數(shù)-native函數(shù)-skia函數(shù)-對應(yīng)的三方庫 libijpeg ,哈夫曼表就在libjpeg

  • 安卓版本圖,來源于維基百科


    image.png
  • 在安卓6.0和安卓7.0壓縮JPEG圖片的區(qū)別,實際上是Android在調(diào)用libjpeg的時候有一些區(qū)別,在Android7.0 SKImageDecoder_libjpeg.cpp中多了一個optimize_coding的標(biāo)記是否計算哈夫曼表
    官方的說法:為了提高運行的效率,Google在Android的Skia實現(xiàn)中,對JPG壓縮處理算法改寫來代替調(diào)用libjpeg-turbo,實現(xiàn)了一個低精度的YUV轉(zhuǎn)換為RGB的算法,但該改寫算法中除法取整的方式不合理,不僅每次壓縮后畫質(zhì)劣化更嚴(yán)重,隨著誤差逐步累積,還會導(dǎo)致圖片會越來越偏向綠色。最終該缺陷在2016年4月得到修復(fù),修改回直接使用libjpeg-turbo的調(diào)用。而作為Android基礎(chǔ)庫的一部分,該修復(fù)也被認(rèn)為預(yù)計于Android 7中修復(fù)。

兩種算法 定長算法和哈夫曼:libjpeg在壓縮圖片使用的就是這種算法,我其實也說不清哈,這個算法需要的請詳細(xì)了解

image.png
image.png

image.png

最后

  • 在以前我寫過一篇文章 [安卓代碼、圖片、布局、網(wǎng)絡(luò)和電量優(yōu)化](http://www.itdecent.cn/p/82b76e0cb41e其實現(xiàn)在看來還是太簡單,這篇文章要詳細(xì)一些

  • 什么時候需要,比如說我們在開發(fā)聊天頁面的時候,發(fā)送本地圖片,現(xiàn)在手機(jī)都是10m的圖片,肯定需要去優(yōu)化他的大小,要么尺寸壓縮,或者質(zhì)量壓縮,在質(zhì)量壓縮的時候,當(dāng)然選擇WEBP格式,只不過要copy一份到本地

  • 能靈活運用才是最好的

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容