chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

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

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

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

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

掃碼添加小助手

加入工程師交流群

作者 | Video++極鏈科技移動端Team秦鵬程

整理 | 包包

初識

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

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

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

了解

Bitmap 占用了多大的內存

Bitmap 用來處理位圖,每一張圖片的每個像素點都會被讀取,每個像素點的大小決定了 Bitmap 的內存大小。

所以計算內存大小的公式為:

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

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

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

dd10223e3e0a41f3ba4e5857adf086e1


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

Bitmap 占用內存大小實例

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


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

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


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

1b627a3bc6b94c8da34fdf0b6a806f5d


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

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

? inTargetDensity: Bitmap 最終繪制的目標位置的分辨率

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

a4a77501595a4a0ca17ea7fad53a2faa


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

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

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

手動設置縮放系數(shù)

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

168ca8c69c4b432e92b3f6eac127cc07


壓縮方式 inSampleSize & quality

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

quality 正如字面意思指的是圖片品質,在代碼中對應的 api 為:

5c6276611390424d8bb176604c582155


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

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

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

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

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

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

調試

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

inSampleSize

45aa8fc9b5214936bcaf103256312559


顯示結果 :


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

降低圖片品質

0b74cd8226bd4e15819acd14b12b53dd


顯示結果 :


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

改變 Bitmap.Config

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


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

總結

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

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

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

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


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

    關注

    12

    文章

    4026

    瀏覽量

    134004
  • BITMAP
    +關注

    關注

    0

    文章

    4

    瀏覽量

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

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    知識分享|連接器焊接方法幾種?

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

    rk基于linux/android內存管理

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

    Linux Swap交換空間詳解:Android編譯內存不足?這樣擴充立竿見影

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

    有多少種方法可以進行頻響曲線測量?

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

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

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

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

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

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

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

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

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

    請問如何優(yōu)化OpenVINO?工具套件中的內存使用?

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

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

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

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

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

    ArkUI-X與Android橋接通信之方法回調

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

    HarmonyOS優(yōu)化應用內存占用問題性能優(yōu)化

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

    HarmonyOS優(yōu)化應用內存占用問題性能優(yōu)化

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

    HarmonyOS優(yōu)化應用內存占用問題性能優(yōu)化

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