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高效內(nèi)存:讓圖片占用盡可能少的內(nèi)存

Dbwd_Imgtec ? 來(lái)源:未知 ? 作者:胡薇 ? 2018-06-02 11:05 ? 次閱讀

在做內(nèi)存優(yōu)化的時(shí)候,我們發(fā)現(xiàn)除了解決內(nèi)存泄露問(wèn)題,剩下的就只有想辦法減少真實(shí)的內(nèi)存占用。而在App中,大部分內(nèi)存可能被我們圖片占用了,所以減少圖片的內(nèi)存占用可以帶來(lái)直接的效果。

一、一張圖片到底占用多少內(nèi)存

我們先假設(shè)我們有一張圖片是600 * 800像素的,圖片磁盤(pán)占用空間大小假設(shè)是 100KB。

圖片內(nèi)存大小跟磁盤(pán)占用空間大小有什么關(guān)系?

磁盤(pán)占用空間的大小不是圖片占用內(nèi)存的大小,磁盤(pán)占用空間是在磁盤(pán)上存儲(chǔ)圖片需要的一個(gè)空間大小,內(nèi)存大小是加載到內(nèi)存中占用的內(nèi)存大小。兩個(gè)只是單位是一樣的,本質(zhì)不是一個(gè)概念。

一張圖片到底占用多少內(nèi)存呢?

圖片占用內(nèi)存的計(jì)算公式是:圖片高度 * 圖片寬度 * 一個(gè)像素占用的內(nèi)存大小,在Android中一般情況下默認(rèn)一個(gè)像素占用內(nèi)存是4個(gè)字節(jié),所以上面的圖片占用內(nèi)存是:800 * 600 * 4 byte = 1875KB = 1.83M。為什么是4個(gè)字節(jié)呢?一定是4個(gè)字節(jié)么?這兩個(gè)問(wèn)題后面仔細(xì)講。

圖片所在目錄對(duì)內(nèi)存的影響?

在Android中,圖片的存放目錄和手機(jī)的屏幕密度影響圖片最終加載到內(nèi)存的實(shí)際大小,舉個(gè)例子:假設(shè)我們的圖片放到xhdpi目錄下,那么我們本文中的圖片占用的內(nèi)存大小如下:

屏幕密度為2的設(shè)備:800 * 600 * 4byte = 1.83M

屏幕密度為3的設(shè)備:800 * 1.5 * 600 * 1.5 * 4byte = 1.83 * 2.25M = 4.12M

這里所說(shuō)的屏幕密度是指android.util.DisplayMetrics類(lèi)中的density變量,是一個(gè)float值,關(guān)于屏幕密度的更多內(nèi)容本文不做介紹。

所以,計(jì)算圖片占用內(nèi)存大小的時(shí)候,要考慮圖片所在的目錄跟屏幕密度,這兩個(gè)因素其實(shí)影響的是圖片的高寬,Android會(huì)對(duì)圖片進(jìn)行拉升跟壓縮。

二、 讓你的圖片省內(nèi)存

2.1 讓你的圖片最小化

圖片的內(nèi)存占用計(jì)算方式為:圖片高度 * 圖片寬度 * 一個(gè)像素占用的內(nèi)存大小,所以圖片的高寬如果都變?yōu)樵瓉?lái)寬高的2倍,那么內(nèi)存將變?yōu)樵瓉?lái)的4倍。所以圖片的使用原則可以總結(jié)如下:

使用盡可能小的圖

使用.9圖,.9圖本身也要盡可能的小

自己繪制(覆寫(xiě)View的onDraw自己畫(huà))或者使用Drawable來(lái)繪制

比如要實(shí)現(xiàn)一個(gè)線性漸變效果可以采用以下drawable實(shí)現(xiàn):

2.2 在內(nèi)存中壓縮圖片

加載大圖片時(shí)需要對(duì)圖片進(jìn)行壓縮,使用等比例壓縮方法直接在內(nèi)存中處理圖片。

這樣做要注意的是,圖片質(zhì)量會(huì)變差,inSampleSize設(shè)置的值越大,圖片質(zhì)量就越差。

2.3 讀取位圖尺寸和類(lèi)型時(shí)不把圖片加載到內(nèi)存中

