android 如何實(shí)現(xiàn)比較靠譜的圖片壓縮
追加:按照寬高壓縮
????????@SuppressLint("NewApi") public?static?Bitmap?getSmallBitmap(String?file_path)?{ Bitmap?image?=?null; try?{ BitmapFactory.Options?opt?=?new?BitmapFactory.Options();?? opt.inPreferredConfig?=?Bitmap.Config.RGB_565;??? opt.inPurgeable?=?true;?? opt.inInputShareable?=?true;?? opt.inSampleSize?=?2; //獲取資源圖片?? FileInputStream?is?=?new?FileInputStream(new?File(file_path)); image?=?BitmapFactory.decodeStream(is,?null,?opt); if(image.getHeight()>800?||?image.getWidth()>800){//這里判斷?寬高比例?大于?800 int?width?=?image.getWidth(); int?height?=?image.getHeight(); int?tmp?=??800; // int?newHeigth?=?800; float?scale?=?1; int?tmp2?=?width>height??width:height; if(tmp2>tmp){ scale?=?(float)tmp/(float)tmp2; } LogsUtil.log_error(ImageUtil.class,"tmp2"+tmp2+?"tmp"+tmp+"---s"+scale); Matrix?matrix?=?new?Matrix(); matrix.postScale(scale,scale); Bitmap?bitmap?=?Bitmap.createBitmap(image,0,0,?width,?height,?matrix,?true); LogsUtil.log_error(ImageUtil.class,?bitmap.getByteCount()+"");//1920000 if(bitmap.getByteCount()>1024*1024*5){//?判斷?如果?大于500kb?進(jìn)行質(zhì)量壓縮 return?compressImage(bitmap);//壓縮好比例大小后再進(jìn)行質(zhì)量壓縮 } return?bitmap; } }?catch?(FileNotFoundException?e)?{ //?TODO?Auto-generated?catch?block e.printStackTrace(); } return?image; }
第一:我們先看下質(zhì)量壓縮方法:
?
private?Bitmap?compressImage(Bitmap?image)?{?? ?? ????????ByteArrayOutputStream?baos?=?new?ByteArrayOutputStream();?? ????????image.compress(Bitmap.CompressFormat.JPEG,?100,?baos);//質(zhì)量壓縮方法,這里100表示不壓縮,把壓縮后的數(shù)據(jù)存放到baos中?? ????????int?options?=?100;?? ????????while?(?baos.toByteArray().length?/?1024>100)?{??//循環(huán)判斷如果壓縮后圖片是否大于100kb,大于繼續(xù)壓縮????????? ????????????baos.reset();//重置baos即清空baos?? ????????????image.compress(Bitmap.CompressFormat.JPEG,?options,?baos);//這里壓縮options%,把壓縮后的數(shù)據(jù)存放到baos中?? ????????????options?-=?10;//每次都減少10?? ????????}?? ????????ByteArrayInputStream?isBm?=?new?ByteArrayInputStream(baos.toByteArray());//把壓縮后的數(shù)據(jù)baos存放到ByteArrayInputStream中?? ????????Bitmap?bitmap?=?BitmapFactory.decodeStream(isBm,?null,?null);//把ByteArrayInputStream數(shù)據(jù)生成圖片?? ????????return?bitmap;?? ????}?? ?
第二:圖片按比例大小壓縮方法(根據(jù)路徑獲取圖片并壓縮):
?
private?Bitmap?getimage(String?srcPath)?{?? ????????BitmapFactory.Options?newOpts?=?new?BitmapFactory.Options();?? ????????//開(kāi)始讀入圖片,此時(shí)把options.inJustDecodeBounds?設(shè)回true了?? ????????newOpts.inJustDecodeBounds?=?true;?? ????????Bitmap?bitmap?=?BitmapFactory.decodeFile(srcPath,newOpts);//此時(shí)返回bm為空?? ?????????? ????????newOpts.inJustDecodeBounds?=?false;?? ????????int?w?=?newOpts.outWidth;?? ????????int?h?=?newOpts.outHeight;?? ????????//現(xiàn)在主流手機(jī)比較多是800*480分辨率,所以高和寬我們?cè)O(shè)置為?? ????????float?hh?=?800f;//這里設(shè)置高度為800f?? ????????float?ww?=?480f;//這里設(shè)置寬度為480f?? ????????//縮放比。由于是固定比例縮放,只用高或者寬其中一個(gè)數(shù)據(jù)進(jìn)行計(jì)算即可?? ????????int?be?=?1;//be=1表示不縮放?? ????????if?(w?>?h?&&?w?>?ww)?{//如果寬度大的話根據(jù)寬度固定大小縮放?? ????????????be?=?(int)?(newOpts.outWidth?/?ww);?? ????????}?else?if?(w?<?h?&&?h?>?hh)?{//如果高度高的話根據(jù)寬度固定大小縮放?? ????????????be?=?(int)?(newOpts.outHeight?/?hh);?? ????????}?? ????????if?(be?<=?0)?? ????????????be?=?1;?? ????????newOpts.inSampleSize?=?be;//設(shè)置縮放比例?? ????????//重新讀入圖片,注意此時(shí)已經(jīng)把options.inJustDecodeBounds?設(shè)回false了?? ????????bitmap?=?BitmapFactory.decodeFile(srcPath,?newOpts);?? ????????return?compressImage(bitmap);//壓縮好比例大小后再進(jìn)行質(zhì)量壓縮?? ????}?? ?
第三:圖片按比例大小壓縮方法(根據(jù)Bitmap圖片壓縮):
?
private?Bitmap?comp(Bitmap?image)?{??
??????
????ByteArrayOutputStream?baos?=?new?ByteArrayOutputStream();?????????
????image.compress(Bitmap.CompressFormat.JPEG,?100,?baos);??
????if(?baos.toByteArray().length?/?1024>1024)?{//判斷如果圖片大于1M,進(jìn)行壓縮避免在生成圖片(BitmapFactory.decodeStream)時(shí)溢出????
????????baos.reset();//重置baos即清空baos??
????????image.compress(Bitmap.CompressFormat.JPEG,?50,?baos);//這里壓縮50%,把壓縮后的數(shù)據(jù)存放到baos中??
????}??
????ByteArrayInputStream?isBm?=?new?ByteArrayInputStream(baos.toByteArray());??
????BitmapFactory.Options?newOpts?=?new?BitmapFactory.Options();??
????//開(kāi)始讀入圖片,此時(shí)把options.inJustDecodeBounds?設(shè)回true了??
????newOpts.inJustDecodeBounds?=?true;??
????Bitmap?bitmap?=?BitmapFactory.decodeStream(isBm,?null,?newOpts);??
????newOpts.inJustDecodeBounds?=?false;??
????int?w?=?newOpts.outWidth;??
????int?h?=?newOpts.outHeight;??
????//現(xiàn)在主流手機(jī)比較多是800*480分辨率,所以高和寬我們?cè)O(shè)置為??
????float?hh?=?800f;//這里設(shè)置高度為800f??
????float?ww?=?480f;//這里設(shè)置寬度為480f??
????//縮放比。由于是固定比例縮放,只用高或者寬其中一個(gè)數(shù)據(jù)進(jìn)行計(jì)算即可??
????int?be?=?1;//be=1表示不縮放??
????if?(w?>?h?&&?w?>?ww)?{//如果寬度大的話根據(jù)寬度固定大小縮放??
????????be?=?(int)?(newOpts.outWidth?/?ww);??
????}?else?if?(w?<?h?&&?h?>?hh)?{//如果高度高的話根據(jù)寬度固定大小縮放??
????????be?=?(int)?(newOpts.outHeight?/?hh);??
????}??
????if?(be?<=?0)??
????????be?=?1;??
????newOpts.inSampleSize?=?be;//設(shè)置縮放比例??
????//重新讀入圖片,注意此時(shí)已經(jīng)把options.inJustDecodeBounds?設(shè)回false了??
????isBm?=?new?ByteArrayInputStream(baos.toByteArray());??
????bitmap?=?BitmapFactory.decodeStream(isBm,?null,?newOpts);??
????return?compressImage(bitmap);//壓縮好比例大小后再進(jìn)行質(zhì)量壓縮??
}?