国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Android端:優(yōu)化Bitmap內(nèi)存的幾種方法

張康康 ? 2019-07-29 18:27 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

作者 | Video++極鏈科技移動(dòng)端Team秦鵬程

整理 | 包包

初識(shí)

Bitmap是圖像處理的最重要類之一。用它可以獲取圖像文件信息,進(jìn)行圖像顏色變換、剪切、旋轉(zhuǎn)、縮放等操作,并可以指定格式保存圖像文件。

許多 Android 開發(fā)者都對(duì) Bitmap 不陌生,其作為顯示圖片的載體,會(huì)經(jīng)常接觸。而在日常開發(fā)中對(duì)圖片的處理通常會(huì)用到第三方的開源庫:Glide、Fresco、Picasso...,這些已經(jīng)足夠完善的工具不需要讓我們考慮處理 Bitmap 的細(xì)節(jié),這使得我們對(duì)其不是那么熟悉。

Bitmap 實(shí)實(shí)在在是內(nèi)存使用的“大客戶”。如何更好的使用 Bitmap,減少其對(duì)App內(nèi)存的使用,是 Android 優(yōu)化方面不可回避的問題,因此,本文從常規(guī)的 Bitmap 使用,到 Bitmap 內(nèi)存計(jì)算,最后分析如何更有效的使用 Bitmap。

了解

Bitmap 占用了多大的內(nèi)存

Bitmap 用來處理位圖,每一張圖片的每個(gè)像素點(diǎn)都會(huì)被讀取,每個(gè)像素點(diǎn)的大小決定了 Bitmap 的內(nèi)存大小。

所以計(jì)算內(nèi)存大小的公式為:

占用的內(nèi)存大小 = 像素總數(shù)量(寬x高)x 每個(gè)像素的字節(jié)大小

單個(gè)像素的字節(jié)大小

單個(gè)像素的字節(jié)大小由Bitmap的一個(gè)可配置的參數(shù)Config來決定。Bitmap中,存在一個(gè)枚舉類Config,定義了Android中支持的Bitmap配置:

dd10223e3e0a41f3ba4e5857adf086e1


Android系統(tǒng)中,默認(rèn)Bitmap加載圖片,使用ARGB_8888模式。

Bitmap 占用內(nèi)存大小實(shí)例

我們準(zhǔn)備一張分辨率為 1920x1080,大小為 273KB 的 jpg 圖片,放在手機(jī)SD 卡中,調(diào)用 BitmatFactory.decodeFile() 加載并顯示到一個(gè)大小為 640x320 的 ImageView 中,占用的內(nèi)存如下:


從計(jì)算內(nèi)存大小的公式可以得到加載這張圖片使用了大約 7m 的內(nèi)存,即使是手機(jī)內(nèi)存普遍上漲的今天,這樣的開銷也是法接受的。

在剛才的實(shí)例中,我們是將圖片放在了手機(jī)的外置 SD 卡中,現(xiàn)在,我們將圖片分別放到項(xiàng)目工程的 mipmap-xhdpi, mipmap-xxhdpi, mipmap-xxxhdpi 這三個(gè)資源目錄中,調(diào)用 BitmatFactory.decodeResource() 加載到同樣的 ImageView 中看看加載的情況:


我們發(fā)現(xiàn),圖片放在不同的資源目錄中、使用不同的方法加載,占用的內(nèi)存也會(huì)不同,為了探究這其中原理,需要通過觀察 Bitmap.decode 的源碼,這一過程是有 native 來完成的,所以我們找到 BitmapFactory.cpp#nativeDecode 開始跟蹤,省略了其他不相關(guān)的代碼:

1b627a3bc6b94c8da34fdf0b6a806f5d


上述代碼中,最終 bitmap 是通過 canvas 繪制出來,而 canvas 繪制前有 scale 的操作 scale = (float) targetDensity / density; 這一行代碼決定,即縮放的倍率和 targetDensity 和 density 相關(guān),而這兩個(gè)參數(shù)都是從傳入的 options 中獲取到的,再到 Bitmap.Options 中找到相關(guān)的參數(shù):

? inDensity:Bitmap 位圖自身的密度、分辨率

? inTargetDensity: Bitmap 最終繪制的目標(biāo)位置的分辨率

其中 inDensity 和圖片存放的資源文件的目錄有關(guān),同一張圖片放置在不同目錄下會(huì)有不同的值:

a4a77501595a4a0ca17ea7fad53a2faa


通過以上兩個(gè)實(shí)例,我們得出了 decodeResource() 和 decodeFile() 的區(qū)別:

?decodeResource 用于讀取Res、Raw等資源,得到的是圖片的原始尺寸 * 縮放系數(shù)(inDensity)

