掌握excel线性回归技巧助力数据分析与决策优化
1211
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
在本博客示例中 , 使用的是 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小时内删除侵权内容。