當前位置:首頁 » 安卓系統 » android圖片優化

android圖片優化

發布時間: 2023-03-03 20:08:12

A. Android 高效內存-圖片內存使用優化

內容整理自網路。

在做內存優化的時候,我們發現除了解決內存泄露問題,剩下的就只有想辦法減少真實的內存佔用。而在App中,大部分內存可能被我們圖片佔用了,所以減少圖片的內存佔用可以帶來直接的效果。本文就簡單介紹一張圖片到底佔用多少內存,我們先假設我們有一張圖片時** 600 * 800** 的,圖片佔用空間大小假設是** 100KB**。

圖片內存大小跟佔用空間大小有什麼關系?

佔用空間的大小不是圖片佔用內存的大小,一些初學者可能會誤解一下。佔用空間是在磁碟上佔用的空間,內存大小是載入到內存中佔用的內存大小。兩個只是單位是一樣的,本質不是一個概念。

一張圖片到底佔用多少內存呢?(ARGB_8888編碼)

1. 圖片佔用內存的計算公式: 圖片高度 * 圖片寬度 * 一個像素佔用的內存大小

2. 所以上面的圖片佔用內存是:**800 * 600 * 4 byte = 1875KB = 1.83M **

上面的計算公式中,為什麼是4byte呢?文章後面有總結哦

圖片所在目錄對內存的影響?

在Android中,圖片的存放目錄和手機的屏幕密度影響圖片最終的大小,舉個例子:

假設我們的圖片放到 xhdpi 目錄下,那麼我們本文中的圖片佔用的內存大小如下:

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

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

所以,計算圖片佔用內存大小的時候,要考慮圖片所在的目錄跟設備密度,這兩個因素其實影響的是圖片的高寬,android會對圖片進行拉升跟壓縮

總結

1. 圖片確實很佔用內存,內存優化先考慮圖片內存佔用;

2. 一定要避免使用大圖片,這就是.9圖很有用的原因之一;

3. 圖片的大小對內存的影響是正比關系;

4. 本文只是簡單的告知讀者怎麼計算圖片的內存大小。

大圖: 440 * 336    小圖: 220 * 168 資源目錄: xhdpi

小圖的高寬都是大圖的1/2-->小圖是原圖的1/4

界面效果:

測試設備: Coolpad   8676-M01   5.1   density=2.0

測試前准備操作: 同一款設備,設置圖片前後多次調用gc直到內存短時間內保持穩定不再變化

內存使用情況: 下圖依次是 初始內存,大圖內存,小圖內存

大圖佔用內存: 11.23 MB - 10.66 MB = 0.57 MB

小圖佔用內存: 10.81 MB - 10.66 MB = 0.15 MB

大圖小圖內存關系: 0.15 MB * 4 = 0.60 MB 約等於 0.57 MB (這是統計工具的誤差,理論上就是相等的)

同樣的方式在另外一台設備小米4c上得到的結果如下:

測試設備: Xiaomi   Mi-4c   V8.2.1.0.LXKCNDL   5.1.1   density=3.0

大圖佔用內存: 13.22 MB - 11.95 MB = 1.27 MB

小圖佔用內存: 12.27 MB - 11.95 MB = 0.32 MB

大圖小圖內存關系: 0.32 MB * 4 = 1.28 MB 約等於 1.27 MB

結論: 由此可見大圖比小圖佔用更多的內存,圖片大小(解析度)與佔用內存成正比關系

備註: 圖片在硬碟上佔用的磁碟空間大小,與在內存中佔用的內存大小完全不一樣,不是一個概念,不要混淆

根據上文中圖片大小與內存的關系,可以更加深刻的理解Android中.9圖片的作用,它不但能減少apk的體積,還能減少圖片佔用內存。

有些時候我們根本不需要圖片,而是自己繪制背景,可以在自定義View的onDraw中繪制背景,當然最方便的還是使用系統的Drawable,繪制部分交給系統去完成。

下面測試圖片與Drawable的內存佔用對比

原始圖片大小: 482 * 482

界面效果:

測試設備: Xiaomi   Mi-4c   V8.2.1.0.LXKCNDL   5.1.1

測試前准備操作: 同一款設備,設置背景前後多次調用gc直到內存短時間內保持穩定不再變化

內存使用情況: 下圖依次是 初始內存,使用圖片佔用的內存,使用Drawable佔用的內存,使用onDraw繪制佔用的內存

使用圖片佔用內存: 13.97 MB - 11.97 MB = 2.00 MB

使用Drawable佔用內存: 11.97 MB - 11.97 MB = 0.00 MB (不會是0,有誤差,只是很少)

使用onDraw繪制佔用內存: 11.98 MB - 11.97 MB = 0.01 MB

