Android 图片压缩
来源:互联网 发布:sql server可视化界面 编辑:程序博客网 时间:2024/06/10 09:10
从转行Android这个行业,对图片这一块都是一个模糊区,总是理解不彻底,下午闲来无事,所以就在网上查查资料,总结一下。废话不说,马上开始。
首先,大家都知道图片压缩,大致可以分为2中,质量压缩(不改变图片的尺寸)和尺寸压缩(相当于是像素上的压缩),质量压缩一般可用于上传大图前的处理,这样就可以节省一定的流量
而图片的储存也是三种:硬盘上时是file,网络传输时是stream,内存中是stream或bitmap。
先看第一种:
1. 将图片保存到本地时进行压缩, 即将图片从Bitmap形式变为File形式时进行压缩,
private Bitmap compressImage(Bitmap image){ ByteArrayOutputStream out = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG,100,out);//不压缩是100,表示压缩率为0
int intoptions = 100; while (out.toByteArray().length/1024>100){//循环判断如果压缩后图片是否大于100kb,大于继续压缩 out.reset();//重置out即清空 intoptions -=10; image.compress(Bitmap.CompressFormat.JPEG,intoptions,out); }
//把压缩后的数据baos存放到ByteArrayInputStream中
ByteArrayInputStream input = new ByteArrayInputStream(out.toByteArray()); Bitmap bitmap = BitmapFactory.decodeStream(input,null,null);//把ByteArrayInputStream数据生成图片 return bitmap;}
第二:图片按比例大小压缩方法(根据路径获取图片并压缩):
首先需要了解BitmapFactory相信大家都很熟悉了,这个类里面的所有方法都是用来解码创建一个Bitmap,其中有一个重要的类是Options,此类用于解码Bitmap时的各种参数控制,那这里面的各种参数都是什么含义呢?今天我们就来重点解读几个参数。
1、inJustDecodeBounds :如果我们把它设为true,那么BitmapFactory.decodeFile(String path, Options opt)并不会真的返回一个Bitmap给你,它仅仅会把它的宽,高取回来给你,这样就不会占用太多的内存,也就不会那么频繁的发生OOM了。
2、inJustDecodeBounds:如果将这个值置为true,那么在解码的时候将不会返回bitmap,只会返回这个bitmap的尺寸。这个属性的目的是,如果你只想知道一个bitmap的尺寸,但又不想将其加载到内存时。这是一个非常有用的属性。
3、inSampleSize:
这个值是一个int,当它小于1的时候,将会被当做1处理,如果大于1,那么就会按照比例(1 / inSampleSize)缩小bitmap的宽和高、降低分辨率,大于1时这个值将会被处置为2的倍数。例如,width=100,height=100,inSampleSize=2,那么就会将bitmap处理为,width=50,height=50,宽高降为1 / 2,像素数降为1 / 4。
4、inPreferredConfig:这个值是设置色彩模式,默认值是ARGB_8888,在这个模式下,一个像素点占用4bytes空间
,一般对透明度不做要求的话,一般采用RGB_565模式,这个模式下一个像素点占用2bytes
5、inPremultiplied:这个值和透明度通道有关,默认值是true,如果设置为true,则返回的bitmap的颜色通道上会预先附加上透明度通道。
6、inDither:这个值和抖动解码有关,默认值为false,表示不采用抖动解码。如果想知道什么是抖动解码,请参看另一篇文章:http://blog.csdn.net/haozipi/article/details/47185535
7、inDensity:表示这个bitmap的像素密度(对应的是DisplayMetrics中的densityDpi,不是density)。
8、inTargetDensity:表示要被画出来时的目标像素密度(对应的是DisplayMetrics中的densityDpi,不是density)。
9、inScreenDensity:表示实际设备的像素密度(对应的是DisplayMetrics中的densityDpi,不是density)。
10、inScaled:设置这个Bitmap是否可以被缩放,默认值是true,表示可以被缩放。
11、inDensity,inTargetDensity,inScreenDensity三个值的具体关系请参看另一篇文章:http://blog.csdn.net/haozipi/article/details/47185917
方法2:
private Bitmap getimage(String srcPath){ /* * BitmapFactory相信大家都很熟悉了,这个类里面的所有方法都是用来解码创建 * 一个Bitmap,其中有一个重要的类是Options,此类用于解码Bitmap时的各种参数控制, * */ BitmapFactory.Options newOpts = new BitmapFactory.Options(); newOpts.inJustDecodeBounds = true;//图01 Bitmap bitmap = BitmapFactory.decodeFile(srcPath,newOpts);////此时返回bm为空 newOpts.inJustDecodeBounds =false;// int w = newOpts.outWidth; int h = newOpts.outHeight; float hh = 800f;//这里设置高度为800f float ww = 480f;//这里设置高度480分; int be = 1;//1表示不缩放 if(w>h&&w>ww){//如果宽度大的话根据宽度固定大小缩放 be = (int)(newOpts.outWidth/ww); }else if(w < h && h > hh){ be = (int) (newOpts.outHeight / hh); } if(be<=0){ be = 1; } newOpts.inSampleSize = be;//这里设置比例 //重新读入图片,注意这里已经把newOpts.inJustDecodeBounds =false, bitmap = BitmapFactory.decodeFile(srcPath,newOpts); return compressImage(bitmap);}
方法3:(其实这种是第一种和第二种合起来用)
// 图片按比例大小压缩方法private Bitmap comp(Bitmap image) { ByteArrayOutputStream out = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 100, out); if( out.toByteArray().length / 1024>1024) {//判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出 out.reset();//重置baos即清空baos image.compress(Bitmap.CompressFormat.JPEG, 50, out);//这里压缩50%,把压缩后的数据存放到baos中 } ByteArrayInputStream isBm = new ByteArrayInputStream(out.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; //现在主流手机比较多是800*480分辨率,所以高和宽我们设置为 float hh = 800f;//这里设置高度为800f float ww = 480f;//这里设置宽度为480f //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可 int be = 1;//be=1表示不缩放 if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放 be = (int) (newOpts.outWidth / ww); } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放 be = (int) (newOpts.outHeight / hh); } if (be <= 0) be = 1; newOpts.inSampleSize = be;//设置缩放比例 //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了 isBm = new ByteArrayInputStream(out.toByteArray()); bitmap = BitmapFactory.decodeStream(isBm, null, newOpts); return compressImage(bitmap);//压缩好比例大小后再进行质量压缩}
其实博客上有很多封装好的类,直接用起来就很好。
推荐:http://blog.csdn.net/jdsjlzx/article/details/44228935(一叶飘舟)大神
- android图片压缩方法
- android图片压缩方法
- android图片压缩
- android图片压缩
- Android图片压缩
- android图片压缩
- Android BitmapFactory 图片压缩
- android图片压缩
- android图片压缩总结
- android图片压缩一:
- Android 图片压缩二:
- Android图片压缩总结
- Android开发压缩图片
- Android图片压缩
- android 的图片压缩
- Android关于图片压缩
- android 图片压缩
- android图片压缩上传
- libiconv 交叉编译和调用方法(UTF-8和GB2312转换)
- 常用的linux命令
- 第二周项目1 - C/C++语言中函数参数传递的三种方式
- 每日小记(16.9.8)
- APP被苹果APPStore拒绝的各种原因
- Android 图片压缩
- maven+springmvc下载excle文件——ie8可用(二)
- 输入xxxx-xx-xx格式的日期可查询当日万年历
- 单点登录之CAS SSO从入门到精通(第一天)
- 推荐好听歌曲下载
- Javascript Flash Access-Control-Allow-Origin 跨域
- RecyclerView
- iOS开发:UITableView性能优化
- gcc编译参数:如何包含头文件和动态链接库