在Android 4.0以下机型上支持webp编码和解码

来源:互联网 发布:医学影像工作站软件 编辑:程序博客网 时间:2024/06/03 07:07

据说webp编码产生的文件大小要比jpeg小很多,但是webp在Android 4.0以下的机型上不被支持,所以这里采取的思路跟jpeg压缩的时候一样,将webp的库使用NDK移植到Android 4.0以下的机型上。


第一步:使用NDK移植webp编码解码库

webp的库源码下载地址:http://download.csdn.net/detail/lihuapinghust/8221345


下载好了之后,解压到Android工程的JNI目录,将swig目录下面的libwebp_java_wrap.c文件拷贝到src目录下,然后在Android.mk文件的LOCAL_SRC_FILES中加上libwebp_java_wrap.c文件,按照上一篇博客的方法进行JNI编译,得到so库


第二部,接口设计

非常幸运的是libwebp库已经为我们写好了JNI的接口和Java接口,我们只需要直接调用即可,将swig下面的libwebp.jar文件拷贝到Android工程的libs目录下,然后就可以在java层使用libwebp的接口了


解码接口的实现:

public static Bitmap decodeStream(InputStream is) {Bitmap bitmap = null;byte[] buffer = new byte[1024];ByteArrayOutputStream baos = new ByteArrayOutputStream();try {int ret;while ((ret = is.read(buffer, 0, buffer.length)) > 0) {baos.write(buffer);}byte[] data = baos.toByteArray();int[] width = new int[] { 0 };int[] height = new int[] { 0 };byte[] decodedData = libwebp.WebPDecodeARGB(data, data.length,width, height);int[] pixels = new int[decodedData.length / 4];ByteBuffer.wrap(decodedData).asIntBuffer().get(pixels);bitmap = Bitmap.createBitmap(pixels, width[0], height[0],Bitmap.Config.ARGB_8888);} catch (IOException e) {e.printStackTrace();}return bitmap;}


编码的接口实现:

public static void compress(Bitmap bitmap, int quality, OutputStream os) {Config config = bitmap.getConfig();Log.i(TAG, "config = " + config.toString());int width = bitmap.getWidth();int height = bitmap.getHeight();byte[] sourceByteArray;byte[] encodedData = null;if (config.equals(Config.ARGB_8888)) {ByteBuffer byteBuffer = ByteBuffer.allocate(bitmap.getRowBytes()* bitmap.getHeight());bitmap.copyPixelsToBuffer(byteBuffer);sourceByteArray = byteBuffer.array();encodedData = libwebp.WebPEncodeRGBA(sourceByteArray, width,height, width * 4, quality);} else {sourceByteArray = new byte[width * height * 4];for (int i = 0; i < width; i++) {for (int j = 0; j < height; j++) {int pixel = bitmap.getPixel(i, j);int index = (j * width + i) * 4;sourceByteArray[index] = (byte) (pixel & 0xff);sourceByteArray[index + 1] = (byte) (pixel >> 8 & 0xff);sourceByteArray[index + 2] = (byte) (pixel >> 16 & 0xff);sourceByteArray[index + 3] = (byte) (pixel >> 24 & 0xff);}}encodedData = libwebp.WebPEncodeBGRA(sourceByteArray, width,height, width * 4, quality);}try {os.write(encodedData);} catch (IOException e) {e.printStackTrace();}}

注意编码接口中要注意检查bitmap的config设置,要区分ARGB_8888和非ARGB_8888的情况

0 0