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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android BitMap图片压缩

發(fā)布時(shí)間:2023/12/14 Android 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android BitMap图片压缩 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

? ? ? ? ?最近在網(wǎng)上看了一些關(guān)于圖片壓縮的博客,自己也動(dòng)手實(shí)驗(yàn)了一遍,也算事對圖片壓縮有了一個(gè)了解,打算寫個(gè)博客記錄一下。文末附上參考鏈接。

? ? ? ? ?Android中涉及到圖片的話一般都會(huì)用到BitMap類和BitmapFactory類。而本文講述的圖片壓縮也都是通過這兩個(gè)類來實(shí)現(xiàn)的。Android中,圖片占用內(nèi)存大小計(jì)算公式:圖片寬度 * 圖片高度 * 圖片每一個(gè)像素占用的字節(jié)數(shù)。所以圖片占用內(nèi)存的大小(或者說壓縮),就是通過改變這三個(gè)值來改變的。

? ? ? ? ?1、質(zhì)量壓縮

? ? ? ? ? ? ? 這種方法,它是通過改變圖片的位深和透明度來實(shí)現(xiàn)圖片壓縮的。它不會(huì)改變圖片的大小,也不會(huì)改變圖片占用的內(nèi)存空間。它改變的是圖片對應(yīng)的BitMap對象的length屬性值。下面是實(shí)現(xiàn)代碼:

private Bitmap compressQuality(Bitmap bitmap){ByteArrayOutputStream bos = new ByteArrayOutputStream();bitmap.compress(Bitmap.CompressFormat.JPEG,100,bos);byte bytes[] = bos.toByteArray();Log.d(TAG, "compressQuality: length = "+bytes.length);return BitmapFactory.decodeByteArray(bytes,0,bytes.length);}

? ? ? ? 上述代碼重點(diǎn)是compress方法的使用,下面是它的API的形式。

//按指定的圖片格式以及畫質(zhì),將圖片轉(zhuǎn)換為輸出流。 public boolean compress(CompressFormat format, int quality, OutputStream stream)

? ? ? ? 這個(gè)方法接收一個(gè)圖片格式參數(shù)(format),畫質(zhì)參數(shù)(quality)還有一個(gè)輸出流(stream)。圖片格式參數(shù)有JPEG、PNG和WEBP,畫質(zhì)參數(shù)是[0,100]區(qū)間。使用這個(gè)方法壓縮圖片的時(shí)候,我們主要是想把圖片對應(yīng)的BitMap對象的length屬性變小,以應(yīng)對一些對圖片大小有限制的情況。而這里就需要注意,當(dāng)圖片格式參數(shù)為Bitmap.CompressFormat.PNG的時(shí)候,是無法改變這個(gè)length屬性值的,因?yàn)镻NG格式是無損的。畫質(zhì)參數(shù)為100的時(shí)候,length屬性值也不變,表示不壓縮。

? ? ? ? ?對于上面代碼,還可以學(xué)習(xí)到的知識(shí)點(diǎn)是:BitMap轉(zhuǎn)換成字節(jié)數(shù)組(使用ByteArrayOutputStream類)及字節(jié)數(shù)組轉(zhuǎn)換成BitMap(使用decodeByteArray方法)

? ? ? ?2、采樣率壓縮

? ? ? ? ? ?這種方法是通過改變BitmapFactory.Options的inSampleSize屬性值來改變圖片的大小的。通過它的代碼注釋可以知道,它是用來記錄圖片壓縮倍數(shù)的,如果它的值是4,那么它的寬高最后都變成原來的1/4,根據(jù)前面圖片占用內(nèi)存大小公式,最終它占用內(nèi)存大小就變成原來的1/16。這里我設(shè)置它的值為2,則最后占用內(nèi)存大小為原來的1/4。

private Bitmap compressSampling(){BitmapFactory.Options options = new BitmapFactory.Options();options.inSampleSize = 2;return BitmapFactory.decodeResource(getResources(),R.mipmap.fengjing,options);}/*** If set to a value > 1, requests the decoder to subsample the original* image, returning a smaller image to save memory. The sample size is* the number of pixels in either dimension that correspond to a single* pixel in the decoded bitmap. For example, inSampleSize == 4 returns* an image that is 1/4 the width/height of the original, and 1/16 the* number of pixels. Any value <= 1 is treated the same as 1. Note: the* decoder uses a final value based on powers of 2, any other value will* be rounded down to the nearest power of 2.*/public int inSampleSize;

? ? 3、縮放法壓縮

? ? ? ? 這種方法通過給給定一個(gè)矩陣來對圖片進(jìn)行壓縮,通過查看createBitMap的源碼發(fā)現(xiàn),最終也是改變圖片的寬高實(shí)現(xiàn)的。

