圖片加載<第二篇>:BitmapFactory.Options詳解

(1)常用屬性
BitmapFactory.Options options = new BitmapFactory.Options();

//默認(rèn)值為false酬凳,如果設(shè)置成true,那么在解碼的時(shí)候就不會返回bitmap,即bitmap = null不皆。
options.inJustDecodeBounds = false;

//可以復(fù)用之前用過的bitmap
options.inBitmap = null;

//是該bitmap緩存是否可變,如果設(shè)置為true熊楼,將可被inBitmap復(fù)用
options.inMutable = true;


DisplayMetrics dm = getResources().getDisplayMetrics();
//表示這個(gè)bitmap的像素密度霹娄,當(dāng)inDensity為0時(shí),系統(tǒng)默認(rèn)賦值為屏幕當(dāng)前像素密度
options.inDensity = dm.densityDpi;

//表示要被畫出來時(shí)的目標(biāo)像素密度鲫骗,當(dāng)inTargetDensity為0時(shí)犬耻,系統(tǒng)默認(rèn)賦值為屏幕當(dāng)前像素密度
options.inTargetDensity = options.inDensity;

//表示實(shí)際設(shè)備的像素密度
options.inScreenDensity = 0;

//這個(gè)參數(shù)可以改變bitmap分辨率大小,inSampleSize >= 1执泰。
//當(dāng)inSampleSize < 1時(shí)枕磁,inSampleSize就默認(rèn)是1。
//假如:圖片的寬和高分別是width术吝、height透典,那么圖片解碼生成的bitmap的寬度是:width / inSampleSize,高度是:height / inSampleSize
//inSampleSize影響bitmap的分辨率顿苇,從而影響bitmap占用內(nèi)存的大小峭咒。
options.inSampleSize = 1;

//設(shè)置這個(gè)Bitmap是否可以被縮放,默認(rèn)值是true纪岁,表示可以被縮放凑队。
options.inScaled = true;
(2)圖片加載之前先計(jì)算圖片大小
Bitmap bitmap = BitmapFactory.decodeFile(FileDirUtil.getInstance().getExternalStorageDirectory() + File.separator + "temp.jpg");

我們看一下上面的代碼,那是解碼一張本地圖片,解碼之后bitmap將占用內(nèi)存空間漩氨,如果bitmap太大導(dǎo)致app性能降低西壮,甚至導(dǎo)致OOM發(fā)生,為了防止這種現(xiàn)象叫惊,我們可以先計(jì)算本地圖片的分辨率:

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(FileDirUtil.getInstance().getExternalStorageDirectory() + File.separator + "temp.jpg", options );
int imageHeight = options.outHeight;
Log.d("aaa", "圖片的高度:"+imageHeight);
int imageWidth = options.outWidth;
Log.d("aaa", "圖片的寬度:"+imageWidth);

當(dāng)inJustDecodeBounds設(shè)置true時(shí)款青,本地圖片解碼之后bitmap為null,只計(jì)算圖片的寬度和高度霍狰。拿到圖片寬度和高度之后可以根據(jù)我們自己的策略是否放大或縮小圖片分辨率抡草。

(3)使用inBitmap復(fù)用bitmap

inMutable設(shè)置成true,可以使當(dāng)前bitmap對空間可被復(fù)用蔗坯。

(4)像素密度分析

BitmapFactory.Options中與像素密度有關(guān)的主要有三個(gè)參數(shù):inDensity康震、inTargetDensityinScreenDensity

配合inScaled參數(shù)可以控制圖像縮放宾濒。

我們先看一下源碼

/**
 * Set the newly decoded bitmap's density based on the Options.
 */
private static void setDensityFromOptions(Bitmap outputBitmap, Options opts) {
    if (outputBitmap == null || opts == null) return;

    final int density = opts.inDensity;
    if (density != 0) {
        outputBitmap.setDensity(density);
        final int targetDensity = opts.inTargetDensity;
        if (targetDensity == 0 || density == targetDensity || density == opts.inScreenDensity) {
            return;
        }

        byte[] np = outputBitmap.getNinePatchChunk();
        final boolean isNinePatch = np != null && NinePatch.isNinePatchChunk(np);
        if (opts.inScaled || isNinePatch) {
            outputBitmap.setDensity(targetDensity);
        }
    } else if (opts.inBitmap != null) {
        // bitmap was reused, ensure density is reset
        outputBitmap.setDensity(Bitmap.getDefaultDensity());
    }
}

