Android 安裝包優化】WebP 應用 ( Android 中使用 libwebp.so 庫解碼 WebP 圖片 )

      網友投稿 1344 2022-05-30

      文章目錄

      一、Android 中使用 libwebp.so 庫解碼 WebP 圖片

      二、完整代碼示例

      三、參考資料

      一、Android 中使用 libwebp.so 庫解碼 WebP 圖片

      libwebp.jar 中解碼相關的的方法如下 : libwebpJNI 是 Java 層調用 libwebp.so 動態庫的入口類 ;

      public static byte[] WebPDecodeRGB(byte[] var0, long var1, int[] var3, int[] var4) { return libwebpJNI.WebPDecodeRGB(var0, var1, var3, var4); } public static byte[] WebPDecodeRGBA(byte[] var0, long var1, int[] var3, int[] var4) { return libwebpJNI.WebPDecodeRGBA(var0, var1, var3, var4); } public static byte[] WebPDecodeARGB(byte[] var0, long var1, int[] var3, int[] var4) { return libwebpJNI.WebPDecodeARGB(var0, var1, var3, var4); } public static byte[] WebPDecodeBGR(byte[] var0, long var1, int[] var3, int[] var4) { return libwebpJNI.WebPDecodeBGR(var0, var1, var3, var4); } public static byte[] WebPDecodeBGRA(byte[] var0, long var1, int[] var3, int[] var4) { return libwebpJNI.WebPDecodeBGRA(var0, var1, var3, var4); }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      【Android 安裝包優化】WebP 應用 ( Android 中使用 libwebp.so 庫解碼 WebP 圖片 )

      在本博客示例中 , 使用的是 WebPDecodeARGB 方法 , 傳入的 4 4 4 個參數作用 :

      byte[] var0 : ARGB 字節數據 ;

      int var1 : ARGB 字節數據字節個數 ;

      int[] var3 : 圖像寬度 , 傳入的是數組 , 只有 1 個元素 , 作為返回值使用 ;

      int[] var4 : 圖像高度 , 傳入的是數組 , 只有 1 個元素 , 作為返回值使用 ;

      public static byte[] WebPDecodeARGB(byte[] var0, long var1, int[] var3, int[] var4) { return libwebpJNI.WebPDecodeARGB(var0, var1, var3, var4); }

      1

      2

      3

      使用 libwebp.so 庫解碼 WebP 圖片 : 讀取 R.mipmap.icon_webp 資源文件 , 使用 libwebp 解碼出 RGBA 數據 , 然后將 RGBA 數據轉換為 Bitmap 位圖 , 最后將 Bitmap 位圖顯示到界面中 ;

      @SuppressLint("ResourceType") fun libwebpDecode() { var webPStart = System.currentTimeMillis() // 獲取 WebP 資源文件的輸入流 var inputStream: InputStream = resources.openRawResource(R.mipmap.icon_webp) // 將數據讀取到 Byte 數組輸出流中 var bos: ByteArrayOutputStream = ByteArrayOutputStream() var buffer: ByteArray = ByteArray(2048) // 記錄長度 var len = inputStream.read(buffer) while ( len != -1 ){ bos.write(buffer, 0, len) len = inputStream.read(buffer) } inputStream.close() // 讀取完畢后 , 獲取完整的 Byte 數組數據 var data_webp: ByteArray = bos.toByteArray() // 將 ByteArray 解碼成 ARGB 數據 var width = IntArray(1) var height = IntArray(1) var data_argb_byte: ByteArray = libwebp.WebPDecodeARGB(data_webp, data_webp.size.toLong(), width, height) // 將 data_argb: ByteArray 轉為 IntArray var data_argb_int = IntArray(data_argb_byte.size / 4) // 使用 nio 中的 ByteBuffer 進行讀寫 var byteBuffer: ByteBuffer = ByteBuffer.wrap(data_argb_byte); // 將 byteBuffer 轉為 IntBuffer , 然后獲取其中的 int 數組 byteBuffer.asIntBuffer().get(data_argb_int) // 將 ARGB 數據轉為 Bitmap 位圖圖像 var bitmap: Bitmap = Bitmap.createBitmap( data_argb_int, // 圖像數據 , int 數組格式 width[0], // 圖像寬度 height[0], // 圖像高度 Bitmap.Config.ARGB_8888 // 圖像顏色格式 ) // 界面顯示解碼后的位圖 binding.imageView.setImageBitmap(bitmap) Log.e(TAG, "使用 libwebp.so 庫解碼 WebP 格式圖片時間 : ${System.currentTimeMillis() - webPStart} ms") }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      43

      44

      45

      46

      二、完整代碼示例

      調用 libweb.jar 中的 libwebp.WebPDecodeARGB 函數 , 進行 WebP 圖片的解碼操作 ;

      同時測試解碼的時長 ;

      package kim.hsl.webp import android.annotation.SuppressLint import android.graphics.Bitmap import android.graphics.BitmapFactory import android.os.Bundle import android.util.Log import androidx.appcompat.app.AppCompatActivity import com.google.webp.libwebp import kim.hsl.webp.databinding.ActivityMainBinding import java.io.ByteArrayOutputStream import java.io.FileOutputStream import java.io.InputStream import java.nio.ByteBuffer class MainActivity : AppCompatActivity() { companion object{ val TAG = "MainActivity" init { System.loadLibrary("webp") } } lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) Log.e(TAG, "libwebp 函數庫版本 : ${libwebp.WebPGetDecoderVersion()}") // 測試 WebP 解碼速度 decodeWebP() // 測試 WebP 編碼速度 encodeWebP() // 使用 libwebp 庫編碼 WebP 圖片 libwebpEncode() // 使用 libwebp 庫解碼 WebP 圖片 libwebpDecode() } @SuppressLint("ResourceType") fun libwebpDecode() { var webPStart = System.currentTimeMillis() // 獲取 WebP 資源文件的輸入流 var inputStream: InputStream = resources.openRawResource(R.mipmap.icon_webp) // 將數據讀取到 Byte 數組輸出流中 var bos: ByteArrayOutputStream = ByteArrayOutputStream() var buffer: ByteArray = ByteArray(2048) // 記錄長度 var len = inputStream.read(buffer) while ( len != -1 ){ bos.write(buffer, 0, len) len = inputStream.read(buffer) } inputStream.close() // 讀取完畢后 , 獲取完整的 Byte 數組數據 var data_webp: ByteArray = bos.toByteArray() // 將 ByteArray 解碼成 ARGB 數據 var width = IntArray(1) var height = IntArray(1) var data_argb_byte: ByteArray = libwebp.WebPDecodeARGB( data_webp, data_webp.size.toLong(), width, height) // 將 data_argb: ByteArray 轉為 IntArray var data_argb_int = IntArray(data_argb_byte.size / 4) // 使用 nio 中的 ByteBuffer 進行讀寫 var byteBuffer: ByteBuffer = ByteBuffer.wrap(data_argb_byte); // 將 byteBuffer 轉為 IntBuffer , 然后獲取其中的 int 數組 byteBuffer.asIntBuffer().get(data_argb_int) // 將 ARGB 數據轉為 Bitmap 位圖圖像 var bitmap: Bitmap = Bitmap.createBitmap( data_argb_int, // 圖像數據 , int 數組格式 width[0], // 圖像寬度 height[0], // 圖像高度 Bitmap.Config.ARGB_8888 // 圖像顏色格式 ) // 界面顯示解碼后的位圖 binding.imageView.setImageBitmap(bitmap) Log.e(TAG, "使用 libwebp.so 庫解碼 WebP 格式圖片時間 : ${System.currentTimeMillis() - webPStart} ms") } fun libwebpEncode(){ var webPStart = System.currentTimeMillis() // 讀取一張本地圖片 var bitmap = BitmapFactory.decodeResource(resources, R.mipmap.icon_png) // 獲取位圖寬高 var width = bitmap.width var height = bitmap.height // 申請一個 Byte 緩沖區 var byteBuffer: ByteBuffer = ByteBuffer.allocate(bitmap.byteCount) // 將 位圖 數據拷貝到 Byte 緩沖區中 bitmap.copyPixelsToBuffer(byteBuffer) // 使用 libwebp.so 進行 WebP 格式編碼 var data: ByteArray = libwebp.WebPEncodeRGBA( byteBuffer.array(), // 位圖數據 width, // 位圖寬度 height, // 位圖高度 width * 4, // 位圖每行數據 75F // 圖像質量 ) // 將數據寫出到文件中 var fos = FileOutputStream("${cacheDir}/icon_webp2.webp") fos.write(data) fos.close() Log.e(TAG, "使用 libwebp.so 庫編碼 WebP 格式圖片時間 : ${System.currentTimeMillis() - webPStart} ms , " + "輸出文件 : ${cacheDir}/icon_webp2.webp") } fun encodeWebP(){ // 讀取一張本地圖片 var bitmap = BitmapFactory.decodeResource(resources, R.mipmap.icon_png) var pngStart = System.currentTimeMillis() var fos = FileOutputStream("${cacheDir}/icon_png.png") bitmap.compress(Bitmap.CompressFormat.PNG, 75, fos) fos.close() Log.e(TAG, "編碼 png 格式圖片時間 : ${System.currentTimeMillis() - pngStart} ms , " + "輸出文件 : ${cacheDir}/icon_png.png") var webPStart = System.currentTimeMillis() fos = FileOutputStream("${cacheDir}/icon_webp.webp") bitmap.compress(Bitmap.CompressFormat.WEBP, 75, fos) fos.close() Log.e(TAG, "編碼 WebP 格式圖片時間 : ${System.currentTimeMillis() - webPStart} ms , " + "輸出文件 : ${cacheDir}/icon_webp.webp") } fun decodeWebP(){ var pngStart = System.currentTimeMillis() BitmapFactory.decodeResource(resources, R.mipmap.icon_png) Log.e(TAG, "解碼 png 格式圖片時間 : ${System.currentTimeMillis() - pngStart} ") var webPStart = System.currentTimeMillis() BitmapFactory.decodeResource(resources, R.mipmap.icon_webp) Log.e(TAG, "解碼 WebP 格式圖片時間 : ${System.currentTimeMillis() - webPStart} ") } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      43

      44

      45

      46

      47

      48

      49

      50

      51

      52

      53

      54

      55

      56

      57

      58

      59

      60

      61

      62

      63

      64

      65

      66

      67

      68

      69

      70

      71

      72

      73

      74

      75

      76

      77

      78

      79

      80

      81

      82

      83

      84

      85

      86

      87

      88

      89

      90

      91

      92

      93

      94

      95

      96

      97

      98

      99

      100

      101

      102

      103

      104

      105

      106

      107

      108

      109

      110

      111

      112

      113

      114

      115

      116

      117

      118

      119

      120

      121

      122

      123

      124

      125

      126

      127

      128

      129

      130

      131

      132

      133

      134

      135

      136

      137

      138

      139

      140

      141

      142

      143

      144

      145

      146

      147

      148

      149

      150

      151

      152

      153

      154

      155

      156

      157

      158

      執行結果 :

      2021-04-25 17:24:20.486 12660-12707/kim.hsl.webp E/libc: Access denied finding property "vendor.debug.egl.profiler" 2021-04-25 17:24:20.653 12660-12660/kim.hsl.webp E/MainActivity: libwebp 函數庫版本 : 1537 2021-04-25 17:24:20.933 12660-12660/kim.hsl.webp E/MainActivity: 解碼 png 格式圖片時間 : 280 2021-04-25 17:24:21.134 12660-12660/kim.hsl.webp E/MainActivity: 解碼 WebP 格式圖片時間 : 201 2021-04-25 17:24:23.814 12660-12660/kim.hsl.webp E/MainActivity: 編碼 png 格式圖片時間 : 2410 ms , 輸出文件 : /data/user/0/kim.hsl.webp/cache/icon_png.png 2021-04-25 17:24:26.902 12660-12660/kim.hsl.webp E/MainActivity: 編碼 WebP 格式圖片時間 : 3088 ms , 輸出文件 : /data/user/0/kim.hsl.webp/cache/icon_webp.webp 2021-04-25 17:24:30.289 12660-12660/kim.hsl.webp E/MainActivity: 使用 libwebp.so 庫編碼 WebP 格式圖片時間 : 3387 ms , 輸出文件 : /data/user/0/kim.hsl.webp/cache/icon_webp2.webp 2021-04-25 17:24:30.457 12660-12660/kim.hsl.webp E/MainActivity: 使用 libwebp.so 庫解碼 WebP 格式圖片時間 : 168 ms

      1

      2

      3

      4

      5

      6

      7

      8

      使用 libwebp.so 庫解碼 WebP 圖片的速度要 高于 Android 本身自帶 API 的速度 ;

      界面顯示 :

      三、參考資料

      參考文檔 :

      創建 WebP 圖片 : https://developer.android.google.cn/studio/write/convert-webp

      Android 中支持的媒體格式 : https://developer.android.google.cn/guide/topics/media/media-formats

      isparta 工具官網 : http://isparta.github.io/

      isparta 工具 GitHub 地址 : https://github.com/iSparta/iSparta

      Google 提供的 WebP 工具 ( 國內不能訪問 ) : https://developers.google.com/speed/webp/download

      Google WebP 主頁 : https://developers.google.com/speed/webp

      WebP 相關工具下載頁 : https://developers.google.com/speed/webp/download

      WebP工具和函數庫使用文檔 : https://developers.google.com/speed/webp/docs/using

      Android NDK 編譯構建腳本參考文檔 :

      ndk-build 腳本 : https://developer.android.google.cn/ndk/guides/ndk-build

      Android.mk 構建腳本 : https://developer.android.google.cn/ndk/guides/android_mk

      Application.mk 構建腳本 : https://developer.android.google.cn/ndk/guides/application_mk

      博客資源 :

      iSparta 工具 : https://download.csdn.net/download/han1202012/17496041

      Google libwebp 庫 : https://download.csdn.net/download/han1202012/17498155

      libwebp 源碼及編譯相關資源 : https://download.csdn.net/download/han1202012/17826464 ( 源碼 , 編譯腳本 , 編譯結果 so 庫 )

      博客源碼 :

      GitHub 地址 : https://github.com/han1202012/Webp

      CSDN - : https://download.csdn.net/download/han1202012/18125733

      Android 數據結構

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:ROS2編程基礎課程--概述
      下一篇:華為云ModelArts結合AnimeGANv2,讓照片在云上動漫化 丨【華為云AI賀新年】
      相關文章
      亚洲精品国产自在久久| 亚洲av再在线观看| 国产成人麻豆亚洲综合无码精品| 色偷偷亚洲男人天堂| 亚洲欧美不卡高清在线| 亚洲av永久无码精品天堂久久| 亚洲精品视频久久| 亚洲日产2021三区| 亚洲国产精品一区二区久| 亚洲最大的视频网站| 亚洲性69影院在线观看| 亚洲国语在线视频手机在线| 自怕偷自怕亚洲精品| 亚洲欧洲精品视频在线观看| 91亚洲自偷在线观看国产馆| 精品久久亚洲中文无码| 亚洲国产熟亚洲女视频| 亚洲最大中文字幕无码网站| 亚洲深深色噜噜狠狠网站| 在线aⅴ亚洲中文字幕| 亚洲欧美精品午睡沙发| 色窝窝亚洲av网| 亚洲精品视频在线观看你懂的| 亚洲男人的天堂一区二区| 国产av无码专区亚洲国产精品 | 少妇亚洲免费精品| 亚洲精品国产V片在线观看| 久久久久亚洲AV成人网| 亚洲国产精品高清久久久| 无码乱人伦一区二区亚洲| 亚洲黄色片免费看| 亚洲校园春色另类激情| 亚洲乱码无人区卡1卡2卡3| 校园亚洲春色另类小说合集 | 亚洲А∨精品天堂在线| 77777亚洲午夜久久多人| 久久精品国产精品亚洲艾| 亚洲天堂福利视频| 亚洲欧美aⅴ在线资源| 亚洲国产成人爱av在线播放| 久久久久久a亚洲欧洲aⅴ|