Android應用中怎么對圖片進行壓縮?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
創新互聯公司是一家專業提供烏爾禾企業網站建設,專注與網站建設、網站設計、html5、小程序制作等業務。10年已為烏爾禾眾多企業、政府機構等服務。創新互聯專業網絡公司優惠進行中。
為何要壓縮
1、體積的原因
如果你的圖片是要準備上傳的,那動輒幾M的大小肯定不行的,況且圖片分辨率大于設備分辨率的話毫無意義。
2、內存原因
如果圖片要顯示下Android設備上,ImageView最終是要加載Bitmap對象的,就要考慮單個Bitmap對象的內存占用了,如何計算一張圖片的加載到內存的占用呢?其實就是所有像素的內存占用總和:
bitmap內存大小 = 圖片長度 x 圖片寬度 x 單位像素占用的字節數
起決定因素就是最后那個參數了,Bitmap'常見有2種編碼方式:ARGB_8888和RGB_565,ARGB_8888每個像素點4個byte,RGB_565是2個byte,一般都采用ARGB_8888這種。那么常見的1080*1920的圖片內存占用就是:
1920 x 1080 x 4 = 7.9M
壓縮原理
從上面可以總結出,圖片壓縮應該從兩個方面入手同時進行:先是降低分辨率,然后降低每個像素的質量也就是內存占用。
分辨率壓縮
假設有張原圖是3840x2400,我想壓縮成1920x1080,實際是不可能100%能壓縮這個值的。因為圖片壓縮要保證寬高比,試想一下800x100的橫向圖可能壓成20x200豎向圖嗎? 不可能的.。這里常見的算法就是在1920x1080的范圍內保證較短邊,然后按照比例壓縮整個圖:
這里原圖的寬高比是 3840/2400 = 1.6,目標圖的寬高比是1920/1080 = 1.78>1.6,較短邊是高。所以就應該按照高的比例來壓縮。
2400/1080=2.22,這樣真實目標值就是:1728x1080,壓縮比四舍五入是:2,然后通過下面代碼進行壓縮:
private Bitmap compressPixel(String filePath){ Bitmap bmp = null; BitmapFactory.Options options = new BitmapFactory.Options(); //setting inSampleSize value allows to load a scaled down version of the original image options.inSampleSize = 2; //inJustDecodeBounds set to false to load the actual bitmap options.inJustDecodeBounds = false; options.inTempStorage = new byte[16 * 1024]; try { //load the bitmap from its path bmp = BitmapFactory.decodeFile(filePath, options); if (bmp == null) { InputStream inputStream = null; try { inputStream = new FileInputStream(filePath); BitmapFactory.decodeStream(inputStream, null, options); inputStream.close(); } catch (FileNotFoundException exception) { exception.printStackTrace(); } catch (IOException exception) { exception.printStackTrace(); } } } catch (OutOfMemoryError exception) { exception.printStackTrace(); }finally { return bmp; } }
看起來沒什么問題,看看實測結果,原圖 3840*2400,大小2.2M,我選4個分辨率當做目標值來壓縮:
可以看出壓縮后的4張圖沒有一張達到目標值,而且偏差較大,原因就是options.inSampleSize這個屬性,他只能是2的N次方,如果算出來是7,Android會取近似值8,以此類推導致這個值不能壓縮到目標值。看了一下Compressor這個開源庫他對此做了處理,把壓縮后的圖片在Canvas上面按照目標尺寸重繪,得到一個新的bitmap:
核心代碼:
Matrix scaleMatrix = new Matrix(); scaleMatrix.setScale(ratioX, ratioY, 0, 0); Canvas canvas = new Canvas(scaledBitmap); canvas.setMatrix(scaleMatrix); canvas.drawBitmap(bmp, 0, 0, new Paint(Paint.FILTER_BITMAP_FLAG));
用Compressor開源庫壓縮的圖片對比下:
可以看出每次都能壓縮到真實目標值。(注意不是目標值,注意區分目標值和真實目標值)
質量壓縮
Bitmap有個方法 compress(CompressFormat format, int quality, OutputStream stream),quality就是壓縮質量傳入0-100,數值越小壓縮的越厲害。
不過我們一般不直接設置這個數值,而是自定義一個壓縮后大小比如300KB,然后動態計算這個quality,核心代碼:
//進行有損壓縮 ByteArrayOutputStream baos = new ByteArrayOutputStream(); int options_ = 100; actualOutBitmap.compress(Bitmap.CompressFormat.JPEG, options_, baos); //質量壓縮方法,把壓縮后的數據存放到baos中 (100表示不壓縮,0表示壓縮到最小) int baosLength = baos.toByteArray().length; while (baosLength / 1024 > maxFileSize) { //循環判斷如果壓縮后圖片是否大于maxMemmorrySize,大于繼續壓縮 baos.reset(); //重置baos即讓下一次的寫入覆蓋之前的內容 options_ = Math.max(0, options_ - 10);//圖片質量每次減少10 actualOutBitmap.compress(Bitmap.CompressFormat.JPEG, options_, baos); //將壓縮后的圖片保存到baos中 baosLength = baos.toByteArray().length; if (options_ == 0)//如果圖片的質量已降到最低則,不再進行壓縮 break; }
看完上述內容,你們掌握Android應用中怎么對圖片進行壓縮的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注創新互聯行業資訊頻道,感謝各位的閱讀!
當前名稱:Android應用中怎么對圖片進行壓縮
文章出自:http://vcdvsql.cn/article36/gdecpg.html
成都網站建設公司_創新互聯,為您提供響應式網站、定制開發、ChatGPT、用戶體驗、品牌網站設計、網站策劃
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