浅谈图片压缩方式

2 篇文章 0 订阅

浅谈图片压缩方式


刚毕业开始工作,在项目开发中,一个很棘手的问题就是图片的压缩,上传速度太慢!所以现在闲下来有时间就想学习一下这方面的知识……参考网上的一些大神分享的干粮,如果有错的地方请大神毫不犹豫的指出!哈哈


压缩格式:

  • ALPHA_8
    表示8位Alpha位图,即A=8,一个像素点占用1个字节,它没有颜色,只有透明度
  • ARGB_4444
    表示16位ARGB位图,即A=4,R=4,G=4,B=4,一个像素点占4+4+4+4=16位,2个字节
  • ARGB_8888
    表示32位ARGB位图,即A=8,R=8,G=8,B=8,一个像素点占8+8+8+8=32位,4个字节,系统默认是这个
  • RGB_565
    表示16位RGB位图,即R=5,G=6,B=5,它没有透明度,一个像素点占5+6+5=16位,2个字节

获取图片所占内存

public static int getBitmapSize(Bitmap bitmap) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {//API 19
        return bitmap.getAllocationByteCount();
    }else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {//API 12
        return bitmap.getByteCount();
    }
    //在低版本中用一行的字节x高度
    return bitmap.getRowBytes() * bitmap.getHeight();
}

SampleSize取样压缩(分辨率压缩、体积压缩)

private Bitmap compressBitmap(String path,int width,int height){
    BitmapFactory.Options options=new BitmapFactory.Options();
    options.inJustDecodeBounds=true;
    BitmapFactory.decodeFile(path,options);
    options.inSampleSize=caculateInSampleSize(options,width,height);
    options.inJustDecodeBounds=false;
    Bitmap bitmap=BitmapFactory.decodeFile(path,options);
    Log.e("BitmapSize","压缩后:"+getBitmapSize(bitmap)/1024);
    return bitmap;
}
/**
 * 获取压缩比
 */
private int caculateInSampleSize(BitmapFactory.Options options,int width,int height){
    int outWidth=options.outWidth;
    int outHeight=options.outHeight;
    int InSampleSize=1;
    if(outWidth>width || outHeight>height){
        int maxWidth=Math.round(outWidth*1.0f/width);
        int maxHeight=Math.round(outHeight*1.0f/height);
        InSampleSize=Math.max(maxHeight,maxWidth);
    }

    return InSampleSize;
}

质量压缩

private Bitmap compressBtye(Bitmap bitmap,int maxFileSize){
    ByteArrayOutputStream out=new ByteArrayOutputStream();
    int options=100;
    //质量压缩方法,把压缩后的数据存放到out中 (100表示不压缩,0表示压缩到最小)
    //以jpeg格式压缩后, 原来图片中透明的元素将消失,图片很可能会失真
    bitmap.compress(Bitmap.CompressFormat.JPEG,options,out);
    //获取大小
    int outSize=out.toByteArray().length;
    while (outSize/1024 > maxFileSize){
        out.reset();//重置out即让下一次的写入覆盖之前的内容
        options=Math.max(30,options-10);//30为个人预设最小压缩比(30以下会失真)
        bitmap.compress(Bitmap.CompressFormat.JPEG,options,out);
        outSize=out.toByteArray().length;
        if(options==30)
            break;
    }
    ByteArrayInputStream in=new ByteArrayInputStream(out.toByteArray());
    bitmap=BitmapFactory.decodeStream(in);
    Log.e("BtyeBitmap","100质量压缩后:"+getBitmapSize(bitmap)/1024);
    return bitmap;
}

方法说明: 该方法是压缩图片的质量, 注意它不会减少图片的像素;bitmap.getByteCount()是计算它的像素所占用的内存。所以当你想把体积压缩后得到的bitmap直接进行质量压缩是无效的,内存大小并不会变化。亲测,如图:我原图大小为3888k,进过体积压缩后为60k,然而质量压缩前得到outSize的值为11k,maxFileSize设为10,压缩比为90,得到的bimap内存大小还是60。所以out.toByteArray().length得到的值和getByteCount()得到的值是不同的!图片质量压缩改变了图片的显示质量, 达到了对File形式的图片进行压缩, 图片的像素没有改变的话, 那重新读取经过压缩的file为Bitmap时, 它占用的内存并不会少!

Matrix压缩法(体积压缩、矩阵压缩)

private Bitmap MatrixBitmap(String path,int width,int height){
    Bitmap bitmap=BitmapFactory.decodeFile(path);
    int outWidth=bitmap.getWidth();
    int outHeight=bitmap.getHeight();
    //缩放比
    float reWidth=width*1.0f/outWidth;
    float reHeight=height*1.0f/outHeight;
    float max=Math.max(reWidth,reHeight);
    Log.e("BitmapSize","压缩max:"+max);
    Matrix matrix=new Matrix();
    matrix.postScale(max,max);

    Bitmap bm=Bitmap.createBitmap(bitmap,0,0,outWidth,outHeight,matrix,true);
    if(!bitmap.isRecycled()){//Android2.3以后系统不建议手动调用,系统会自动GC
        bitmap.recycle();
    }
    Log.e("BitmapSize","Matrix压缩后:"+getBitmapSize(bm)/1024);
    return bm;
}

如图,Matrix压缩与SampleSize压缩方式效果差别不大。但因为SampleSize压缩比InSampleSize的值必须是2的次方,而Matrix压缩的压缩比可以使float型,所以个人感觉Matrix压缩稍微好一些。

小总结:
体积压缩和质量压缩都会减少file流的大小,有利于快速上传!但只有体积压缩(分辨率压缩)才会减少图片所占内存的大小!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值