图片的压缩

最近弄一个在画板上签名然后保存成图片保存在本地,压缩图片(要求:压缩后的图片大小小于5kb,宽高130*78)

我的压缩办法是按比例大小压缩+缩放压缩+质量压缩


byte[] bs=Const.compressScale(newBitmap);//按比例大小压缩+缩放压缩+质量压缩 newBitmap为bitmap


/**
	 * 图片按比例大小压缩方法
	 * @param image
	 * (根据Bitmap图片压缩)
	 * 
	 * @return byte[]
	 */
	public static byte[] compressScale(Bitmap image) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		image.compress(Bitmap.CompressFormat.PNG, 100, baos);

		// 判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
		if (baos.toByteArray().length / 1024 > 1024) {
			baos.reset();// 重置baos即清空baos
			image.compress(Bitmap.CompressFormat.PNG, 80, baos);// 这里压缩50%,把压缩后的数据存放到baos中
		}
		ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
		BitmapFactory.Options newOpts = new BitmapFactory.Options();
		// 开始读入图片,此时把options.inJustDecodeBounds 设回true了
		newOpts.inJustDecodeBounds = true;
		Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
		newOpts.inJustDecodeBounds = false;
		int w = newOpts.outWidth;
		int h = newOpts.outHeight;
		Log.i("Const", w + "---------------" + h);

		// inSampleSize比1小的话会被当做1(为1表示不缩放),任何inSampleSize的值会被取接近2的幂值。
		newOpts.inSampleSize = calculateInSampleSize(newOpts, 130, 78);// 设置缩放比例
		// newOpts.inPreferredConfig = Config.RGB_565;//降低图片从ARGB888到RGB565

		// 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
		isBm = new ByteArrayInputStream(baos.toByteArray());
		bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
		return scale(bitmap, (int) Const.width, (int) Const.height, true);// 缩放压缩(130*78)

	}
	
	
	/**
	 * (按比例大小压缩) 压缩比例 inSampleSize
	 * @param options
	 * @param reqWidth
	 * @param reqHeight
	 * @return
	 */
	public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
		final int height = options.outHeight;
		final int width = options.outWidth;
		int inSampleSize = 1;

		if (height > reqHeight || width > reqWidth) {
			final int heightRatio = Math.round((float) height / (float) reqHeight);
			final int widthRatio = Math.round((float) width / (float) reqWidth);
			inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
		}
		Log.e("url", "inSampleSize==" + inSampleSize);
		return inSampleSize;
	}
	
	
	/**
	 * /** 缩放图片
	 *
	 * @param src
	 *            源图片
	 * @param newWidth
	 *            新宽度
	 * @param newHeight
	 *            新高度
	 * @param recycle
	 *            是否回收
	 * @return 缩放后的图片的字节数组
	 */
	public static byte[] scale(Bitmap src, int newWidth, int newHeight, boolean recycle) {
		Bitmap ret = Bitmap.createScaledBitmap(src, newWidth, newHeight, true);
		if (recycle && !src.isRecycled())
			src.recycle();
		return compressImage(ret);//质量压缩图片(大小小于5kb)
	}
	
	
	/**
	 * 质量压缩方法
	 * 
	 * @param image
	 * @return byte[]
	 */
	public static byte[] compressImage(Bitmap image) {

		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		image.compress(Bitmap.CompressFormat.PNG, 100, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
		int options = 90;
		Log.e("url", "baos.toByteArray().length压缩前==" + baos.toByteArray().length);
		while (baos.toByteArray().length / 1024 > 4) { // 循环判断如果压缩后图片是否大于5kb,大于继续压缩
			baos.reset(); // 重置baos即清空baos
			image.compress(Bitmap.CompressFormat.PNG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中
			options -= 5;// 每次都减少10
			if (options <= 0) {
				options = 0;
				break;
			}

			Log.e("url", "options==" + options);
		}
		Log.e("url", "baos.toByteArray().length压缩后==" + baos.toByteArray().length);
		return baos.toByteArray();
	}

压缩完后在保存
           byte[] buffer = bs;
if (buffer != null) {
File file = new File(path);
if (file.exists()) {
if (file.delete()) {
System.out.println("file delete success!");
} else {
System.out.println("file delete fail!");
}
}
file = new File(path);
OutputStream outputStream = new FileOutputStream(file);
outputStream.write(buffer);
outputStream.close();
scanMediaFile(file);
if (newBitmap != null && !newBitmap.isRecycled()) {
// 回收并且置为null
newBitmap.recycle();
}
}


注意点:

1、调用质量压缩的时候,网上很多方法是:质量压缩后byte数组转成bitmap,然后bitmap在转成byte数组写入file,这样的图片大小并没有压缩。我的解决办法就是:质量压缩后byte数组直接返回,然后写入file,这样图片就能压缩到自己所限制的大小;

2、图片压缩,如果图片大小很大,还是需要先按比例压缩一下,在进行质量压缩,不然有时候直接质量压缩,当options=0(0~100)的时候,就无法再压缩了。也就无法达到我们所要压缩的大小

3、按比例大小压缩:

newOpts.inSampleSize = be; // 设置缩放比例

inSampleSize比1小的话会被当做1(为1表示不缩放),任何inSampleSize的值会被取接近2的幂值。

4、如果是画布上签名形成图片的,然后要注意画笔的粗细,如果画笔太细,可能导致像素太低,也就导致字体断断续续的

5、IE上打不开)压缩图片的时候,图片保存格式是.png,压缩图片的时候,也要用对应的PNGimage.compress(Bitmap.CompressFormat.PNG, options, baos);


有错误或者更好方法欢迎指出,谢谢




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值