日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

android 图片压缩,bitmap压缩总结

發布時間:2023/12/14 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android 图片压缩,bitmap压缩总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.?? ?圖片壓縮相關概念

在android開發中,圖片加載到內存中通常需要占用大量的內存,導致app性能過度消耗,嚴重的話可能會導致OOM異常,所以對圖片進行優化就尤為重要。
android圖片壓縮的格式可以通過以下一張圖進行概括,這張圖摘自官方API文檔:
?
對于各個參數的含義,通過以下一張表格總結一下

ALPHA_8每個像素存儲為單個半透明(alpha)通道,占用1字節內存,用來存儲遮罩非常有用
ARGB_4444?每個像素占用2字節存儲空間,由于在這個配置下的圖片質量比較差,官方建議使用ARGB_8888,官方已提示ARGB_4444不推薦使用
ARGB_8888??每個像素占用4字節存儲空間,每個通道(A,R,G,B)都以8位精度進行存儲,這種格式下圖片質量最佳,官方推薦盡可能使用這種格式存儲
HARDWARE?? ?一種特殊的存儲格式,當位圖僅僅存儲在圖形內存中時,位圖始終保持不變
RGBA_F16? ?每個像素存儲在8個字節上,很少用
RGB_565??每個像素存儲在2個字節上,沒有透明度,只包括了紅,綠,藍三個通道,當使用不需要透明度圖片時,可以使用該格式存儲

android圖片加載到內存,bitmap所占內存的大小可以由下列公式進行計算:
bitmap所占內存 = 圖片分辨率 * 一個像素所占的字節數
上述公式其實是不嚴謹的,對于從SD卡,assests目錄或者網絡中加載圖片所占用的內存,是可以通過上述的公式計算出來的。但是如果圖片存儲在res目錄中,當圖片加載進內存時,會經過一次分辨率的轉換,然后在計算內存占用多少,這時圖片的分辨率應該是轉換之后的分辨率,而不是原圖的分辨率。
這里只討論常規圖片壓縮方式,圖片都是存儲在SD卡或者assests目錄中,對于存儲在res目錄下的情況忽略。
bitmap的壓縮方式主要有:
1.?? ?采樣率壓縮
2.?? ?縮放壓縮
3.?? ?質量壓縮
4.?? ?設置RGB_565
5.?? ?使用createScaledBitmap
下面簡單討論下各種壓縮方式

2.?采樣率壓縮

通過設置BitmapFactory.Options的inSampleSize參數,達到壓縮圖片的目的。該參數表示壓縮為原圖的幾分之一,必須大于1,小于1按照1處理。
下面通過加載原圖和設置inSampleSize來對比設置inSampleSize加載圖片之后的效果。
把一張原圖不經過壓縮直接加載到內存中:

Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/compresstest/test.png"); if(bitmap != null) {String info = "原始圖片大小: " + (bitmap.getByteCount()) + " 寬度: " + bitmap.getWidth() + " 高度: " + bitmap.getHeight();Log.v("sample", info);tvOrgin.setText(info);imgvOrgin.setImageBitmap(bitmap); }

設置inSampleSize參數,加載一張圖片到內存中:

BitmapFactory.Options options = new BitmapFactory.Options(); String str = edtvSample.getText().toString(); int sample = 2; try {sample = Integer.parseInt(str); } catch (Exception e) {Toast.makeText(this, "請輸入有效數字內容", Toast.LENGTH_SHORT).show();e.printStackTrace();return ; } options.inSampleSize = sample;Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/compresstest/test.png", options); if(bitmap != null) {String info = "壓縮圖片大小: " + (bitmap.getByteCount()) + " 寬度: " + bitmap.getWidth() + " 高度: " + bitmap.getHeight();Log.v("sample", info);tvCompress.setText(info);imgvCompress.setImageBitmap(bitmap); }

其中inSampleSize通過界面動態設置,以此來查看不同inSampleSize加載圖片的具體效果。
例如把inSampleSize設置成4,寬度和高度都變為了原來的1/4,圖片內存整整縮小為原來的1/16。
?
下面是我測試的一張效果:

3.?縮放壓縮

