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

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


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

webp的库源码下载地址:http://download.youkuaiyun.com/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的情况
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值