Android圖片采樣縮放功能實(shí)例代碼
為什么要對Android中的圖片進(jìn)行采樣縮放呢?
是為了更加高效的加載Bitmap。假設(shè)通過imageView來顯示圖片,很多時候ImageView并沒有圖片的原始尺寸那么大,這時候把整張圖片加載進(jìn)來后再設(shè)給ImageView是沒有必要的,因?yàn)镮magView并沒有辦法顯示原始的圖片。
所以我們可以使用BitmapFactory.Options按照一定的采樣率加載縮小后的圖片,將縮小后的圖片在ImageView中顯示,這樣就能降低內(nèi)存占用,在一定程度上避免OOM,提高bitma加載時候的性能。
BitmapFactory有一個參數(shù):inSampleSize(采樣率)。
inSampleSize為1,那么采樣后圖片大小等于原始圖片大小。
inSampleSize為2,那么采樣后圖片寬高均為原始圖片的1/2,像素為原圖的1/4,占有的內(nèi)存大小為原圖的1/4。
例如:一張的圖片像素為1024*1024,儲存格式為ARGB8888格式儲存,那么它占有內(nèi)存1024*1024*4=4M,用采樣率為2采樣后內(nèi)存占用為512*512*4=1M。
總結(jié):inSampleSize是必須大于1的整數(shù)才有效果,小與1就相當(dāng)于1,并且同時作用于寬高,所以縮放后的圖片大小以采樣率的2次方形式遞減.根據(jù)最新的官方文檔,inSampleSize的取值應(yīng)該總是為2的指數(shù),若給系統(tǒng)的inSampleSize不為2的指數(shù),那么系統(tǒng)會向下取整并且選擇一個最接近2的指數(shù)來代替,不過經(jīng)過驗(yàn)證,這個結(jié)論并不是在所有的Android版本上都成立。
那么我們?nèi)绾潍@取采樣率呢?
1、將BitmapFactory.Option的inJustDecodeBound參數(shù)設(shè)為true,加載圖片,這個時候圖片并沒有加載進(jìn)內(nèi)存,僅僅是去解析圖片原始寬高信息而已。
2、從BitmapFactory.Option取出圖片的原始寬高信息,對應(yīng)于outWidth,outHeight參數(shù)。
3、根據(jù)采樣率的規(guī)則和目標(biāo)原始View的所需大小計(jì)算出采樣率inSampleSize。
4、將BitmapFactory.Option的inJustDecodeBound參數(shù)設(shè)為false,重新加載圖片,這時候圖片才真正被載進(jìn)內(nèi)存。
以下提供一份代碼模板:package com.example.chatting.chatting.utils;
import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.BitmapFactory.Options; import android.util.DisplayMetrics; import android.view.ViewGroup.LayoutParams; import android.widget.ImageView; public class ImagesTool { /** * 根據(jù)ImageView的大小壓縮圖片 * @param path * @param imageView * @return */ public static Bitmap decodeSampledBitmapFromPath(String path,ImageView imageView) { Options options = new Options(); options.inJustDecodeBounds=true; BitmapFactory.decodeFile(path,options); ImageSize imageSize=getImageViewSize(imageView); //獲取圖片大小,ImageSize是封裝著ImageView大小的類 //計(jì)算采樣率 options.inSampleSize=caculateInSampleSize(options,imageSize.width,imageSize.height); options.inJustDecodeBounds=false; Bitmap bitmap=BitmapFactory.decodeFile(path, options); return bitmap; } //計(jì)算采樣率 public static int caculateInSampleSize(Options options,ImageView imageView) { ImageSize imageSize=getImageViewSize(imageView); int inSampleSize=caculateInSampleSize(options, imageSize.width,imageSize.height); return inSampleSize; } /** * 根據(jù)具體的大小要求解析圖片 * @param path * @param reqWidth * @param reqHeight * @return */ public static Bitmap decodeSampledBitmapFromPath(String path,int reqWidth, int reqHeight) { Options options = new Options(); options.inJustDecodeBounds=true; BitmapFactory.decodeFile(path,options); //計(jì)算采樣率 options.inSampleSize=caculateInSampleSize(options,reqWidth,reqHeight); options.inJustDecodeBounds=false; Bitmap bitmap=BitmapFactory.decodeFile(path, options); return bitmap; } //計(jì)算采樣率 private static int caculateInSampleSize(Options options, int reqWidth, int reqHeight) { int width=options.outWidth; //原始圖片寬 int height=options.outHeight; //原始圖片高 int inSampleSize=1; //采樣率 if(width>reqWidth || height>reqHeight) //原始的寬比目標(biāo)寬大,或者原始高比目標(biāo)高大 { int widthRadio=Math.round(width *1.0f/reqWidth); int heightRadio = Math.round(height * 1.0f / reqHeight); inSampleSize = Math.max(widthRadio, heightRadio); } return inSampleSize; } //獲取ImageView的大小 protected static ImageSize getImageViewSize(ImageView imageView) { ImageSize imageSize = new ImageSize(); DisplayMetrics metrics = imageView.getContext().getResources().getDisplayMetrics(); LayoutParams lp = imageView.getLayoutParams(); int width = imageView.getWidth(); if (width <= 0) { width = lp.width; } if (width <= 0) { width = imageView.getMaxWidth(); } if (width <= 0) { width = metrics.widthPixels; } int height = imageView.getHeight(); if (height <= 0) { height = lp.height; } if (height <= 0) { height = imageView.getMaxHeight(); } if (height <= 0) { height = metrics.heightPixels; } imageSize.width = width; imageSize.height = height; return imageSize; } //ImageView大小的封裝類 private static class ImageSize { int width; int height; } }
總結(jié)
以上所述是小編給大家介紹的Android圖片采樣縮放功能實(shí)例代碼,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
Android使用ListView實(shí)現(xiàn)下拉刷新及上拉顯示更多的方法
這篇文章主要介紹了Android使用ListView實(shí)現(xiàn)下拉刷新及上拉顯示更多的方法,結(jié)合實(shí)例形式分析了ListView滾動刷新與加載的相關(guān)操作技巧,需要的朋友可以參考下2017-02-02Android自定義View Flyme6的Viewpager指示器
這篇文章主要為大家詳細(xì)介紹了Android自定義View Flyme6的Viewpager指示器,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-01-01Android面試Intent采用了什么設(shè)計(jì)模式解析
這篇文章主要為大家介紹了Android面試Intent采用了什么設(shè)計(jì)模式解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03Android應(yīng)用開發(fā)中觸摸屏手勢識別的實(shí)現(xiàn)方法解析
這篇文章主要介紹了Android應(yīng)用開發(fā)中觸摸屏手勢識別的實(shí)現(xiàn)方法解析,深入的部分則是對左右手勢的識別給出了相關(guān)編寫思路,需要的朋友可以參考下2016-02-02Android實(shí)現(xiàn)高德地圖首頁效果(下)
這篇文章主要為大家詳細(xì)介紹了基于Android實(shí)現(xiàn)高德地圖首頁效果下篇,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2023-08-08Android SQLite數(shù)據(jù)庫操作代碼類分享
這篇文章主要介紹了Android SQLite數(shù)據(jù)庫操作代碼類分享,本文直接給出實(shí)現(xiàn)代碼和使用代碼,需要的朋友可以參考下2015-03-03Android自定義View之組合控件實(shí)現(xiàn)類似電商app頂部欄
這篇文章主要為大家詳細(xì)介紹了Android自定義View之組合控件,實(shí)現(xiàn)類似電商app頂部欄的相關(guān)資料,具有參考價值,感興趣的小伙伴們可以參考一下2016-05-05一文帶你了解Android?Flutter中Transform的使用
flutter的強(qiáng)大之處在于,可以對所有的widget進(jìn)行Transform,因此可以做出非??犰诺男Ч1疚木蛠泶蠹伊私庖幌耇ransform的具體使用,感興趣的可以了解一下2023-01-01