关于图片压缩的总结

当需要往服务器上传图片的时候,越小越好,既节省流量也节省时间,同时也节省内存。

今天我遇到的问题就是这样,我最初的解决办法是动态的设置BitmapFactory.Options的inSampleSize的值,方法如下:

private void compressImageFromFile(String srcPath) {
		long s = System.currentTimeMillis();
		try {

			BitmapFactory.Options newOpts = new BitmapFactory.Options();
			newOpts.inJustDecodeBounds = true;
			Bitmap btemp = BitmapFactory.decodeFile(srcPath, newOpts);
			Log.i(TAG, "w=" + newOpts.outWidth);
			Log.i(TAG, "h=" + newOpts.outHeight);
			Log.i(TAG, "w*h=" + newOpts.outWidth * newOpts.outHeight);
			newOpts.inJustDecodeBounds = false;
			ByteArrayOutputStream stream = new ByteArrayOutputStream();
			newOpts.inSampleSize = 7;// 设置采样率

			newOpts.inPreferredConfig = Config.RGB_565;
			Bitmap bmp = BitmapFactory.decodeFile(srcPath, newOpts);
			Log.i(TAG, "bmp.getByteCount()=" + bmp.getByteCount());
			bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
			byte[] bytes = stream.toByteArray();
			Log.i(TAG, "first--bytes.length=" + bytes.length);
			while (bytes.length > (5 * 1024 * 1024)) {
				int sample_size = (int) Math.ceil((float) bytes.length
						/ (5 * 1024 * 1024));
				Log.i(TAG, "sample_size=" + sample_size);
				newOpts.inSampleSize = sample_size;
				bmp = BitmapFactory.decodeFile(srcPath, newOpts);
				stream.reset();
				bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
				bytes = stream.toByteArray();
				Log.i(TAG, "bytes.length=" + bytes.length);
			}

			Log.i(TAG, "bytes.length=" + bytes.length);
			Log.i(TAG, "bmp.getWidth()=" + bmp.getWidth());
			Log.i(TAG, "bmp.getHeight()=" + bmp.getHeight());

		} catch (Exception e) {

			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Log.i(TAG,
				"System.currentTimeMillis()-s="
						+ (System.currentTimeMillis() - s));
	}
问题是速度很慢,每次耗时是近40秒,我的要求是压缩的图片大小要小于5M,压缩后的大小,即bytes流的大小都在2M左右,符合要求。

在这个里面我没有使用质量压缩,原因是对于一张太大的图片质量压缩达不到最后要求,但是这个尺寸的压缩,由于inSimpleSize是进行一次compress之后,计算出来的所以耗时太多,也有部分人用的是指定压缩后的宽高,一步到位。但是在选择固定值时我由于知识不完备不知道该指定多大的,最后查资料,找到一个较新的统计:http://blog.sina.com.cn/s/blog_541bdbb80102v2km.html 最后选定的大小是:1136*640

方法如下:

private Bitmap compressImageFromFileFaster(String srcPath) {
		long s = System.currentTimeMillis();
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		BitmapFactory.Options newOpts = new BitmapFactory.Options();
		newOpts.inJustDecodeBounds = true;
		BitmapFactory.decodeFile(srcPath, newOpts);// 打开空图片获取分辨率
		newOpts.inSampleSize = getinSampleSize(newOpts);// 设置缩放倍数
		newOpts.inJustDecodeBounds = false;
		Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
		bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
		Log.i(TAG, "压缩后分辨率:" + newOpts.outWidth + "*" + newOpts.outHeight);
		Log.i(TAG, "分辨率压缩后的大小:" + (baos.toByteArray().length / (1024 * 1024))
				+ "");
		Log.i(TAG, "耗时=" + (System.currentTimeMillis() - s));

		return bitmap;
	}


/**
	 * 获取图片压缩的比率
	 * 
	 * @param options
	 * @return
	 */
	public static int getinSampleSize(BitmapFactory.Options options) {
		final int height = options.outHeight;
		final int width = options.outWidth;
		float reqHeight = 1136.0f;
		float reqWidth = 640.0f;
		int inSampleSize = 1;

		if (height > width && height > reqHeight) {
			inSampleSize = (int) Math.ceil(height / reqHeight);

		} else if (height <= width && width > reqWidth) {
			inSampleSize = (int) Math.ceil(width / reqWidth);

		}
		return inSampleSize;
	}

耗时在2000到3000毫秒。

更多介绍:http://www.oschina.net/code/snippet_726985_22365

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值