通過Martix變換,設置縮放值以此來達到圖片壓縮的目的。

Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/compresstest/test.png"); String strx = edtvSx.getText().toString(); String stry = edtvSy.getText().toString();float sx = 0.5f; float sy = 0.5f; try {sx = Float.parseFloat(strx);sy = Float.parseFloat(stry); } catch (Exception e) {Toast.makeText(this, "請輸入有效數字內容", Toast.LENGTH_SHORT).show();e.printStackTrace();return ; } if(bitmap != null) {Matrix matrix = new Matrix();matrix.setScale(sx, sy);Bitmap newBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);String info = " sx: " + sx + " sy: " + sy + " 壓縮圖片大小: " + (newBitmap.getByteCount()) + " 寬度為: " + newBitmap.getWidth() + " 高度為: " + newBitmap.getHeight();Log.v("martix", info);tvCompress.setText(info);imgvCompress.setImageBitmap(newBitmap); }

把x,y縮放值分別設置成0.5f,可以看到壓縮后的圖片寬,高都是原圖寬高的1/2,圖片整體大小是原圖的1/4.
?
效果圖:

4.?質量壓縮

質量壓縮并不會減少bitmap占用的內存,bitmap的分辨率會和原圖保持一致。質量壓縮的原理是通過算法扣掉(同化)了 圖片中的一些某個點附近相近的像素,以此介紹圖片中的顏色數量,達到減少文件大小的目的。
質量壓縮測試代碼:

? ? ? ? Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/compresstest/test.png");ByteArrayOutputStream baos = new ByteArrayOutputStream();String str = edtvQuality.getText().toString();int quality = 100;try {quality = Integer.parseInt(str);} catch (Exception e) {Toast.makeText(this, "請輸入有效數字內容", Toast.LENGTH_SHORT).show();e.printStackTrace();return ;}if(bitmap != null) { // ? ? ? ? ? ?bitmap.compress(Bitmap.CompressFormat.PNG, quality, baos); // 設置Bitmap.CompressFormat.PNG,quality將不起作用,PNG是無損壓縮bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);byte[] bytes = baos.toByteArray();Bitmap newBitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);String info = " quality: " + quality + " 壓縮圖片大小: " + (newBitmap.getByteCount()) + " 壓縮后文件大小: " + (bytes.length) + " 寬度為: " + newBitmap.getWidth() + " 高度為: " + newBitmap.getHeight();Log.v("quality", info);tvCompress.setText(info);imgvCompress.setImageBitmap(newBitmap);} 關鍵代

碼是:

bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);

其中quality是壓縮質量,100表示保持最佳質量壓縮效果,值越小表示壓縮效果越差。
如果上述方法的CompressFormat參數設置成Bitmap.CompressFormat.PNG,那么后面的quality參數將會失效,無論怎樣改變quality的值,壓縮后的文件都不會改變這是因為PNG是無損壓縮。
把quality設置成5,可以看下壓縮效果:
?
效果圖:
?

5.?設置RGB_565

設置RGB_565相比ARGB_8888減少了一半內存,這是因為RGB_565每個像素是2個字節存儲的,但是bitmap的寬和高并不會改變。

BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = config; Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/compresstest/test.png", options); if(bitmap != null) {String info = " 壓縮圖片大小: " + (bitmap.getByteCount()) + " 寬度為: " + bitmap.getWidth() + " 高度為: " + bitmap.getHeight();Log.v("rgb", info);tvCompress.setText(info);imgvCompress.setImageBitmap(bitmap); }

以下是使用RGB_565壓縮的輸出:

?效果圖:

6.?使用createScaledBitmap

使用createScaledBitmap()方法可以把圖片壓縮成用戶期望任意尺寸的圖片,如果期望尺寸和圖片相差太大,會導致圖片失真。

Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/compresstest/test.png"); String strx = edtvWidth.getText().toString(); String stry = edtvHeight.getText().toString();int width = 200; int height = 200; try {width = Integer.parseInt(strx);height = Integer.parseInt(stry); } catch (Exception e) {Toast.makeText(this, "請輸入有效數字內容", Toast.LENGTH_SHORT).show();e.printStackTrace();return ; } if(bitmap != null) {Bitmap newBitmap = Bitmap.createScaledBitmap(bitmap, width, height, true);String info = " width: " + width + " height: " + height + " 壓縮圖片大小: " + (newBitmap.getByteCount()) + " 寬度為: " + newBitmap.getWidth() + " 高度為: " + newBitmap.getHeight();Log.v("scale", info);tvCompress.setText(info);imgvCompress.setImageBitmap(newBitmap); }

把寬高設置成200之后的效果:
?
?
可以看到,如果不按比例進行縮放設置,圖片是會拉伸,失真的。

本文的源碼比較簡單,就不上傳了,需要的留下郵箱私發。


?

總結

以上是生活随笔為你收集整理的android 图片压缩,bitmap压缩总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。