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(一叶飘舟)大神
















































































0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 维修车辆被拍违章停车怎么办 网贷申请平台太多怎么办 所在城市没有网店怎么办信用卡 拍拍贷不放款了怎么办 拍拍贷账号注销了怎么办 我在拍拍贷注销了怎么办 快贷逾期一年了怎么办 广州车牌买新车旧车怎么办 高尔夫旅行款被锁在车内怎么办 英雄联盟误删文件怎么办 拍拍贷换了号码怎么办 手机打开显示无法连接服务器怎么办 剑灵画面卡顿怎么办 cf被永久禁赛了怎么办 微信没有微游戏商店怎么办 游侠云盒下载慢怎么办2018 安卓手机玩网页游戏卡怎么办 safari点开什么都没有怎么办 康佳电视全网搜索打不开怎么办 脚被图钉扎了怎么办 电脑中毒了打不开软件怎么办 剑三程序不兼容怎么办 玩无主之地卡怎么办 平台老板跑路了怎么办 qq在苹果下载不了怎么办 下载速度快上传速度慢怎么办 苹果7开网页慢怎么办 为什么浏览器下载视频速度慢怎么办 机连WLAN网速慢怎么办 会声会影卸载后无法重新安装怎么办 电视空间不足无法卸载怎么办 堡垒之夜下载慢怎么办 手机网盘下载速度慢怎么办插件 笔记本电脑显示连接不可用怎么办 蓝魔手机充电慢怎么办 360f4手机充电慢怎么办 vivo卡了怎么办小窍门 白色衣服用84泡后变黄怎么办 用祛斑霜脱皮了怎么办 用祛斑霜脸一直蜕皮怎么办 吃热的就流鼻涕怎么办