Android Bitmap压缩方式分析
AndroidBitmap压缩方式分析
在网上调查了图片压缩的方法并实装后,大致上可以认为有两类压缩:质量压缩(不改变图片的尺寸)和尺寸压缩(相当于是像素上的压缩);质量压缩一般可用于上传大图前的处理,这样就可以节省一定的流量,毕竟现在的手机拍照都能达到3M左右了,尺寸压缩一般可用于生成缩略图。
在Android开发中我们都会遇到在一个100*100的ImageView上显示一张过大的图片,如果直接把这张图片显示上去对我们应用没有一点好处反而存在OOM的危险,所以我们有必要采用一种有效压缩方式来显示上去。
privatevoidcalculateBitmapInSimpleSize(){ Bitmap_bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.bg_homepage); getBitmapDatas(_bitmap); BitmapFactory.Optionsoptioins=newBitmapFactory.Options(); optioins.inJustDecodeBounds=true; //optioins.inPreferredConfig=Bitmap.Config.RGB_565;//11158560 optioins.inPreferredConfig=Bitmap.Config.ARGB_8888;//22317120 BitmapFactory.decodeResource(getResources(),R.drawable.bg_homepage,optioins); intreqWidth=optioins.outWidth; intreqHeight=optioins.outHeight; Log.w(TAG,"reqWidth="+reqWidth); Log.w(TAG,"reqHeight="+reqHeight); intinSampleSize=1; finalintwidthRatio=Math.round((float)reqWidth/100f); finalintheigthRatio=Math.round((float)reqHeight/100f); //取最小值这将保证压缩出来的图片大于或者等于请求的宽度或者高度 inSampleSize=widthRatio>heigthRatio?heigthRatio:widthRatio; Log.w(TAG,"firstinSampleSize="+inSampleSize); finalinttotalPixel=100*100; finalinttotalReqPixel=reqWidth*reqHeight*2; Log.w(TAG,"totalReqPixel="+totalReqPixel); while(totalPixel/(inSampleSize*inSampleSize)>totalReqPixel){ Log.w(TAG,"totalPixel="+(totalPixel/(inSampleSize*inSampleSize))); inSampleSize++; } Log.w(TAG,"LastInSampleSize="+inSampleSize); optioins.inJustDecodeBounds=false; BitmaplastBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.bg_homepage,optioins); getBitmapDatas(lastBitmap); mImageView.setImageBitmap(lastBitmap); }
通过打印log我们可以清楚发现一张原始的图片占有22317120字节,经过压缩后11158560(RGB_565)/22317120(RGB8888)明显所占用的内存都减少了,尽量降低这种情况带来的OOM。
做法:
1.optioins.inJustDecodeBounds=true设置为true可用于读取该bitmap的宽高且不会占用内存。
2.optioins.inPreferredConfig=Bitmap.Config.RGB_565设置在内存中以占用最少的方式,相比RGB_8888只有其一半的内存占有。
3.finalintwidthRatio=Math.round((float)reqWidth/100f);
finalintheigthRatio=Math.round((float)reqHeight/100f);
inSampleSize=widthRatio>heigthRatio?heigthRatio:widthRatio;
计算压缩比例,取最小值这将保证压缩出来的图片大于或者等于请求的宽度或者高度。
4.在要显示到ImageView的时候optioins.inJustDecodeBounds=false设回false这样就能正常显示了
//计算bitmap所占内存值 publicvoidgetBitmapDatas(Bitmapbitmap){ Log.w(TAG,"Bitmapsize="+bitmap.getByteCount()); }
采用以上的压缩方式我们就能避免一张过大的图片”浪费”的显示在ImageView上造成内存消耗过大。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!