有時(shí)候我們?nèi)〉靡粡垐D片,也許只是為了獲得這個(gè)圖片的一些信息,比如圖片的width、height等信息,不需要顯示到界面上,這個(gè)時(shí)候我們可以不把圖片加載到內(nèi)存中。

2.4 用完就回收

由于Android外層是使用java,而底層使用的是C語(yǔ)言為圖片對(duì)象分配的內(nèi)存空間。所以我們的外部雖然看起來(lái)釋放了,但里層卻并不一定完全釋放了,我們使用完圖片后最好再釋放掉里層的內(nèi)存空間。

2.5 降低要顯示的圖片色彩質(zhì)量

2.5.1 顏色模型

RGB(ARGB)

RGB色彩模式是工業(yè)界的一種顏色標(biāo)準(zhǔn),是通過(guò)對(duì)紅(R)、綠(G)、藍(lán)(B)三個(gè)顏色通道的變化以及它們相互之間的疊加來(lái)得到各式各樣的顏色的,RGB即是代表紅、綠、藍(lán)三個(gè)通道的顏色,這個(gè)標(biāo)準(zhǔn)幾乎包括了人類(lèi)視力所能感知的所有顏色,是目前運(yùn)用最廣的顏色系統(tǒng)之一。在Android中還有包含透明度Alpha的顏色模型,即ARGB。

2.5.2 RGB在計(jì)算機(jī)中顏色值的數(shù)字化編碼

在不考慮透明度的情況下,一個(gè)像素點(diǎn)的顏色值在計(jì)算機(jī)中的表示方法有以下3種:

浮點(diǎn)數(shù)編碼:比如float: (1.0, 0.5, 0.75),每個(gè)顏色分量各占1個(gè)float字段,其中1.0表示該分量的值為全紅或全綠或全藍(lán)。

24位的整數(shù)編碼:比如24-bit:(255, 128, 196),每個(gè)顏色分量各占8位,取值范圍0-255,其中255表示該分量的值為全紅或全綠或全藍(lán)。

16位的整數(shù)編碼:比如16-bit:(31, 45, 31),第1和第3個(gè)顏色分量各占5位,取值范圍0-31,第2個(gè)顏色分量占6位,取值范圍0-63。

在Java中,float類(lèi)型的變量占32位,int類(lèi)型的變量占32位,short和char類(lèi)型的變量都在16位,因此可以看出,用浮點(diǎn)數(shù)表示法編碼一個(gè)像素的顏色,內(nèi)存占用量是96位即12字節(jié);而用24位整數(shù)表示法編碼,只要一個(gè)int類(lèi)型變量,占用4個(gè)字節(jié)(高8位空著,低24位用于表示顏色);用16位整數(shù)表示法編碼,只要一個(gè)short類(lèi)型變量,占2個(gè)字節(jié);因此可以看出采用整數(shù)表示法編碼顏色值,可以大大節(jié)省內(nèi)存,當(dāng)然,顏色質(zhì)量也會(huì)相對(duì)低一些。在Android中獲取Bitmap的時(shí)候一般也采用整型編碼。

2.5.3 Android中RGB編碼格式(整型編碼)

RGB888(int):R、G、B分量各占8位

RGB565(short):R、G、B分量分別占5、6、5位

RGB555(short):RGB分量都用5位表示(剩下的1位不用)

ARGB8888(int):A、R、G、B分量各占8位

ARGB4444(short):A、R、G、B分量各占4位

在Android的Bitmap.Config類(lèi)中,有ARGB_8888、ARGB_4444、RGB565等常量,現(xiàn)在可以知道它們分別代表了什么含義。

在Android中系統(tǒng)默認(rèn)使用的編碼格式是ARGB_8888,所以在文章開(kāi)頭計(jì)算圖片內(nèi)存大小的時(shí)候每個(gè)像素占用內(nèi)存大小是4byte,比如采用ARGB_8888編碼載入一張1920*1200的圖片,大概就會(huì)占用1920*1200*4/1024/1024=8.79MB的內(nèi)存。

2.5.4 降低要顯示的圖片色彩質(zhì)量

采用低內(nèi)存占用量的編碼方式,比如Bitmap.Config.ARGB_4444比Bitmap.Config.ARGB_8888更省內(nèi)存,比如1920*1200的圖片。