inDensity的默認(rèn)值為0腿短,會執(zhí)行

outputBitmap.setDensity(Bitmap.getDefaultDensity());

bitmap的像素密度為屏幕默認(rèn)像素密度,相當(dāng)于

DisplayMetrics dm = getResources().getDisplayMetrics();
//表示這個(gè)bitmap的像素密度绘梦,當(dāng)inDensity為0時(shí)橘忱,系統(tǒng)默認(rèn)賦值為屏幕當(dāng)前像素密度
options.inDensity = dm.densityDpi;

當(dāng)我們給inDensity取值時(shí),就會走另一個(gè)分支卸奉,接下來才是重點(diǎn)

當(dāng)inTargetDensity=0或者inDensity=inTargetDensity或者inDensity=inScreenDensity時(shí)钝诚,圖像的像素密度是inDensity,否則择卦,當(dāng)inScaled = true或者圖像為9Path圖片時(shí),最終圖像的像素密度為inTargetDensity郎嫁。

inDensity秉继、inTargetDensityinScreenDensity泽铛、inScaled配合使用可以對圖片進(jìn)行縮放尚辑,縮放的比例是targetDensity / density

(5)inSampleSize

修改像素密度只能修改圖像的分辨率,但不能改變bitmap大小盔腔。
而inSampleSize不僅可以修改分辨率杠茬,而且bitmap的大小也隨便變化。

假如默認(rèn)情況(inSampleSize = 1)下弛随,圖像的分辨率是205x205瓢喉,占用內(nèi)存0.16031265M,那么如果將inSampleSize 設(shè)置成2舀透,那么分辨率的寬和高分別除以2栓票,占用的內(nèi)存也會變小,最終圖像的分辨率是103x103愕够,占用內(nèi)存為0.040470123M走贪,bitmap大小整整縮小了4倍佛猛。

(6)設(shè)置彩色模式
options.inPreferredConfig = Bitmap.Config.ARGB_8888;

比較簡單,只有一句話坠狡。

圖片.png

ARGB_8888: 圖像默認(rèn)模式继找,有AR逃沿、G婴渡、B四個(gè)顏色通道,每個(gè)通道占8位感挥。

ARGB_4444: 已被棄用缩搅,有AR触幼、G硼瓣、B四個(gè)顏色通道,每個(gè)通道占4位置谦。

RGB_565: 屏幕默認(rèn)顏色模式堂鲤,有RG媒峡、B三個(gè)顏色通道瘟栖。

ALPHA_8: 單通道,只有透明度通道谅阿。

RGBA_F16HARDWARE是Android 8.0新增的半哟,目前用的比較少。

(7)獲取圖像的Mime類型
options.outMimeType
(8)設(shè)置緩沖區(qū)大小
//設(shè)置緩存區(qū),如果不設(shè)置默認(rèn)為16M
options.inTempStorage = new byte[1024 * 1024 * 16];

如果不設(shè)置签餐,那么默認(rèn)為16M寓涨。

(9)其他方法
//這個(gè)值和抖動(dòng)解碼有關(guān),默認(rèn)值為false氯檐,表示不采用抖動(dòng)解碼戒良。在Android N 之后已被廢棄。
options.inDither = true;

//這個(gè)值表示是否在解碼時(shí)圖片有更高的品質(zhì)冠摄,僅用于JPEG格式糯崎。如果設(shè)置為true,則圖片會有更高的品質(zhì)河泳,但是會解碼速度會很慢沃呢。
//在Android N 之后已被廢棄。
options.inPreferQualityOverSpeed = true;

//設(shè)置為true時(shí)拆挥,表示空間不夠是否可以被釋放樟插。和inInputShareable一起使用。在Android5.0后被棄用。
options.inPurgeable = false;

//設(shè)置為true時(shí)黄锤,后者表示是否可以共享引用搪缨。和inPurgeable一起使用。在Android5.0后被棄用鸵熟。
options.inInputShareable = false;

//在Android N 之后已被廢棄
options.mCancel = false;