結論: 繪制背景,或者使用系統提供Drawable作為背景,會大大減少內存佔用

Drawable參考資料:

Drawable實戰解析:Android XML shape 標簽使用詳解(apk瘦身,減少內存好幫手)

Android GradientDrawable(shape標簽定義)靜態使用和動態使用(圓角,漸變實現)

「讓你的圖片最小化」一節中描述的方法:使用盡可能小的圖,使用.9,自己繪制背景或者使用Drawable來繪制背景

載入大圖片時需要對圖片進行壓縮,使用等比例壓縮方法直接在內存中處理圖片

這樣做要注意的是,圖片質量會變差,inSampleSize設置的值越大,圖片質量就越差。

有時候我們取得一張圖片,也許只是為了獲得這個圖片的一些信息,比如圖片的width、height等信息,不需要顯示到界面上,這個時候我們可以不把圖片載入到內存中。

由於Android外層是使用java,而底層使用的是C語言為圖片對象分配的內存空間。所以我們的外部雖然看起來釋放了,但里層卻並不一定完全釋放了,我們使用完圖片後最好再釋放掉里層的內存空間。

RGB(ARGB)

RGB色彩模式是工業界的一種顏色標准,是通過對紅(R)、綠(G)、藍(B)三個顏色通道的變化以及它們相互之間的疊加來得到各式各樣的顏色的,RGB即是代表紅、綠、藍三個通道的顏色,這個標准幾乎包括了人類視力所能感知的所有顏色,是目前運用最廣的顏色系統之一。在Android中還有包含透明度Alpha的顏色模型,即ARGB。

YUV

YUV,分為三個分量,「Y」表示明亮度(Luminance或Luma),也就是灰度值;而「U」和「V」 表示的則是色度(Chrominance或Chroma),作用是描述影像色彩及飽和度,用於指定像素的顏色。

YUV的原理是把亮度與色度分離,研究證明,人眼對亮度的敏感超過色度。利用這個原理,可以把色度信息減少一點,人眼也無法查覺這一點。

主要用於電視系統以及模擬視頻領域,它將亮度信息(Y)與色彩信息(UV)分離,沒有UV信息一樣可以顯示完整的圖像,只不過是黑白的,這樣的設計很好地解決了彩色電視機與黑白電視的兼容問題

YUV的存儲中與RGB格式最大不同在於,RGB格式每個點的數據是連繼保存在一起的。即R,G,B是前後不間隔的保存在2-4byte空間中。而YUV的數據中為了節約空間,U,V分量空間會減小。每一個點的Y分量獨立保存,但連續幾個點的U,V分量是保存在一起的,(反正人眼一般也看不出區別).這幾個點合起來稱為macro-pixel, 這種存儲格式稱為Packed格式。另外一種存儲格式是把一幅圖像中Y,U,V分別用三個獨立的數組表示。這種模式稱為planar模式。

CMYK
  CMYK也稱作印刷色彩模式,顧名思義就是用來印刷的。印刷四分色模式是彩色印刷時採用的一種套色模式,利用色料的三原色混色原理,加上黑色油墨,共計四種顏色混合疊加,形成所謂「全彩印刷」。四種標准顏色是:

CMYK和RGB相比有一個很大的不同:RGB模式是一種發光的色彩模式,你在一間黑暗的房間內仍然可以看見屏幕上的內容;CMYK是一種依靠反光的色彩模式,我們是怎樣閱讀報紙的內容呢?是由陽光或燈光照射到報紙上,再反射到我們的眼中,才看到內容。它需要有外界光源,如果你在黑暗房間內是無法閱讀報紙的。只要是在印刷品上看到的圖像,就是CMYK模式表現的。比如期刊、雜志、報紙、宣傳畫等,都是印刷出來的,那麼就是CMYK模式的了。

CMYK原色與疊加之後的顏色對比

在不考慮透明度的情況下,一個像素點的顏色值在計算機中的表示方法有以下3種:

在Java中,float類型的變數佔32位,int類型的變數佔32位,short和char類型的變數都在16位,因此可以看出,用浮點數表示法編碼一個像素的顏色,內存佔用量是96位即12位元組;而用24位整數表示法編碼,只要一個int類型變數,佔用4個位元組(高8位空著,低24位用於表示顏色);用16位整數表示法編碼,只要一個short類型變數,佔2個位元組;因此可以看出採用整數表示法編碼顏色值,可以大大節省內存,當然,顏色質量也會相對低一些。在Android中獲取Bitmap的時候一般也採用整型編碼。

回想一下Android的BitmapConfig類中,有ARGB_8888、ARGB_4444、RGB565等常量,現在可以知道它們分別代表了什麼含義。同時也可以計算一張圖片在內存中可能佔用的大小,比如採用ARGB_8888編碼載入一張1920 1200的圖片,大概就會佔用1920 1200*4/1024/1024=8.79MB的內存。

