您好,登錄后才能下訂單哦!
本篇內容主要講解“Android開發怎么實現圖片大小與質量壓縮及保存”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Android開發怎么實現圖片大小與質量壓縮及保存”吧!
ALPHA_8:每個像素占用1byte內存
ARGB_4444:每個像素占用2byte內存
ARGB_8888:每個像素占用4byte內存 (默認)
RGB_565:每個像素占用2byte內存
Android默認的顏色模式為ARGB_8888,這個顏色模式色彩最細膩,顯示質量最高。但同樣的,占用的內存也最大。所以在對圖片效果不是特別高的情況下使用RGB_565(565沒有透明度屬性)
有png,jpeg和webp
png:無損壓縮圖片格式,支持Alpha通道,Android切圖素材多采用該格式
jpeg:有損壓縮圖片格式,不支持背景透明,適用于照片等色彩豐富的(大圖壓縮,不適合logo)
webp:是一種同時提供了有損壓縮和無損壓縮的圖片格式,派生自視頻編碼格式VP8,從谷歌官網來看,無損webp平均比png小26%,有損的webp平均比jpeg小25%~34%,無損webp支持Alpha通道,有損webp在一定的條件下同樣支持,有損webp在Android4.0(API 14)之后支持,無損和透明在Android4.3(API18)之后支持
private Bitmap getimage(String srcPath) { BitmapFactory.Options newOpts = new BitmapFactory.Options(); //開始讀入圖片,此時把options.inJustDecodeBounds 設回true了 newOpts.inJustDecodeBounds = true; Bitmap bitmap = BitmapFactory.decodeFile(srcPath,newOpts);//此時返回bm為空 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了 bitmap = BitmapFactory.decodeFile(srcPath, newOpts); return compressImage(bitmap);//壓縮好比例大小后再進行質量壓縮 }
注意:
第二次壓縮之前都要先清空 baos.reset(); 再進行壓縮
image.compress(Bitmap.CompressFormat.JPEG, quality, baos);
有時候我們采用質量壓縮沒有效果,有可能是每次壓縮的質量過小,所以我們可以嘗試修改壓縮質量(quality)是10;
quality壓縮機提示,0-100。0表示壓縮小尺寸,100意味著最大質量的壓縮。一些格式,如無損的PNG,將忽略質量設定;
private Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 100, baos); int options = 90; int length = baos.toByteArray().length / 1024; if (length>5000){ //重置baos即清空baos baos.reset(); //質量壓縮方法,這里100表示不壓縮,把壓縮后的數據存放到baos中 image.compress(Bitmap.CompressFormat.JPEG, 10, baos); }else if (length>4000){ baos.reset(); image.compress(Bitmap.CompressFormat.JPEG, 20, baos); }else if (length>3000){ baos.reset(); image.compress(Bitmap.CompressFormat.JPEG, 50, baos); }else if (length>2000){ baos.reset(); image.compress(Bitmap.CompressFormat.JPEG, 70, baos); } //循環判斷如果壓縮后圖片是否大于1M,大于繼續壓縮 while (baos.toByteArray().length / 1024>1024) { //重置baos即清空baos baos.reset(); //這里壓縮options%,把壓縮后的數據存放到baos中 image.compress(Bitmap.CompressFormat.JPEG, options, baos); //每次都減少10 options -= 10; } //把壓縮后的數據baos存放到ByteArrayInputStream中 ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray()); //把ByteArrayInputStream數據生成圖片 Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null); return bitmap; }
private Bitmap comp(Bitmap image) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 100, baos); if( baos.toByteArray().length / 1024>1024) {//判斷如果圖片大于1M,進行壓縮避免在生成圖片(BitmapFactory.decodeStream)時溢出 baos.reset();//重置baos即清空baos image.compress(Bitmap.CompressFormat.JPEG, 50, baos);//這里壓縮50%,把壓縮后的數據存放到baos中 } ByteArrayInputStream isBm = new ByteArrayInputStream(baos.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(baos.toByteArray()); bitmap = BitmapFactory.decodeStream(isBm, null, newOpts); return compressImage(bitmap);//壓縮好比例大小后再進行質量壓縮 }
采樣率壓縮是通過設置BitmapFactory.Options.inSampleSize,來減小圖片的分辨率,進而減小圖片所占用的磁盤空間和內存大小。
設置的inSampleSize會導致壓縮的圖片的寬高都為1/inSampleSize,整體大小變為原始圖片的inSampleSize平方分之一,當然,這些有些注意點:
1、inSampleSize小于等于1會按照1處理
2、inSampleSize只能設置為2的平方,不是2的平方則最終會減小到最近的2的平方數,如設置7會按4進行壓縮,設置15會按8進行壓縮。
/** * * @param inSampleSize 可以根據需求計算出合理的inSampleSize */ public static void compress(int inSampleSize) { File sdFile = Environment.getExternalStorageDirectory(); File originFile = new File(sdFile, "originImg.jpg"); BitmapFactory.Options options = new BitmapFactory.Options(); //設置此參數是僅僅讀取圖片的寬高到options中,不會將整張圖片讀到內存中,防止oom options.inJustDecodeBounds = true; Bitmap emptyBitmap = BitmapFactory.decodeFile(originFile.getAbsolutePath(), options); options.inJustDecodeBounds = false; options.inSampleSize = inSampleSize; Bitmap resultBitmap = BitmapFactory.decodeFile(originFile.getAbsolutePath(), options); ByteArrayOutputStream bos = new ByteArrayOutputStream(); resultBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos); try { FileOutputStream fos = new FileOutputStream(new File(sdFile, "resultImg.jpg")); fos.write(bos.toByteArray()); fos.flush(); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
/** * 保存bitmap到本地 * @param context the context * @param mBitmap the m bitmap * @return string */ public static String saveBitmap(Context context, Bitmap mBitmap) { String savePath; File filePic; try { if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { savePath = SD_PATH; } else { savePath = context.getApplicationContext().getFilesDir().getAbsolutePath() + IN_PATH; } filePic = new File(savePath + DateTimeHelper.format(new Date(), "yyyyMMddHHmmss") + ".jpg"); Log.d("LUO", "圖片地址====" + filePic); if (!filePic.exists()) { filePic.getParentFile().mkdirs(); filePic.createNewFile(); } FileOutputStream fos = new FileOutputStream(filePic); //不壓縮,保存本地 mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); fos.flush(); fos.close(); } catch (IOException e) { e.printStackTrace(); return null; } return filePic.getAbsolutePath(); }
到此,相信大家對“Android開發怎么實現圖片大小與質量壓縮及保存”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。