以上這些方法在高版本API上已被棄用副编,所以就不用研究了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末流强,一起剝皮案震驚了整個(gè)濱河市痹届,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌打月,老刑警劉巖队腐,帶你破解...
    沈念sama閱讀 212,294評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異奏篙,居然都是意外死亡柴淘,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,493評論 3 385
  • 文/潘曉璐 我一進(jìn)店門秘通,熙熙樓的掌柜王于貴愁眉苦臉地迎上來为严,“玉大人,你說我怎么就攤上這事肺稀〉诠桑” “怎么了?”我有些...
    開封第一講書人閱讀 157,790評論 0 348
  • 文/不壞的土叔 我叫張陵话原,是天一觀的道長夕吻。 經(jīng)常有香客問我,道長繁仁,這世上最難降的妖魔是什么涉馅? 我笑而不...
    開封第一講書人閱讀 56,595評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮改备,結(jié)果婚禮上控漠,老公的妹妹穿的比我還像新娘蔓倍。我一直安慰自己悬钳,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,718評論 6 386
  • 文/花漫 我一把揭開白布偶翅。 她就那樣靜靜地躺著默勾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪聚谁。 梳的紋絲不亂的頭發(fā)上母剥,一...
    開封第一講書人閱讀 49,906評論 1 290
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼环疼。 笑死习霹,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的炫隶。 我是一名探鬼主播淋叶,決...
    沈念sama閱讀 39,053評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼伪阶!你這毒婦竟也來了煞檩?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,797評論 0 268
  • 序言:老撾萬榮一對情侶失蹤栅贴,失蹤者是張志新(化名)和其女友劉穎斟湃,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體檐薯,經(jīng)...
    沈念sama閱讀 44,250評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡凝赛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,570評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了厨剪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哄酝。...
    茶點(diǎn)故事閱讀 38,711評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖祷膳,靈堂內(nèi)的尸體忽然破棺而出陶衅,到底是詐尸還是另有隱情,我是刑警寧澤直晨,帶...
    沈念sama閱讀 34,388評論 4 332
  • 正文 年R本政府宣布搀军,位于F島的核電站,受9級特大地震影響勇皇,放射性物質(zhì)發(fā)生泄漏罩句。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,018評論 3 316
  • 文/蒙蒙 一敛摘、第九天 我趴在偏房一處隱蔽的房頂上張望门烂。 院中可真熱鬧,春花似錦兄淫、人聲如沸屯远。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,796評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽慨丐。三九已至,卻和暖如春泄私,著一層夾襖步出監(jiān)牢的瞬間房揭,已是汗流浹背备闲。 一陣腳步聲響...
    開封第一講書人閱讀 32,023評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留捅暴,地道東北人恬砂。 一個(gè)月前我還...
    沈念sama閱讀 46,461評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像蓬痒,于是被迫代替她去往敵國和親觉既。 傳聞我的和親對象是個(gè)殘疾皇子乳幸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,595評論 2 350

推薦閱讀更多精彩內(nèi)容

  • 先發(fā)一張昨天去看我雷哥演唱會的皂片然后再說正文哈哈瞪讼。 簡介 由于工作原因,boss下達(dá)的任務(wù)就大概說了對圖片進(jìn)行壓...
    我叫王菜鳥閱讀 5,214評論 2 16
  • 7.1 壓縮圖片 一粹断、基礎(chǔ)知識 1符欠、圖片的格式 jpg:最常見的圖片格式。色彩還原度比較好瓶埋,可以支持適當(dāng)壓縮后保持...
    AndroidMaster閱讀 2,496評論 0 13
  • 摘要:對android 上圖片壓縮希柿,其實(shí)總結(jié)起來基本可以分為兩類壓縮:尺寸壓縮和質(zhì)量壓縮, 尺寸壓縮其實(shí)也可以理解...
    男爵是只貓丶閱讀 8,772評論 2 14
  • 今天去學(xué)校一趟,跟以前比晕粪,給人的感覺是不一樣的挤悉。 在學(xué)校兩年半,直至拍畢業(yè)照時(shí)都沒有一種“要畢業(yè)了”的感覺...
    柳璐櫻閱讀 1,383評論 1 1
  • 第一次知道 “端午節(jié)”是從祖母口中聽說的巫湘。她當(dāng)時(shí)正繪聲繪色地給我講“白娘子與許仙”的故事装悲,說到白娘子與許仙自西湖邊...
    浪里黑條條閱讀 446評論 0 0