关于图片压缩的总结

来源:互联网 发布:弗兰肯斯坦 知乎 编辑:程序博客网 时间:2024/04/29 20:32

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

今天我遇到的问题就是这样,我最初的解决办法是动态的设置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 blocke.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

0 0
原创粉丝点击