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

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(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是圖像處理的最重要類(lèi)之一。用它可以獲取圖像文件信息,進(jìn)行圖像顏色變換、剪切、旋轉(zhuǎn)、縮放等操作,并可以指定格式保存圖像文件。

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

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

了解

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

Bitmap 用來(lái)處理位圖,每一張圖片的每個(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來(lái)決定。Bitmap中,存在一個(gè)枚舉類(lèi)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)存普遍上漲的今天,這樣的開(kāi)銷(xiāo)也是法接受的。

在剛才的實(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ì)不同,為了探究這其中原理,需要通過(guò)觀察 Bitmap.decode 的源碼,這一過(guò)程是有 native 來(lái)完成的,所以我們找到 BitmapFactory.cpp#nativeDecode 開(kāi)始跟蹤,省略了其他不相關(guān)的代碼:

1b627a3bc6b94c8da34fdf0b6a806f5d


上述代碼中,最終 bitmap 是通過(guò) canvas 繪制出來(lái),而 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


通過(guò)以上兩個(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 來(lái)控制縮放系數(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)存占用都被縮小為原來(lái)的 1/4。

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

5c6276611390424d8bb176604c582155


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

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

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

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

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

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

調(diào)試

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

inSampleSize

45aa8fc9b5214936bcaf103256312559


顯示結(jié)果 :


以上 ImageView 的大小(640x320),用來(lái)加載 1920x1080 的圖片確實(shí)有些浪費(fèi),所以經(jīng)過(guò)計(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 是只有透明度的, 所以我們來(lái)看看改為 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,想象一下這樣的開(kāi)銷(xiāo)發(fā)生在一個(gè)圖片列表中,內(nèi)存占用將達(dá)到非??鋸埖牡夭健闹癇itmap占用內(nèi)存的計(jì)算公式來(lái)看,減少內(nèi)存主要可以通過(guò)以下幾種方式:

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

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

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


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

    關(guān)注

    12

    文章

    3980

    瀏覽量

    132324
  • BITMAP
    +關(guān)注

    關(guān)注

    0

    文章

    4

    瀏覽量

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

掃碼添加小助手

加入工程師交流群

    評(píng)論

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

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

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

    ArkUI-X通過(guò)Stage模型開(kāi)發(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開(kāi)發(fā)寶藏案例分享---內(nèi)存優(yōu)化實(shí)戰(zhàn)指南

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

    HarmonyOS優(yōu)化應(yīng)用內(nèi)存占用問(wèn)題性能優(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)存占用問(wèn)題性能優(yōu)化

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

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

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

    變頻器是否有故障的方法判斷

    變頻器是否有故障用這幾種方法就可以輕松判斷,維修使用建議熟記?
    發(fā)表于 03-06 17:19 ?2次下載

    hyper 內(nèi)存,Hyper內(nèi)存:如何監(jiān)控與優(yōu)化hyper-v虛擬機(jī)的內(nèi)存使用

    :如何監(jiān)控與優(yōu)化hyper-v虛擬機(jī)的內(nèi)存使用。 ? ?在虛擬化環(huán)境中,合理監(jiān)控和優(yōu)化Hyper-V虛擬機(jī)的內(nèi)存使用對(duì)于提升性能和資源利用率至關(guān)重要。本文將詳細(xì)介紹如何監(jiān)控Hyper-
    的頭像 發(fā)表于 01-24 14:15 ?1434次閱讀
    hyper <b class='flag-5'>內(nèi)存</b>,Hyper<b class='flag-5'>內(nèi)存</b>:如何監(jiān)控與<b class='flag-5'>優(yōu)化</b>hyper-v虛擬機(jī)的<b class='flag-5'>內(nèi)存</b>使用

    焊接技術(shù)流程優(yōu)化方法

    焊接方法的選擇對(duì)焊接質(zhì)量有著直接影響。常見(jiàn)的焊接方法包括電弧焊、氣體保護(hù)焊、激光焊等。每種方法都有其特點(diǎn)和適用范圍,選擇合適的焊接方法可以提高焊接效率和質(zhì)量。 1.2
    的頭像 發(fā)表于 01-19 13:52 ?1599次閱讀

    如何提高信噪比的有效方法

    信噪比(SNR)是指信號(hào)與噪聲的比例,是評(píng)價(jià)一個(gè)系統(tǒng)或設(shè)備性能的重要指標(biāo)。提高信噪比可以通過(guò)多種方法實(shí)現(xiàn),以下是一些有效的方法: 一、增加信號(hào)強(qiáng)度 提高發(fā)射功率 :在信號(hào)發(fā)射,通過(guò)增加發(fā)射機(jī)的功率
    的頭像 發(fā)表于 12-10 14:30 ?6941次閱讀

    android手機(jī)上emulate應(yīng)用程序的方法

    Android手機(jī)上模擬(emulate)應(yīng)用程序的方法通常涉及到使用Android模擬器(Emulator)或類(lèi)似的工具來(lái)模擬Android環(huán)境,以便在沒(méi)有實(shí)際物理設(shè)備的情況下運(yùn)行
    的頭像 發(fā)表于 12-05 15:33 ?1837次閱讀

    什么是虛擬內(nèi)存分頁(yè) Windows系統(tǒng)虛擬內(nèi)存優(yōu)化方法

    虛擬內(nèi)存分頁(yè)概述 在Windows操作系統(tǒng)中,虛擬內(nèi)存是通過(guò)分頁(yè)機(jī)制實(shí)現(xiàn)的。分頁(yè)允許系統(tǒng)將內(nèi)存中的數(shù)據(jù)移動(dòng)到硬盤(pán)上,以便為當(dāng)前運(yùn)行的程序騰出空間。這個(gè)過(guò)程對(duì)于保持系統(tǒng)的流暢運(yùn)行至關(guān)重要,尤其是在物理
    的頭像 發(fā)表于 12-04 09:16 ?1953次閱讀

    如何優(yōu)化FOC電機(jī)性能

    其他參數(shù)。這種方法精度高,但需要拆卸電機(jī)或使用專門(mén)的測(cè)試設(shè)備。 在線參數(shù)辨識(shí):在電機(jī)運(yùn)行過(guò)程中,通過(guò)采集電機(jī)運(yùn)行數(shù)據(jù),再利用算法估計(jì)出電機(jī)參數(shù)。這種方法無(wú)需拆卸電機(jī),但精度可能不如離線參數(shù)辨識(shí)。 PID參數(shù)調(diào)整 : PID(比例
    的頭像 發(fā)表于 11-21 14:50 ?2275次閱讀

    如何優(yōu)化RAM內(nèi)存使用

    優(yōu)化RAM內(nèi)存使用是一個(gè)重要的任務(wù),特別是對(duì)于那些擁有有限內(nèi)存資源的用戶。以下是一些優(yōu)化RAM內(nèi)存使用的策略,這些策略可以幫助您更有效地使用
    的頭像 發(fā)表于 11-11 09:58 ?2204次閱讀

    如何檢測(cè)電腦的RAM內(nèi)存

    和評(píng)估電腦的RAM內(nèi)存呢? 1. 通過(guò)操作系統(tǒng)檢測(cè)RAM 1.1 Windows系統(tǒng) 在Windows操作系統(tǒng)中,有幾種方法可以查看RAM信息: 任務(wù)管理器 :按 Ctrl + Shift + Esc 打開(kāi)任務(wù)管理器,點(diǎn)擊“性能”標(biāo)簽頁(yè),可以看到
    的頭像 發(fā)表于 11-11 09:51 ?4120次閱讀