?decodeFile 用于讀取SD卡上的圖,得到的是圖片的原始尺寸

手動(dòng)設(shè)置縮放系數(shù)

在 Bitmap.Options 中還有一個(gè)為 inScaled 的屬性,如果設(shè)置為 false,則不進(jìn)行縮放,如果設(shè)置為 true 或者不設(shè)置,則根據(jù) inDensity 和 inTargetDensity 計(jì)算縮放系數(shù)。 如果你不想依賴于這個(gè)系統(tǒng)本身的 density,你可以手動(dòng)設(shè)置 inDensity 和 inTargetDensity 來控制縮放系數(shù):

168ca8c69c4b432e92b3f6eac127cc07


壓縮方式 inSampleSize & quality

inSampleSize 指的是壓縮分辨率,取值必須為 2 的冪(當(dāng)不為2的冪時(shí),解碼器會(huì)取與該值最接近的2的冪),例如,當(dāng) inSampleSize = 2 時(shí),一張 1920x1080 的圖片,將會(huì)被縮小為 960x540,相應(yīng)的它的像素?cái)?shù)和內(nèi)存占用都被縮小為原來的 1/4。

quality 正如字面意思指的是圖片品質(zhì),在代碼中對(duì)應(yīng)的 api 為:

5c6276611390424d8bb176604c582155


CompressFormat 為 Bitmap 中的枚舉類,有三個(gè)可用值:

? JPEG:表示以 JPEG 壓縮算法進(jìn)行圖像壓縮,壓縮后的格式可以是 “.jpg” 或者 “.jpeg” ,是一種有損壓縮。

? PNG:表示以 PNG 壓縮算法進(jìn)行圖像壓縮,壓縮后的格式可以是 “.png” ,是一種無損壓縮。

? WEBP:表示以 WebP 壓縮算法進(jìn)行圖像壓縮,壓縮后的格式可以是 “.webp” ,是一種有損壓縮,質(zhì)量相同的情況下,WebP 格式圖像的體積要比 JPEG 格式圖像小40%。美中不足的是,WebP格式圖像的編碼時(shí)間“比JPEG格式圖像長(zhǎng)8倍”。

quality 為圖片的品質(zhì),取值為 0-100,100 代表最高品質(zhì),不被壓縮。另外,類似 PNG 這種無損格式會(huì)忽略 quality 的設(shè)置 stream 為圖片被壓縮后被保存在的輸出流。

然而 Bitmap.compress 方法確實(shí)可以壓縮圖片,但壓縮的是存儲(chǔ)大小,即放到 disk 上的大小。

調(diào)試

現(xiàn)在我們通過幾個(gè)實(shí)例,來驗(yàn)證一下以上的結(jié)論,首先來看一下兩種壓縮方式占用內(nèi)存的影響:

inSampleSize

45aa8fc9b5214936bcaf103256312559


顯示結(jié)果 :


以上 ImageView 的大小(640x320),用來加載 1920x1080 的圖片確實(shí)有些浪費(fèi),所以經(jīng)過計(jì)算,將原圖壓縮后發(fā)現(xiàn)圖片占用內(nèi)存的大小減少到原圖的 1/10,如果原圖本身與控件的大小相差不多,這時(shí)候還要縮放的話就會(huì)影響到圖片顯示的質(zhì)量。

降低圖片品質(zhì)

0b74cd8226bd4e15819acd14b12b53dd


顯示結(jié)果 :


使用降低圖片質(zhì)量的方式壓縮圖片,可以發(fā)現(xiàn)盡管已經(jīng)降低了 90% 的品質(zhì),圖片也變得模糊,但其占用的內(nèi)存與直接加載還是一樣的。

改變 Bitmap.Config

我們已經(jīng)知道, Bitmap 加載圖片默認(rèn)使用的 config 為 ARGB_8888,而且 ALPHA_8 是只有透明度的, 所以我們來看看改為 ARGB_4444 和 RGB_565 所顯示的結(jié)果,只需要在 decode 的時(shí)候傳入設(shè)置好的 options 參數(shù),所以這里直接給出顯示結(jié)果:


可以看到將 config 改為 ARGB_4444,所占用的內(nèi)存與原圖一樣,而 RGB_565,變得是原圖的 1/2,所以結(jié)論也不言而喻了,另外 ARGB_4444,已被官方標(biāo)記為廢棄。

總結(jié)

在上面,我們將一張 1920x1080 的圖片,不做任何處理解析到內(nèi)存中,將近占用的 7M,想象一下這樣的開銷發(fā)生在一個(gè)圖片列表中,內(nèi)存占用將達(dá)到非常夸張的地步。從之前Bitmap占用內(nèi)存的計(jì)算公式來看,減少內(nèi)存主要可以通過以下幾種方式:

? 使用低色彩的解析模式,如RGB565,減少單個(gè)像素的字節(jié)大小。這樣大約能減少一半的內(nèi)存開銷。Android 默認(rèn)是使用 ARGB_8888 配置來處理色彩,占用4字節(jié),改用RGB_565,將只占用2字節(jié),代價(jià)是顯示的色彩將相對(duì)少,適用于對(duì)色彩豐富程度要求不高的場(chǎng)景。

? 資源文件合理放置,高分辨率圖片可以放到高分辨率目錄下。和圖片的具體分辨率有關(guān),建議開發(fā)中,高分辨率的圖像應(yīng)該放置到合理的資源目錄下,注意到Android默認(rèn)放置的資源目錄是對(duì)應(yīng)于160dpi,目前手機(jī)屏幕分辨率越來越高,此處能節(jié)省下來的開銷也是很可觀的。理論上,圖片放置的資源目錄分辨率越高,其占用內(nèi)存會(huì)越小,但是低分辨率圖片會(huì)因此被拉伸,顯示上出現(xiàn)失真。另一方面,高分辨率圖片也意味著其占用的本地儲(chǔ)存也變大。

? 圖片縮小,減少尺寸。理論上根據(jù)適用的環(huán)境,是可以減少十幾倍的內(nèi)存使用的,它基于這樣一個(gè)事實(shí):源圖片尺寸一般都大于目標(biāo)需要顯示的尺寸,因此可以通過縮放的方式,來減少顯示時(shí)的圖片寬高,從而大大減少占用的內(nèi)存。


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Android
    +關(guān)注

    關(guān)注

    12

    文章

    4026

    瀏覽量

    133988
  • BITMAP
    +關(guān)注

    關(guān)注

    0

    文章

    4

    瀏覽量

    6654
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    知識(shí)分享|連接器焊接方法幾種

    連接器是一種用于連接電路的元件,通常由金屬制成。下面跟小欣一起看看連接器的焊接方法有哪幾種呢?烙鐵焊接法是最常見的連接器焊接方法之一。使用烙鐵將連接器和電路板焊接在一起,這種方法需要使
    的頭像 發(fā)表于 01-20 17:57 ?1166次閱讀
    知識(shí)分享|連接器焊接<b class='flag-5'>方法</b>有<b class='flag-5'>幾種</b>?

    rk基于linux/android內(nèi)存管理

    一、內(nèi)存分布 ? U-Boot 由前級(jí) Loader 加載到 CONFIG_SYS_TEXT_BASE 地址,初始化時(shí)會(huì)探明當(dāng)前系統(tǒng)的總內(nèi)存容 量, 32 位平臺(tái)上認(rèn)為最大 4GB 可用(但是不影響
    的頭像 發(fā)表于 12-15 10:42 ?211次閱讀
    rk基于linux/<b class='flag-5'>android</b><b class='flag-5'>內(nèi)存</b>管理

    Linux Swap交換空間詳解:Android編譯內(nèi)存不足?這樣擴(kuò)充立竿見影

    ? ? 在 ?Linux? 系統(tǒng)使用過程中,你是否遇到過? “ 內(nèi)存不足 ”? 的報(bào)錯(cuò)?比如編譯? Android? 源碼時(shí),明明按教程操作,卻因物理內(nèi)存沒達(dá)到? 16G? 要求而編譯中斷?這正是
    的頭像 發(fā)表于 12-06 08:10 ?4255次閱讀

    有多少種方法可以進(jìn)行頻響曲線測(cè)量?

    APx500軟件提供了頻響曲線的多種測(cè)量方法,對(duì)一個(gè)音頻產(chǎn)品的頻響特性進(jìn)行測(cè)量分析。如果只用一個(gè)測(cè)量對(duì)一個(gè)音頻產(chǎn)品進(jìn)行評(píng)價(jià),那這個(gè)測(cè)量就是頻響曲線,APx500軟件提供了多種方法可以進(jìn)行頻響曲線測(cè)量
    的頭像 發(fā)表于 11-14 11:29 ?878次閱讀
    有多少<b class='flag-5'>種方法</b>可以進(jìn)行頻響曲線測(cè)量?

    內(nèi)存與數(shù)據(jù)處理優(yōu)化藝術(shù)

    內(nèi)存訪問是程序運(yùn)行的瓶頸之一。減少內(nèi)存訪問次數(shù)可以顯著提高程序的運(yùn)行速度。 在C語言中,指針是直接操作內(nèi)存的利器。使用指針遍歷數(shù)組不僅代碼更簡(jiǎn)潔,而且效率更高。例如,用指針直接訪問內(nèi)存
    發(fā)表于 11-14 07:46

    GPIO位輸出操作的幾種方法分享

    ;    //端口A的位3輸出1   PAout03 = 0;    //端口A的位3輸出0 5、綜述   以上4種方法,1、2兩種較為多見;方法3為位帶操作,速度最快,但只對(duì)具備位帶的U有效;方法4是一種新穎的通用
    發(fā)表于 11-13 07:50

    蜂鳥E203內(nèi)核優(yōu)化方法

    。 修改內(nèi)核參數(shù):對(duì)蜂鳥E203的內(nèi)核參數(shù)進(jìn)行相應(yīng)修改,可以優(yōu)化內(nèi)核運(yùn)行效率,提高系統(tǒng)性能,比如調(diào)整緩存大小、內(nèi)存分配策略等。 資源管理:進(jìn)行有針對(duì)的資源管理,例如調(diào)度算法的修改,調(diào)整好CPU占用率等,以
    發(fā)表于 10-21 07:55

    發(fā)展趨勢(shì)下,云算力如何賦能智能駕駛技術(shù)躍遷?

    學(xué)習(xí)網(wǎng)絡(luò)中,讓系統(tǒng)直接從傳感器數(shù)據(jù)生成車輛控制指令。這種方法在提升系統(tǒng)響應(yīng)速度、優(yōu)化復(fù)雜場(chǎng)景表現(xiàn)以及減少模塊間誤差積累方面展現(xiàn)出顯著優(yōu)勢(shì),但同時(shí),為了滿足足夠龐大的智能駕駛輔助需求,
    的頭像 發(fā)表于 09-08 09:16 ?912次閱讀
    <b class='flag-5'>端</b>到<b class='flag-5'>端</b>發(fā)展趨勢(shì)下,云算力如何賦能智能駕駛技術(shù)躍遷?

    請(qǐng)問如何優(yōu)化OpenVINO?工具套件中的內(nèi)存使用?

    運(yùn)行OpenVINO?推斷時(shí)找不到優(yōu)化內(nèi)存使用情況的方法
    發(fā)表于 06-25 06:56

    ArkUI-X通過Stage模型開發(fā)Android應(yīng)用指南(一)

    Android應(yīng)用內(nèi)的Activity的packageName需要與Ability的bundleName一致。 Android應(yīng)用內(nèi)的Activity的activityNam
    發(fā)表于 06-24 22:16

    鴻蒙5開發(fā)寶藏案例分享---內(nèi)存優(yōu)化實(shí)戰(zhàn)指南

    ,里面提供的工具和技巧簡(jiǎn)直太香了!很多案例和方法,在實(shí)際開發(fā)中真的能救命,避免應(yīng)用卡頓、崩潰,還能讓設(shè)備續(xù)航更持久。 今天就來跟大家好好分享這份寶藏,結(jié)合官方內(nèi)容和我的理解,整理成這篇實(shí)戰(zhàn)性超強(qiáng)的內(nèi)存優(yōu)化
    發(fā)表于 06-12 17:15

    ArkUI-X與Android橋接通信之方法回調(diào)

    平臺(tái)橋接用于客戶(ArkUI)和平臺(tái)(Android或iOS)之間傳遞消息,即用于ArkUI與平臺(tái)雙向數(shù)據(jù)傳遞、ArkUI側(cè)調(diào)用平臺(tái)的方法、平臺(tái)調(diào)用ArkUI側(cè)的方法。本文主要介紹
    發(fā)表于 06-08 22:16

    HarmonyOS優(yōu)化應(yīng)用內(nèi)存占用問題性能優(yōu)化

    一、使用purgeable優(yōu)化C++內(nèi)存 Purgeable Memory是HarmonyOS中native層常用的內(nèi)存管理機(jī)制,可用于圖像處理的Bitmap、流媒體應(yīng)用的一次性數(shù)據(jù)、
    發(fā)表于 05-24 17:20

    HarmonyOS優(yōu)化應(yīng)用內(nèi)存占用問題性能優(yōu)化

    一、使用生命周期管理優(yōu)化ArkTS內(nèi)存 組件的生命周期,指的是組件自身的一些可自執(zhí)行的方法,這些方法會(huì)在特殊的時(shí)間點(diǎn)或遇到一些特殊頁面行為時(shí)被自動(dòng)觸發(fā)而執(zhí)行。 (一)原理介紹 在開發(fā)過
    發(fā)表于 05-23 15:35

    HarmonyOS優(yōu)化應(yīng)用內(nèi)存占用問題性能優(yōu)化

    可以避免圖片過大或過小導(dǎo)致的顯示問題,并提高應(yīng)用程序的用戶體驗(yàn)。 二、多種****方法 在日常開發(fā)中,常見的其他減少內(nèi)存方式有如下幾種: 使用虛引用(Weak Reference):在HarmonyOS
    發(fā)表于 05-21 11:27