ARGB_8888:1920*1200*4/1024/1024=8.79MB

ARGB_4444,RGB565:1920*1200*2/1024/1024=4.39MB

三、總結(jié)

在Android中,對(duì)圖片的使用一定要關(guān)注,大多數(shù)情況下,占用內(nèi)存多,OOM發(fā)生都是因?yàn)閳D片資源使用不當(dāng)。不要盲目加一個(gè)大圖到Android項(xiàng)目中,能使用.9進(jìn)來(lái)使用,而且.9圖本身盡可能小,另外能使用繪制實(shí)現(xiàn)就不要加一個(gè)圖片資源。有些時(shí)候,在不影響用戶(hù)體驗(yàn)的情況下,可以降低圖片色彩質(zhì)量,比如不需要透明度的就不要了,有些透明度用肉眼看不出來(lá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

    文章

    3936

    瀏覽量

    127413
  • 內(nèi)存
    +關(guān)注

    關(guān)注

    8

    文章

    3025

    瀏覽量

    74054

原文標(biāo)題:Android高效內(nèi)存之讓你的圖片省內(nèi)存

文章出處:【微信號(hào):Imgtec,微信公眾號(hào):Imagination Tech】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    內(nèi)存管理學(xué)習(xí)筆記分享

    物理內(nèi)存分配設(shè)計(jì)有兩個(gè)重要的評(píng)價(jià)維度。一方面,物理內(nèi)存分配器要追求更高的內(nèi)存資源利用率,即盡可能減少資源浪費(fèi)。另一方面,物理內(nèi)存分配器要追求
    的頭像 發(fā)表于 01-06 14:53 ?1716次閱讀

    Linux內(nèi)核內(nèi)存規(guī)整總結(jié)

    1.前言 伙伴系統(tǒng)作為內(nèi)核最基礎(chǔ)的物理頁(yè)內(nèi)存分配器,具有高效、實(shí)現(xiàn)邏輯簡(jiǎn)介等優(yōu)點(diǎn),其原理頁(yè)也盡可能降低內(nèi)存外部碎片產(chǎn)生,但依然無(wú)法杜絕碎片問(wèn)題。外部碎片帶來(lái)的最大影響就是
    的頭像 發(fā)表于 11-11 11:17 ?1323次閱讀
    Linux內(nèi)核<b class='flag-5'>內(nèi)存</b>規(guī)整總結(jié)

    五大方法內(nèi)存使用更高效

    、文件或窗口。有些應(yīng)用程序不能用一般的方法關(guān)閉,這時(shí)就要進(jìn)行熱啟動(dòng),如按下“CTRL+ALT+DEL”;另外要注意剪貼板中如果存儲(chǔ)了一幅圖片或圖像,圖片或圖像是要占用大量內(nèi)存的,這時(shí)只
    發(fā)表于 01-02 23:46

    labview的內(nèi)存問(wèn)題

    如圖所示為,圖像處理一個(gè)圖像的過(guò)程,按照道理這種圖片的大小為43.3MB,可是觀察VI運(yùn)行時(shí)候的內(nèi)存占用大小,如果沒(méi)有VI運(yùn)行至最后,那么vi占用
    發(fā)表于 09-18 21:20

    如何確保盡可能高效地測(cè)試開(kāi)關(guān)穩(wěn)壓器?

    問(wèn)題:如何確保盡可能高效地測(cè)試開(kāi)關(guān)穩(wěn)壓器?
    發(fā)表于 03-01 08:50

    緩沖VDAC輸出損失如何盡可能的減少?

    ,但是連接后電壓不會(huì)下降到1.9V以下。JRK直接從電位器工作。我想在PSoC和控制器之間放置一個(gè)運(yùn)放來(lái)緩沖這個(gè),但是我想盡可能的損失,盡可能地保持輸出的精確性。我需要一個(gè)DIL包,這樣我就可以剝離
    發(fā)表于 10-08 12:43

    解碼會(huì)占用多少內(nèi)存?使用vpp進(jìn)行圖像處理最大可能會(huì)消耗多少內(nèi)存?

    解碼會(huì)占用多少內(nèi)存?使用vpp進(jìn)行圖像處理,最大可能會(huì)消耗多少內(nèi)存
    發(fā)表于 09-19 07:24

    DDR內(nèi)存接口的設(shè)計(jì)與實(shí)現(xiàn)

    針對(duì)當(dāng)今電子系統(tǒng)對(duì)高速大容量內(nèi)存的需要,本文闡述了使用DDR 控制器IP 核來(lái)設(shè)計(jì)實(shí)現(xiàn)DDR內(nèi)存接口的方法。該方法能使設(shè)計(jì)盡可能簡(jiǎn)單,設(shè)計(jì)者更專(zhuān)注于關(guān)鍵邏輯設(shè)計(jì),以便達(dá)到
    發(fā)表于 08-11 09:42 ?21次下載

    Android應(yīng)用程序內(nèi)存泄漏的原因及規(guī)避方法

    引言 Android應(yīng)用程序中內(nèi)存使用的問(wèn)題經(jīng)常容易被忽視,在傳統(tǒng)的編程語(yǔ)言中(例如C語(yǔ)言),回收內(nèi)存的任務(wù)是由程序本身來(lái)完成的,程序可以顯式分配和釋放變量所占用
    發(fā)表于 10-19 14:52 ?0次下載
    <b class='flag-5'>Android</b>應(yīng)用程序<b class='flag-5'>內(nèi)存</b>泄漏的原因及規(guī)避方法

    基于Android系統(tǒng)的高效內(nèi)存方法解析

    在做內(nèi)存優(yōu)化的時(shí)候,我們發(fā)現(xiàn)除了解決內(nèi)存泄露問(wèn)題,剩下的就只有想辦法減少真實(shí)的內(nèi)存占用。而在App中,大部分內(nèi)存
    發(fā)表于 06-05 20:23 ?1168次閱讀

    設(shè)計(jì)全定制ASIC以占用盡可能多的硅面積變得越來(lái)越具有挑戰(zhàn)性

    “設(shè)計(jì)重用”是將高質(zhì)量知識(shí)產(chǎn)權(quán)(IP)從一種ASIC設(shè)計(jì)遷移到另一種ASIC設(shè)計(jì)的過(guò)程。隨著半導(dǎo)體技術(shù)的巨大進(jìn)步,越來(lái)越難以彌合技術(shù)提供與硅生產(chǎn)率允許之間的生產(chǎn)率差距。設(shè)計(jì)全定制ASIC以占用盡可能
    的頭像 發(fā)表于 08-13 17:02 ?1849次閱讀

    Java服務(wù)器內(nèi)存和CPU占用過(guò)高的原因

    造成服務(wù)器內(nèi)存占用過(guò)高只有兩種情況:內(nèi)存溢出或內(nèi)存泄漏
    的頭像 發(fā)表于 03-21 15:50 ?2.2w次閱讀

    電腦內(nèi)存占用過(guò)高加內(nèi)存條起作用嗎

    電腦內(nèi)存占用過(guò)高加內(nèi)存條有用。內(nèi)存容量小是內(nèi)容占用過(guò)高的其中一個(gè)原因,所以加內(nèi)存條可以解決問(wèn)題;
    發(fā)表于 06-16 10:25 ?6678次閱讀

    更低內(nèi)存占用的通用Json庫(kù)-RyanJson

    RyanJson是一個(gè)小巧的c語(yǔ)言json解析器,包含json文本文件解析 / 生成,專(zhuān)門(mén)針對(duì)內(nèi)存占用進(jìn)行優(yōu)化,相比cJSON內(nèi)存占用減少30% - 60%,運(yùn)行速度和cJSON差不多
    的頭像 發(fā)表于 08-24 17:23 ?1706次閱讀
    更低<b class='flag-5'>內(nèi)存</b><b class='flag-5'>占用</b>的通用Json庫(kù)-RyanJson

    Windows不明內(nèi)存占用案例分析:Driver Locked

    前一段有客戶(hù)反映Windows系統(tǒng)下不明內(nèi)存占用越來(lái)越多,128GB物理內(nèi)存的主機(jī),啟動(dòng)完成后就有大約一半的內(nèi)存占用,導(dǎo)致留給應(yīng)用的
    的頭像 發(fā)表于 09-25 14:49 ?1938次閱讀
    Windows不明<b class='flag-5'>內(nèi)存</b><b class='flag-5'>占用</b>案例分析:Driver Locked