private Bitmap compressMatrix(Bitmap bitmap){Matrix matrix = new Matrix();matrix.setScale(0.5f,0.5f);return Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);}public static Bitmap createBitmap(@NonNull Bitmap source, int x, int y, int width, int height,@Nullable Matrix m, boolean filter) {//...if (m == null || m.isIdentity()) {bitmap = createBitmap(neww, newh, newConfig, source.hasAlpha());paint = null; // not needed} else {final boolean transformed = !m.rectStaysRect();m.mapRect(deviceR, dstR);neww = Math.round(deviceR.width());newh = Math.round(deviceR.height());//...bitmap = createBitmap(neww, newh, transformedConfig, transformed || source.hasAlpha());//...}return bitmap;}

? ? ?4、RGB_565格式壓縮

? ? ? ? ? ?前面說到,圖片占用內(nèi)存大小公式是:圖片寬度 * 圖片高度 * 圖片每一個(gè)像素占用的字節(jié)數(shù)。而上面的兩種方法都是通過改變圖片的寬高來實(shí)現(xiàn)壓縮的,接著講解的這種方法就是通過改變圖片每一個(gè)像素占用的字節(jié)數(shù)來改變圖片占用內(nèi)存空間。

? ? ? ? ? 先來了解一下,圖片常用的壓縮格式:

ALPHA_8一個(gè)像素點(diǎn)占用1個(gè)字節(jié),它沒有顏色,只有透明度
ARGB_4444一個(gè)像素點(diǎn)占用2個(gè)字節(jié)
ARGB_8888一個(gè)像素點(diǎn)占用4個(gè)字節(jié)
RGB_565一個(gè)像素點(diǎn)占用2個(gè)字節(jié),它沒有透明度

代碼如下:

private Bitmap compressRGB565(){BitmapFactory.Options options = new BitmapFactory.Options();options.inPreferredConfig = Bitmap.Config.ALPHA_8;Log.d(TAG, "compressRGB565: "+options.inSampleSize);Log.d(TAG, "compressRGB565: "+options.inPreferredConfig);Log.d(TAG, "compressRGB565: "+options.inDensity);Log.d(TAG, "compressRGB565: "+options.outWidth);Log.d(TAG, "compressRGB565: "+options.outHeight);Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.fengjing,options);Log.d(TAG, "compressRGB565: -----------------");Log.d(TAG, "compressRGB565: "+options.inSampleSize);Log.d(TAG, "compressRGB565: "+options.inPreferredConfig);Log.d(TAG, "compressRGB565: "+options.inDensity);Log.d(TAG, "compressRGB565: "+options.outWidth);Log.d(TAG, "compressRGB565: "+options.outHeight);return bitmap;}

? ? ? ? 實(shí)現(xiàn)這種方式的方法是通過更改BitmapFactory.Options的inPreferredConfig值。默認(rèn)情況下,Android使用ARGB_8888格式。實(shí)驗(yàn)中,除了ARGB_4444格式,看到的現(xiàn)象是一個(gè)黑色的圖片區(qū)域,沒有顯示外,其他格式圖片正常顯示,內(nèi)存大小以ARGB_8888格式為準(zhǔn)的話,其他格式都縮小相應(yīng)倍數(shù)。

? ? ? ? 注意:由于ARGB_4444的畫質(zhì)慘不忍睹,一般假如對圖片沒有透明度要求的話,可以改成RGB_565,相比ARGB_8888將節(jié)省一半的內(nèi)存開銷。

? ? ? ?上面的代碼我加了一些日志打印,主要是為了驗(yàn)證,執(zhí)行完BitmapFactory.decodeResource方法之后,會(huì)對options的一些屬性進(jìn)行賦值,所以在某些情況下,會(huì)使用這種方式來獲取圖片的options信息。

? ? ? ?5、使用createScaleBitMap壓縮

private Bitmap compressScaleBitMap(Bitmap bitmap){int w = bitmap.getWidth();int h = bitmap.getHeight();return Bitmap.createScaledBitmap(bitmap, (int) (w*0.8), (int) (h*0.7),true);}

? ? ? ? ? ? ?這種方法通過給定期望的圖片寬高來進(jìn)行圖片的壓縮。注意圖片大小改動(dòng)太大會(huì)導(dǎo)致圖片的畫質(zhì)變得很差。

?

? ? ? 總結(jié)

? ? ? ? ? ?第一種方法,質(zhì)量壓縮。不改變圖片的大小,不改變內(nèi)存占用空間。但會(huì)改變圖片對于的Bitmap對象的字節(jié)length值。

? ? ? ? ? ?第二種方法,采樣率壓縮。通過改變圖片的寬高來改變圖片大小及占用的內(nèi)存空間。使用BitmapFactory類來實(shí)現(xiàn)。

? ? ? ? ? ?第三種方法,縮放法壓縮。通過給定一個(gè)具體的矩陣來改變圖片大小及占用的內(nèi)存空間。使用BitMap類實(shí)現(xiàn)。

? ? ? ? ? ?第四種方法,RGB_565格式壓縮。通過改變圖片每一個(gè)像素占用的字節(jié)數(shù)來改變圖片大小及占用內(nèi)存空間。

? ? ? ? ? ?第五種方法,createScaleBitMap壓縮。通過給定期望的圖片寬高來改變圖片的大小及占用內(nèi)存空間。

? ? ? ? ? 以上五種方法只是針對Android運(yùn)行加載的Bitmap占用內(nèi)存來說,壓縮后的Bitmap存儲(chǔ)到SD卡中,占用的內(nèi)存空間并不一樣。App開發(fā)過程中,如果需要對內(nèi)存做優(yōu)化,可以從這方面入手。

?

參考鏈接:

? ? ? ? ? ? ? ?bitmap的六種壓縮方式,Android圖片壓縮

? ? ? ? ? ? ? ?Android Bitmap的常用壓縮方式

? ? ? ? ? ? ??Android圖片緩存之Bitmap詳解

? ? ? ? ? ??

?

?

總結(jié)

以上是生活随笔為你收集整理的Android BitMap图片压缩的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。