【Android 内存优化】Android 原生 API 图片压缩原理 ( 哈夫曼编码开关 | 哈夫曼编码原理 | libjpeg-turbo 函数库 )
文章目錄
- 一、 哈夫曼編碼開關
- 二、 哈夫曼編碼原理
- 三、 libjpeg-turbo 函數庫
- 四、 libjpeg-turbo 函數庫下載
【Android 內存優化】圖片文件壓縮 ( Android 原生 API 提供的圖片壓縮功能能 | 圖片質量壓縮 | 圖片尺寸壓縮 ) 簡要介紹了 圖片文件壓縮格式 , 以及 Android 提供的圖片質量 , 尺寸壓縮原生 API ;
【Android 內存優化】Android 原生 API 圖片壓縮代碼示例 ( PNG 格式壓縮 | JPEG 格式壓縮 | WEBP 格式壓縮 | 動態權限申請 | Android10 存儲策略 ) 主要使用了上述 Android 原生 API 壓縮圖片功能進行圖片壓縮 ;
【Android 內存優化】Android 原生 API 圖片壓縮原理 ( 圖片質量壓縮方法 | 查找 Java 源碼中的 native 方法對應的 C++ 源碼 ) 中主要查找 Bitmap.java 對應的 Native 層的 C++ 類 Bitmap.cpp 源碼文件 , 并分析了其動態注冊 Native 方法的過程 ;
【Android 內存優化】Android 原生 API 圖片壓縮原理 ( Bitmap_compress 方法解析 | Skia 二維圖形庫 | libjpeg 函數庫 | libpng 函數庫 ) 博客中分析了 Bitmap.cpp 中的 Bitmap_compress 方法 ;
一、 哈夫曼編碼開關
上一篇博客 【Android 內存優化】Android 原生 API 圖片壓縮原理 ( Bitmap_compress 方法解析 | Skia 二維圖形庫 | libjpeg 函數庫 | libpng 函數庫 ) 分析到了 實際的圖片壓縮方法是由 Skia 圖形庫執行的 , Skia 圖形庫根據不同的壓縮格式 , 選擇不同的函數庫進行壓縮 , 如果壓縮格式是 JPEG 格式 , 那么使用 libjpeg 庫進行圖片壓縮 , 如果壓縮格式是 PNG 庫 , 那么使用 libpng 庫進行壓縮 ;
1. 哈夫曼編碼 : 在 libjpeg 中提供了圖片哈夫曼編碼功能 , 該功能非常消耗 CPU 性能 , 因此早期的 Android 版本禁用了該功能 , 在 7.0 之后的版本 , 此時 Android 設備上的 CPU 性能很高 , 這時才將哈夫曼編碼功能打開 ; ( SkImageDecoder_libjpeg.cpp 代碼參考 )
2. 打開哈夫曼編碼 : 將 jpeg_compress_struct 結構體的 optimize_coding 成員設置成 TRUE ; 作用是 通知 libjpeg-turbo 為圖像計算最佳的哈夫曼編碼表 , 該操作可以 提高圖片壓縮比例 , 代價是編碼速度較慢 ;
3. 源碼參考 :
SkImageDecoder_libjpeg.cpp 中 SkJPEGImageEncoder 類 ( SkImageEncoder 對應的 JPEG 格式圖片壓縮實現類 ) 中的 onEncode 方法 , 在 7.0 以后的版本 , 打開圖片壓縮哈夫曼編碼功能 ;
// 該類是 SkImageEncoder 的子類 , 在 Bitmap.cpp 中使用的就是 class SkJPEGImageEncoder : public SkImageEncoder { protected:virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) {// ... jpeg_compress_struct cinfo;// ... // 打開哈夫曼編碼 // 通知 libjpeg-turbo 為圖像計算最佳的哈夫曼編碼表// 該功能可以提高壓縮比例 , 代價是編碼速度較慢cinfo.optimize_coding = TRUE;// ... return true;} };源碼位置 7.0.0/external/skia/src/images/SkImageDecoder_libjpeg.cpp ( 7.0.0 以后的源碼才添加了上述功能 )
二、 哈夫曼編碼原理
在 libjpeg 編碼中 , 如果沒有開啟哈夫曼編碼 , 采用的是定長的編碼方式 , 如果打開了哈夫曼編碼 , 采用的就是變長哈夫曼編碼 , 可以大幅度壓縮數據大小 ;
簡介 : 哈夫曼編碼是字符編碼 , 適用于數據文件壓縮場景 , 能大幅度壓縮文件大小 ;
哈夫曼編碼原理 : 每個數據的編碼長度可變 , 文件中出現較多的字符使用短編碼 , 出現較少的字符使用長編碼 , 另外額外維護一張哈夫曼編碼表 , 用于維護字符與編碼的對應關系 , 總體的文件大小會降低 20% 至 90% ;
三、 libjpeg-turbo 函數庫
使用哈夫曼編碼進行圖片壓縮 , 能最大幅度壓縮圖片大小 , 但是 Android 原生編碼中只有 7.0 以后的系統才打開了哈夫曼編碼功能 , 目前的主流應用都要向下兼容到 android-17 平臺版本 , 對應的系統版本是 Android 4.2 Jelly Bean , 這里就需要引入第三方庫 libjpeg-turbo 函數庫 , 進行哈夫曼編碼圖片壓縮 , 該函數庫是由 C 語言開發 , 需要在 Ubuntu 中進行交叉編譯成 ARM 架構的函數庫 ( 動態庫 / 靜態庫 ) , 然后導入到 Android Studio 中使用 ;
Android 源碼中有 libjpeg-turbo 庫 , 但是Java 框架中提供的 Bitmap.java 只能調用 Bitmap.cpp 中的代碼 , Bitmap.cpp 中通過 Skia 2D 圖形庫調用 libjpeg 庫 , 在該 C++ 代碼中是固定的 , 開發者無法修改框架層的源碼 , 因此該函數庫無法被開發者調用到 ;
NDK 交叉編譯開發參考 : Android NDK 開發 專欄
四、 libjpeg-turbo 函數庫下載
1. libjpeg-turbo 相關資源鏈接 :
① libjpeg-turbo 官方網站 : https://libjpeg-turbo.org/
② GitHub 地址 : libjpeg-turbo/libjpeg-turbo
③ libjpeg-turbo 文檔 : 文檔地址
2. 下載發布版本 :
在 Android 工程中使用該函數庫 , 盡量下載發布的穩定版本 , 最好不要直接下載開發中的 DEBUG 版本 , 可能存在 BUG ;
如下圖 , 找到 release 發布版本界面 , 下載最新的發布版本 ; 或者直接點擊 libjpeg-turbo/libjpeg-turbo 項目的 Release 發布版本地址 進入該界面 ;
進入 Release 界面后 , 查看到目前最新的發布版本是 2.0.5 版本 , 直接下載該源碼 ; 之后需要到 Ubuntu 中進行交叉編譯 ;
下載這個 Source code (tar.gz) 源碼 , 到 Ubuntu 中進行交叉編譯 ; ( 也可以直接點擊上述連接下載 )
總結
以上是生活随笔為你收集整理的【Android 内存优化】Android 原生 API 图片压缩原理 ( 哈夫曼编码开关 | 哈夫曼编码原理 | libjpeg-turbo 函数库 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 内存优化】Androi
- 下一篇: 【Android 内存优化】libjpe