採用低內存佔用量的編碼方式,比如Bitmap.Config.ARGB_4444比Bitmap.Config.ARGB_8888更省內存;

1920 1200的圖片:*

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

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

在Android中,對圖片的使用一定要關注,大多數情況下,佔用內存多,OOM發生都是因為圖片資源使用不當。不要盲目加一個大圖到Android項目中,能使用.9進來使用,而且.9圖本身盡可能小,另外能使用繪制實現就不要加一個圖片資源。有些時候,在不影響用戶體驗的情況下,可以降低圖片素材質量,比如不需要透明度的就不要了,有些透明度用肉眼看不出來。

B. android 餅形圖的百分比和大於100%怎麼優化

應該是布局方面的問題吧,在xml文件的ImageView有個scaleType屬性應該可以解決你的問題 android:scaleType是控制圖片如何resized/moved來匹對ImageView的size。 ImageView.ScaleType / android:scaleType值的意義區別: CENTER /center 按圖片的原來size居中顯示,當圖片長/寬超過View的長/寬,則截取圖片的居中部分顯示 CENTER_CROP / centerCrop 按比例擴大圖片的size居中顯示,使得圖片長(寬)等於或大於View的長(寬) CENTER_INSIDE / centerInside 將圖片的內容完整居中顯示,通過按比例縮小或原來的size使得圖片長/寬等於或小於View的長/寬 FIT_CENTER / fitCenter 把圖片按比例擴大/縮小到View的寬度,居中顯示 FIT_END / fitEnd 把圖片按比例擴大/縮小到View的寬度,顯示在View的下部分...

C. 針對Android的性能優化集中哪些方面

一、概要:

本文主要以Android的渲染機制、UI優化、多線程的處理、緩存處理、電量優化以及代碼規范等幾方面來簡述Android的性能優化

二、渲染機制的優化:

大多數用戶感知到的卡頓等性能問題的最主要根源都是因為渲染性能。

Android系統每隔16ms發出VSYNC信號,觸發對UI進行渲染, 如果每次渲染都成功,這樣就能夠達到流暢的畫面所需要的60fps,為了能夠實現60fps,這意味著程序的大多數操作都必須在16ms內完成。

*關於JobScheler的更多知識可以參考http://hukai.me/android-training-course-in-chinese/background-jobs/scheling/index.html

七、代碼規范

1)for loop中不要聲明臨時變數,不到萬不得已不要在裡面寫try catch。

2)明白垃圾回收機制,避免頻繁GC,內存泄漏,OOM(有機會專門說)

3)合理使用數據類型,StringBuilder代替String,少用枚舉enum,少用父類聲明(List,Map)

4)如果你有頻繁的new線程,那最好通過線程池去execute它們,減少線程創建開銷。

5)你要知道單例的好處,並正確的使用它。

6)多用常量,少用顯式的"action_key",並維護一個常量類,別重復聲明這些常量。

7)如果可以,至少要弄懂設計模式中的策略模式,組合模式,裝飾模式,工廠模式,觀察者模式,這些能幫助你合理的解耦,即使需求頻繁變更,你也不用害怕牽一發而動全身。需求變更不可怕,可怕的是沒有在寫代碼之前做合理的設計。

8)View中設置緩存屬性.setDrawingCache為true.

9)cursor的使用。不過要注意管理好cursor,不要每次打開關閉cursor.因為打開關閉Cursor非常耗時。Cursor.require用於刷cursor.

10)採用SurfaceView在子線程刷新UI,避免手勢的處理和繪制在同一UI線程(普通View都這樣做)

11)採用JNI,將耗時間的處理放到c/c++層來處理

12)有些能用文件操作的,盡量採用文件操作,文件操作的速度比資料庫的操作要快10倍左右

13)懶載入和緩存機制。訪問網路的耗時操作啟動一個新線程來做,而不要再UI線程來做

14)如果方法用不到成員變數,可以把方法申明為static,性能會提高到15%到20%

15)避免使用getter/setter存取field,可以把field申明為public,直接訪問

16)私有內部類要訪問外部類的field或方法時,其成員變數不要用private,因為在編譯時會生成setter/getter,影響性能。可以把外部類的field或方法聲明為包訪問許可權

17)合理利用浮點數,浮點數比整型慢兩倍

18)針對ListView的性能優化,ListView的背景色與cacheColorHint設置相同顏色,可以提高滑動時的渲染性能。ListView中getView是性能是關鍵,這里要盡可能的優化。

getView方法中要重用view;getView方法中不能做復雜的邏輯計算,特別是資料庫操作,否則會嚴重影響滑動時的性能

19)不用new關鍵詞創建類的實例,用new關鍵詞創建類的實例時,構造函數鏈中的所有構造函數都會被自動調用。但如果一個對象實現了Cloneable介面,我們可以調用它的clone()方法。

clone()方法不會調用任何類構造函數。在使用設計模式(Design Pattern)的場合,如果用Factory模式創建對象,則改用clone()方法創建新的對象實例非常簡單。例如,下面是Factory模式的一個典型實現:

20)public static Credit getNewCredit() {
return new Credit();
}
改進後的代碼使用clone()方法,如下所示:
private static Credit BaseCredit = new Credit();
public static Credit getNewCredit() {
return (Credit) BaseCredit.clone();
}
上面的思路對於數組處理同樣很有用。

21)乘法和除法

考慮下面的代碼:

  • for (val = 0; val < 100000; val +=5) { alterX = val * 8; myResult = val * 2; }
    用移位操作替代乘法操作可以極大地提高性能。下面是修改後的代碼:
    for (val = 0; val < 100000; val += 5) { alterX = val << 3; myResult = val << 1; }

  • 22)ViewPager同時緩存page數最好為最小值3,如果過多,那麼第一次顯示時,ViewPager所初始化的pager就會很多,這樣pager累積渲染耗時就會增多,看起來就卡。

    23)每個pager應該只在顯示時才載入網路或資料庫(UserVisibleHint=true),最好不要預載入數據,以免造成浪費

    24)提高下載速度:要控制好同時下載的最大任務數,同時給InputStream再包一層緩沖流會更快(如BufferedInputStream)

    25)提供載入速度:讓服務端提供不同解析度的圖片才是最好的解決方案。還有合理使用內存緩存,使用開源的框架

    引用:Android性能優化的淺談

    D. Android性能優化(八)--Android圖片內存優化

    2個基本原則

    既然需要的內存公式已得到,那優化就顯而易見了,無非就是減小的這三個參數的值,具體的策略如下:
    這里我們將圖片分為2種情況來探討:

    圖片佔用的內存 大小為:

    為什麼mipmap不在這種情況的考慮范圍之內呢?
    因為mipmap是Android系統為了避免Launcher Icon變形而添加的資源目錄,也就是說,mipmap中的圖片不會被縮放。所以Google也不推薦將除Launcher Icon之外的圖片放在mipmap目錄中。

    本地圖片通常都是通過Android提供的BitmapFactory來載入的, 這里看幾個常用的API:

    圖片的優化可通過Options參數來實現(Options的介紹可參考 從fresco 看圖片優化 :

    inPreferredConfig的取值為Bitmap.Config類型(這里只考慮以下幾種情況),它是一個枚舉類型,用來設置每個像素需要的位元組數:

    1.jpeg和gif

    2.webp

    3.png8, png24, png32

    網路圖片通常我們都是使用開源庫進行載入, 所以不需要拿到Bitmap再進行縮放或裁剪。
    這時可讓後台實現網路圖片的裁剪,即:根據圖片的請求參數返回合適的尺寸,最大也只需要控制項的大小即可。
    再大也沒意義,不僅浪費流量,還佔用內存。
    如果你的APP中有很多圖片,那麼可對圖片的寬高根據設備的內存情況進行適當的縮小:

    盡量為所有解析度創建資源 資源匹配解析度 = 減少不必要的縮放,從而提高UI繪制效率

    對於一個多圖片的APP來說,圖片所佔內存的優化是一項必不可少的工作。
    總的來說,其優化也就是通過 縮放 和指定 Bitmap.Config的值 來實現的,只是不同位置,不同格式的圖片有所差異而已。

    https://juejin.im/post/5af84f4b51882542714fdaa9?utm_medium=an&utm_source=weixinqun

    熱點內容
    廣東人社賬號密碼多少 發布:2025-05-10 03:43:11 瀏覽:616
    python對象參數 發布:2025-05-10 03:43:11 瀏覽:575
    自己伺服器搭建梯子 發布:2025-05-10 03:31:39 瀏覽:573
    華為升級包怎麼解壓 發布:2025-05-10 03:18:24 瀏覽:603
    c語言以什麼結束 發布:2025-05-10 03:18:22 瀏覽:257
    160android 發布:2025-05-10 03:03:30 瀏覽:178
    pythonstorage 發布:2025-05-10 02:58:38 瀏覽:499
    如何查看電腦配置顯卡參數 發布:2025-05-10 02:37:00 瀏覽:106
    證券交易密碼在哪裡修改 發布:2025-05-10 02:31:56 瀏覽:839
    javafor是什麼意思 發布:2025-05-10 02:23:09 瀏覽:842