導航:首頁 > 源碼編譯 > bitmap演算法java

bitmap演算法java

發布時間:2022-07-05 13:08:53

A. 在android開發中,有哪些好的內存優化方式

可以考慮使用ArrayMap/SparseArray而不是HashMap等傳統數據結構。通常的HashMap的實現方式更加消耗內存,因為它需要一個額外的實例對象來記錄Mapping操作。另外,SparseArray更加高效,在於他們避免了對key與value的自動裝箱(autoboxing),並且避免了裝箱後的解箱。
2. 避免在Android裡面使用Enum
Android官方培訓課程提到過「Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android.」,具體原理請參考《Android性能優化典範(三)》,所以請避免在Android裡面使用到枚舉。
3. 減小Bitmap對象的內存佔用
Bitmap是一個極容易消耗內存的大胖子,減小創建出來的Bitmap的內存佔用可謂是重中之重,,通常來說有以下2個措施:
inSampleSize:縮放比例,在把圖片載入內存之前,我們需要先計算出一個合適的縮放比例,避免不必要的大圖載入。
decode format:解碼格式,選擇ARGB_8888/RBG_565/ARGB_4444/ALPHA_8,存在很大差異
4.Bitmap對象的復用
縮小Bitmap的同時,也需要提高BitMap對象的復用率,避免頻繁創建BitMap對象,復用的方法有以下2個措施
LRUCache : 「最近最少使用演算法」在Android中有極其普遍的應用。ListView與GridView等顯示大量圖片的控制項里,就是使用LRU的機制來緩存處理好的Bitmap,把近期最少使用的數據從緩存中移除,保留使用最頻繁的數據,
inBitMap高級特性:利用inBitmap的高級特性提高Android系統在Bitmap分配與釋放執行效率。使用inBitmap屬性可以告知Bitmap解碼器去嘗試使用已經存在的內存區域,新解碼的Bitmap會嘗試去使用之前那張Bitmap在Heap中所佔據的pixel data內存區域,而不是去問內存重新申請一塊區域來存放Bitmap。利用這種特性,即使是上千張的圖片,也只會僅僅只需要佔用屏幕所能夠顯示的圖片數量的內存大小
4. 使用更小的圖片
在涉及給到資源圖片時,我們需要特別留意這張圖片是否存在可以壓縮的空間,是否可以使用更小的圖片。盡量使用更小的圖片不僅可以減少內存的使用,還能避免出現大量的InflationException。假設有一張很大的圖片被XML文件直接引用,很有可能在初始化視圖時會因為內存不足而發生InflationException,這個問題的根本原因其實是發生了OOM。

5.StringBuilder
在有些時候,代碼中會需要使用到大量的字元串拼接的操作,這種時候有必要考慮使用StringBuilder來替代頻繁的「+」。
6.避免在onDraw方法裡面執行對象的創建
類似onDraw等頻繁調用的方法,一定需要注意避免在這里做創建對象的操作,因為他會迅速增加內存的使用,而且很容易引起頻繁的gc,甚至是內存抖動。
7. 避免對象的內存泄露
類的靜態變數持有大數據對象
靜態變數長期維持到大數據對象的引用,阻止垃圾回收。
非靜態內部類存在靜態實例
非靜態內部類會維持一個到外部類實例的引用,如果非靜態內部類的實例是靜態的,就會間接長期維持著外部類的引用,阻止被回收掉。
資源對象未關閉
資源性對象比如(Cursor,File文件等)往往都用了一些緩沖,我們在不使用的時候,應該及時關閉它們, 以便它們的緩沖及時回收內存。它們的緩沖不僅存在於java虛擬機內,還存在於java虛擬機外。 如果我們僅僅是把它的引用設置為null,而不關閉它們,往往會造成內存泄露。
解決辦法: 比如SQLiteCursor(在析構函數finalize(),如果我們沒有關閉它,它自己會調close()關閉), 如果我們沒有關閉它,系統在回收它時也會關閉它,但是這樣的效率太低了。 因此對於資源性對象在不使用的時候,應該調用它的close()函數,將其關閉掉,然後才置為null. 在我們的程序退出時一定要確保我們的資源性對象已經關閉。 程序中經常會進行查詢資料庫的操作,但是經常會有使用完畢Cursor後沒有關閉的情況。如果我們的查詢結果集比較小, 對內存的消耗不容易被發現,只有在常時間大量操作的情況下才會復現內存問題,這樣就會給以後的測試和問題排查帶來困難和風險,記得try catch後,在finally方法中關閉連接
Handler內存泄漏
Handler作為內部類存在於Activity中,但是Handler生命周期與Activity生命周期往往並不是相同的,比如當Handler對象有Message在排隊,則無法釋放,進而導致本該釋放的Acitivity也沒有辦法進行回收。

B. 怎麼把圖片壓縮到100K以內呀

將圖片壓縮到100k以內的方法如下:

首先打開計算機,在計算機內打開PS,然後在PS界面內找到」打開「選項並使用滑鼠單擊打開需要壓縮的圖片。然後在界面內找到」圖像「選項並單擊,再在彈出的選項欄內找到」圖像大小「選項並使用滑鼠單擊打開。

然後在彈出的界面內找到寬度和高度並將它們設置為100即可成功將圖片壓縮到100k以內。

文件格式

BMP格式

點陣圖(外語簡稱:BMP、外語全稱:Bitmap),它是Windows操作系統中的標准圖像文件格式,能夠被多種Windows應用程序所支持。隨著Windows操作系統的流行與豐富的Windows應用程序的開發,BMP點陣圖格式理所當然地被廣泛應用。

這種格式的特點是包含的圖像信息較豐富,幾乎不進行壓縮,但由此導致了它與生俱來的缺點——佔用磁碟空間過大,所以,BMP在單機上比較流行。

GIF格式

圖形交換格式(外語簡稱:GIF、外語全稱:Graphics Interchange Format),美國一家著名的在線信息服務機構CompuServe針對當時網路傳輸帶寬的限制,開發出了這種GIF圖像格式。

GIF格式的特點是壓縮比高,磁碟空間佔用較少,所以這種圖像格式迅速得到了廣泛的應用。最初的GIF只是簡單地用來存儲單幅靜止圖像(稱為GIF87a),後來隨著技術發展,可以同時存儲若干幅靜止圖像進而形成連續的動畫。

使之成為當時支持2D動畫為數不多的格式之一(稱為GIF89a),而在GIF89a圖像中可指定透明區域,使圖像具有非同一般的顯示效果,這更使GIF風光十足。在Internet上大量採用的彩色動畫文件多為這種格式的文件,也稱為GIF89a格式文件。

此外,考慮到網路傳輸中的實際情況,GIF圖像格式還增加了漸顯方式,也就是說,在圖像傳輸過程中,用戶可以先看到圖像的大致輪廓,然後隨著傳輸過程的繼續而逐步看清圖像中的細節部分,從而適應了用戶「從朦朧到清楚」的觀賞心理。

以上內容參考:網路-圖片

C. 誰有java語言實現的bitmap馬賽克演算法,在線等哦,親哦,大神們哦!

木有,不知道怎麼搞

D. 如何高效使用和管理Bitmap

一、圖片載入流程

首先,我們談談載入圖片的流程,項目中的該模塊處理流程如下:

1.在UI主線程中,從內存緩存中獲取圖片,找到後返回。找不到進入下一步;

2.在工作線程中,從磁碟緩存中獲取圖片,找到即返回並更新內存緩存。找不到進入下一步;

3.在工作線程中,從網路中獲取圖片,找到即返回並同時更新內存緩存和磁碟緩存。找不到顯示默認以提示。

二、內存緩存類(PanoMemCache)


這里使用Android提供的LruCache類,該類保存一個強引用來限制內容數量,每當Item被訪問的時候,此Item就會移動到隊列的頭部。當cache已滿的時候加入新的item時,在隊列尾部的item會被回收。


[java] view plain print ?

public class PanoMemoryCache {

// LinkedHashMap初始容量

private static final int INITIAL_CAPACITY = 16;

// LinkedHashMap載入因子

private static final int LOAD_FACTOR = 0.75f;

// LinkedHashMap排序模式

private static final boolean ACCESS_ORDER = true;

// 軟引用緩存

private static LinkedHashMap<String, SoftReference<Bitmap>> mSoftCache;

// 硬引用緩存

private static LruCache<String, Bitmap> mLruCache;

public PanoMemoryCache() {

// 獲取單個進程可用內存的最大值

// 方式一:使用ActivityManager服務(計量單位為M)

/*int memClass = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();*/

// 方式二:使用Runtime類(計量單位為Byte)

final int memClass = (int) Runtime.getRuntime().maxMemory();

// 設置為可用內存的1/4(按Byte計算)

final int cacheSize = memClass / 4;

mLruCache = new LruCache<String, Bitmap>(cacheSize) {

@Override

protected int sizeOf(String key, Bitmap value) {

if(value != null) {

// 計算存儲bitmap所佔用的位元組數

return value.getRowBytes() * value.getHeight();

} else {

return 0;

}

}

@Override

protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) {

if(oldValue != null) {

// 當硬引用緩存容量已滿時,會使用LRU演算法將最近沒有被使用的圖片轉入軟引用緩存

mSoftCache.put(key, new SoftReference<Bitmap>(oldValue));

}

}

};

/*

* 第一個參數:初始容量(默認16)

* 第二個參數:載入因子(默認0.75)

* 第三個參數:排序模式(true:按訪問次數排序;false:按插入順序排序)

*/

mSoftCache = new LinkedHashMap<String, SoftReference<Bitmap>>(INITIAL_CAPACITY, LOAD_FACTOR, ACCESS_ORDER) {

private static final long serialVersionUID = 7237325113220820312L;

@Override

protected boolean removeEldestEntry(Entry<String, SoftReference<Bitmap>> eldest) {

if(size() > SOFT_CACHE_SIZE) {

return true;

}

return false;

}

};

}

/**

* 從緩存中獲取Bitmap

* @param url

* @return bitmap

*/

public Bitmap getBitmapFromMem(String url) {

Bitmap bitmap = null;

// 先從硬引用緩存中獲取

synchronized (mLruCache) {

bitmap = mLruCache.get(url);

if(bitmap != null) {

// 找到該Bitmap之後,將其移到LinkedHashMap的最前面,保證它在LRU演算法中將被最後刪除。

mLruCache.remove(url);

mLruCache.put(url, bitmap);

return bitmap;

}

}

// 再從軟引用緩存中獲取

synchronized (mSoftCache) {

SoftReference<Bitmap> bitmapReference = mSoftCache.get(url);

if(bitmapReference != null) {

bitmap = bitmapReference.get();

if(bitmap != null) {

// 找到該Bitmap之後,將它移到硬引用緩存。並從軟引用緩存中刪除。

mLruCache.put(url, bitmap);

mSoftCache.remove(url);

return bitmap;

} else {

mSoftCache.remove(url);

}

}

}

return null;

}

/**

* 添加Bitmap到內存緩存

* @param url

* @param bitmap

*/

public void addBitmapToCache(String url, Bitmap bitmap) {

if(bitmap != null) {

synchronized (mLruCache) {

mLruCache.put(url, bitmap);

}

}

}

/**

* 清理軟引用緩存

*/

public void clearCache() {

mSoftCache.clear();

mSoftCache = null;

}

}

補充一點,由於4.0平台以後對SoftReference類引用的對象調整了回收策略,所以該類中的軟引用緩存實際上沒什麼效果,可以去掉。2.3以前平台建議保留。

三、磁碟緩存類(PanoDiskCache)

五、使用decodeByteArray()還是decodeStream()?

講到這里,有童鞋可能會問我為什麼使用BitmapFactory.decodeByteArray(data, 0, data.length, opts)來創建Bitmap,而非使用BitmapFactory.decodeStream(is, null, opts)。你這樣做不是要多寫一個靜態方法readInputStream()嗎?

沒錯,decodeStream()確實是該使用情景下的首選方法,但是在有些情形下,它會導致圖片資源不能即時獲取,或者說圖片被它偷偷地緩存起來,交 還給我們的時間有點長。但是延遲性是致命的,我們等不起。所以在這里選用decodeByteArray()獲取,它直接從位元組數組中獲取,貼近於底層 IO、脫離平台限制、使用起來風險更小。

六、引入緩存機制後獲取圖片的方法

[java] view plain print ?

/**

* 載入Bitmap

* @param url

* @return

*/

private Bitmap loadBitmap(String url) {

// 從內存緩存中獲取,推薦在主UI線程中進行

Bitmap bitmap = memCache.getBitmapFromMem(url);

if(bitmap == null) {

// 從文件緩存中獲取,推薦在工作線程中進行

bitmap = diskCache.getBitmapFromDisk(url);

if(bitmap == null) {

// 從網路上獲取,不用推薦了吧,地球人都知道~_~

bitmap = PanoUtils.downloadBitmap(this, url);

if(bitmap != null) {

diskCache.addBitmapToCache(bitmap, url);

memCache.addBitmapToCache(url, bitmap);

}

} else {

memCache.addBitmapToCache(url, bitmap);

}

}

return bitmap;

}

七、工作線程池化

有關多線程的切換問題以及在UI線程中執行loadBitmap()方法無效的問題,請參見另一篇博文: 使用嚴苛模式打破Android4.0以上平台應用中UI主線程的「獨斷專行」。

有關工作線程的處理方式,這里推薦使用定製線程池的方式,核心代碼如下:

[java] view plain print ?

// 線程池初始容量

private static final int POOL_SIZE = 4;

private ExecutorService executorService;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// 獲取當前使用設備的CPU個數

int cpuNums = Runtime.getRuntime().availableProcessors();

// 預開啟線程池數目

executorService = Executors.newFixedThreadPool(cpuNums * POOL_SIZE);

...

executorService.submit(new Runnable() {

// 此處執行一些耗時工作,不要涉及UI工作。如果遇到,直接轉交UI主線程

pano.setImage(loadBitmap(url));

});

...

}

我們知道,線程構造也是比較耗資源的。一定要對其進行有效的管理和維護。千萬不要隨意而行,一張圖片的工作線程不搭理也許沒什麼,當使用場景變為 ListView和GridView時,線程池化工作就顯得尤為重要了。Android不是提供了AsyncTask嗎?為什麼不用它?其實 AsyncTask底層也是靠線程池支持的,它默認分配的線程數是128,是遠大於我們定製的executorService。

E. 如何解決bitmap 內存溢出out of memory的問題

android 中用bitmap 時很容易內存溢出,報如下錯誤:Java.lang.OutOfMemoryError : bitmap size exceeds VM budget
● 主要是加上這段:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
● eg1:(通過Uri取圖片)
private ImageView preview;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;//圖片寬高都為原來的二分之一,即圖片為原來的四分之一
Bitmap bitmap = BitmapFactory.decodeStream(cr
.openInputStream(uri), null, options);
preview.setImageBitmap(bitmap);
以上代碼可以優化內存溢出,但它只是改變圖片大小,並不能徹底解決內存溢出。
● eg2:(通過路徑去圖片)
private ImageView preview;
private String fileName= "/sdcard/DCIM/Camera/2010-05-14 16.01.44.jpg";
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;//圖片寬高都為原來的二分之一,即圖片為原來的四分之一
Bitmap b = BitmapFactory.decodeFile(fileName, options);
preview.setImageBitmap(b);
filePath.setText(fileName);
★Android 還有一些性能優化的方法:
● 首先內存方面,可以參考 Android堆內存也可自己定義大小 和 優化Dalvik虛擬機的堆內存分配
● 基礎類型上,因為Java沒有實際的指針,在敏感運算方面還是要藉助NDK來完成。Android123提示游戲開發者,這點比較有意思的是Google推出NDK可能是幫助游戲開發人員,比如OpenGL ES的支持有明顯的改觀,本地代碼操作圖形界面是很必要的。
● 圖形對象優化,這里要說的是Android上的Bitmap對象銷毀,可以藉助recycle()方法顯示讓GC回收一個Bitmap對象,通常對一個不用的Bitmap可以使用下面的方式,如
if(bitmapObject.isRecycled()==false) //如果沒有回收
bitmapObject.recycle();
● 目前系統對動畫支持比較弱智對於常規應用的補間過渡效果可以,但是對於游戲而言一般的美工可能習慣了GIF方式的統一處理,目前 Android系統僅能預覽GIF的第一幀,可以藉助J2ME中通過線程和自己寫解析器的方式來讀取GIF89格式的資源。
● 對於大多數Android手機沒有過多的物理按鍵可能我們需要想像下了做好手勢識別 GestureDetector 和重力感應來實現操控。通常我們還要考慮誤操作問題的降噪處理。
Android堆內存也可自己定義大小
對於一些大型Android項目或游戲來說在演算法處理上沒有問題外,影響性能瓶頸的主要是Android自己內存管理機制問題,目前手機廠商對RAM都比較吝嗇,對於軟體的流暢性來說RAM對性能的影響十分敏感,除了上次Android開發網提到的 優化Dalvik虛擬機的堆內存分配外,我們還可以強制定義自己軟體的對內存大小,我們使用Dalvik提供的 dalvik.system.VMRuntime類來設置最小堆內存為例:
private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ;
VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE); //設置最小heap內存為6MB大小。當然對於內存吃緊來說還可以通過手動干涉GC去處理,我們將在下次提到具體應用。
優化Dalvik虛擬機的堆內存分配
對於Android平台來說,其託管層使用的Dalvik JavaVM從目前的表現來看還有很多地方可以優化處理,比如我們在開發一些大型游戲或耗資源的應用中可能考慮手動干涉GC處理,使用 dalvik.system.VMRuntime類提供的setTargetHeapUtilization方法可以增強程序堆內存的處理效率。當然具體原理我們可以參考開源工程,這里我們僅說下使用方法: private final static floatTARGET_HEAP_UTILIZATION = 0.75f; 在程序onCreate時就可以調用 VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION); 即可。

F. 安卓編程用什麼軟體

一:Java SE 編程
Java 是一種面向對象的開發語言,Android操作系統的應用層使用Java語言來開發,所以要想進行Android開發必須有良好的Java基礎。這一階段的學習,要牢固掌握Java 中的基本語法,掌握面向對象的程序設計思想,及開發工具的使用。之後學習常用類,多線程等高級特性,學習Java網路編程,了解網路通訊結構,掌握資料庫語言及JDBC對資料庫的訪問,了解數據結構與演算法,設計模式,項目開發工具的使用等內容。為後續的學習打一夯實的基礎。
二:Android 基礎應用開發
這一階段的學習主要是掌握Android的系統架構,熟悉整個android開發環境的搭建,以及的常用命令和工具的使用,熟練掌握Andoid的UI開發,包括使用標准控制項,以及自定義各式各樣的UI控制項,配合動畫部分的使用,讓自己UI設計更加炫麗更加吸引。最後在自己的應用中植入廣告,發布到Market中,享受掙錢的樂趣。
三:Android 核心組件開發
精通Android應用開發核心組件的使用,包括Acitivity窗口活動管理;連接各個組件起到通訊作用的Intent信使;存在於服務端不可見的Service組件;為數據提供共享的ContentProvider;之後要掌握Andorid中很實用的數據存儲,以及復習Java中的網路技術,並將它結合到android的開發當中,特別是常用的http通信,以及XML,Json數據的解析。中間通過不同項目讓我們去強化該部分的知識。
四:Android 深入開發
通過前面的三個階段的學習,這一階段主要是把前面的內容作為基礎,結合一些實際的應用,讓Android開發更加多樣化,當然需要一些練習了,不妨可以嘗試一下多媒體方面,如:音視頻播放,照相機,鬧鍾等;常用設備方面,如:GPS,重力感測器,指南針等;還有基本的Android圖形開發,繪制自己的View部件以及通過Bitmap對圖片作一些處理。然後在此基礎之上,學習高級的游戲開發引擎,2D,3D的圖形處理。

G. 如何將Bitmap點陣圖與base64字元串相互轉換

無論要對圖片,還是mp3,還是電影文件,本質都是2進制串。所以你缺的不是點陣圖到base64字元串的轉換,而是一套Base64編碼解碼演算法。
不清楚你的語言,以java為例。jdk1.8之前有api:Base64Encoder,Base64Decoder分別編碼/解碼。1.8除了更加厲害的 「Base64」。當然可以搜索各種各樣的第三方jar包羅。
對於你這個文件處理需求,推薦這個:http://download.csdn.net/download/liuzhao2011/9963611。下載後,將java文件考項目中,調好包路徑即可。大文件處理速度快,可以直接輸出編碼後的文件(代碼中有例子)。使用方便無痛苦。

H. 怎麼防止imagecreatefromjpeg內存溢出

盡量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource來設置一張大圖,
因為這些函數在完成decode後,最終都是通過java層的createBitmap來完成的,需要消耗更多內存。

因此,改用先通過BitmapFactory.decodeStream方法,創建出一個bitmap,再將其設為ImageView的 source,
decodeStream最大的秘密在於其直接調用JNI>>nativeDecodeAsset()來完成decode,
無需再使用java層的createBitmap,從而節省了java層的空間。
如果在讀取時加上圖片的Config參數,可以跟有效減少載入的內存,從而跟有效阻止拋out of Memory異常
另外,decodeStream直接拿的圖片來讀取位元組碼了, 不會根據機器的各種解析度來自動適應,
使用了decodeStream之後,需要在hdpi和mdpi,ldpi中配置相應的圖片資源,
否則在不同解析度機器上都是同樣大小(像素點數量),顯示出來的大小就不對了。

另外,以下方式也大有幫助:
1. InputStream is = this.getResources().openRawResource(R.drawable.pic1);
BitmapFactory.Options options=new BitmapFactory.Options();
options.inJustDecodeBounds = false;
options.inSampleSize = 10; //width,hight設為原來的十分一
Bitmap btp =BitmapFactory.decodeStream(is,null,options);
2. if(!bmp.isRecycle() ){
bmp.recycle() //回收圖片所佔的內存
system.gc() //提醒系統及時回收
}

以下奉上一個方法:

Java代碼

1. /**
2. * 以最省內存的方式讀取本地資源的圖片
3. * @param context
4. * @param resId
5. * @return
6. */
7. public static Bitmap readBitMap(Context context, int resId){
8. BitmapFactory.Options opt = new BitmapFactory.Options();
9. opt.inPreferredConfig = Bitmap.Config.RGB_565;
10. opt.inPurgeable = true;
11. opt.inInputShareable = true;
12. //獲取資源圖片
13. InputStream is = context.getResources().openRawResource(resId);
14. return BitmapFactory.decodeStream(is,null,opt);
15. }

================================================================================
Android內存溢出的解決辦法

轉自:http://www.cppblog.com/iuranus/archive/2010/11/15/124394.html?opt=admin

昨天在模擬器上給gallery放入圖片的時候,出現java.lang.OutOfMemoryError: bitmap size exceeds VM budget 異常,圖像大小超過了RAM內存。
模擬器RAM比較小,只有8M內存,當我放入的大量的圖片(每個100多K左右),就出現上面的原因。
由於每張圖片先前是壓縮的情況,放入到Bitmap的時候,大小會變大,導致超出RAM內存,具體解決辦法如下:

//解決載入圖片 內存溢出的問題
//Options 只保存圖片尺寸大小,不保存圖片到內存
BitmapFactory.Options opts = new BitmapFactory.Options();
//縮放的比例,縮放是很難按准備的比例進行縮放的,其值表明縮放的倍數,SDK中建議其值是2的指數值,值越大會導致圖片不清晰
opts.inSampleSize = 4;
Bitmap bmp = null;
bmp = BitmapFactory.decodeResource(getResources(), mImageIds[position],opts);

...

//回收
bmp.recycle();

通過上面的方式解決了,但是這並不是最完美的解決方式。

通過一些了解,得知如下:

優化Dalvik虛擬機的堆內存分配

對於Android平台來說,其託管層使用的Dalvik Java VM從目前的表現來看還有很多地方可以優化處理,比如我們在開發一些大型游戲或耗資源的應用中可能考慮手動干涉GC處理,使用 dalvik.system.VMRuntime類提供的setTargetHeapUtilization方法可以增強程序堆內存的處理效率。當然具體原理我們可以參考開源工程,這里我們僅說下使用方法: private final static float TARGET_HEAP_UTILIZATION = 0.75f; 在程序onCreate時就可以調用 VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION); 即可。

Android堆內存也可自己定義大小

對於一些Android項目,影響性能瓶頸的主要是Android自己內存管理機制問題,目前手機廠商對RAM都比較吝嗇,對於軟體的流暢性來說RAM對性能的影響十分敏感,除了 優化Dalvik虛擬機的堆內存分配外,我們還可以強制定義自己軟體的對內存大小,我們使用Dalvik提供的 dalvik.system.VMRuntime類來設置最小堆內存為例:

private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ;

VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE); //設置最小heap內存為6MB大小。當然對於內存吃緊來說還可以通過手動干涉GC去處理

bitmap 設置圖片尺寸,避免 內存溢出 OutOfMemoryError的優化方法
★android 中用bitmap 時很容易內存溢出,報如下錯誤:Java.lang.OutOfMemoryError : bitmap size exceeds VM budget

● 主要是加上這段:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;

● eg1:(通過Uri取圖片)
private ImageView preview;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;//圖片寬高都為原來的二分之一,即圖片為原來的四分之一
Bitmap bitmap = BitmapFactory.decodeStream(cr
.openInputStream(uri), null, options);
preview.setImageBitmap(bitmap);
以上代碼可以優化內存溢出,但它只是改變圖片大小,並不能徹底解決內存溢出。
● eg2:(通過路徑去圖片)
private ImageView preview;
private String fileName= "/sdcard/DCIM/Camera/2010-05-14 16.01.44.jpg";
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;//圖片寬高都為原來的二分之一,即圖片為原來的四分之一
Bitmap b = BitmapFactory.decodeFile(fileName, options);
preview.setImageBitmap(b);
filePath.setText(fileName);

★Android 還有一些性能優化的方法:
● 首先內存方面,可以參考 Android堆內存也可自己定義大小 和 優化Dalvik虛擬機的堆內存分配

● 基礎類型上,因為Java沒有實際的指針,在敏感運算方面還是要藉助NDK來完成。Android123提示游戲開發者,這點比較有意思的是Google 推出NDK可能是幫助游戲開發人員,比如OpenGL ES的支持有明顯的改觀,本地代碼操作圖形界面是很必要的。

● 圖形對象優化,這里要說的是Android上的Bitmap對象銷毀,可以藉助recycle()方法顯示讓GC回收一個Bitmap對象,通常對一個不用的Bitmap可以使用下面的方式,如

if(bitmapObject.isRecycled()==false) //如果沒有回收
bitmapObject.recycle();

● 目前系統對動畫支持比較弱智對於常規應用的補間過渡效果可以,但是對於游戲而言一般的美工可能習慣了GIF方式的統一處理,目前Android系統僅能預覽GIF的第一幀,可以藉助J2ME中通過線程和自己寫解析器的方式來讀取GIF89格式的資源。

● 對於大多數Android手機沒有過多的物理按鍵可能我們需要想像下了做好手勢識別 GestureDetector 和重力感應來實現操控。通常我們還要考慮誤操作問題的降噪處理。

Android堆內存也可自己定義大小

對於一些大型Android項目或游戲來說在演算法處理上沒有問題外,影響性能瓶頸的主要是Android自己內存管理機制問題,目前手機廠商對RAM都比較吝嗇,對於軟體的流暢性來說RAM對性能的影響十分敏感,除了上次Android開發網提到的優化Dalvik虛擬機的堆內存分配外,我們還可以強制定義自己軟體的對內存大小,我們使用Dalvik提供的 dalvik.system.VMRuntime類來設置最小堆內存為例:

private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ;

VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE); //設置最小heap內存為6MB大小。當然對於內存吃緊來說還可以通過手動干涉GC去處理,我們將在下次提到具體應用。

優化Dalvik虛擬機的堆內存分配

對於Android平台來說,其託管層使用的Dalvik JavaVM從目前的表現來看還有很多地方可以優化處理,比如我們在開發一些大型游戲或耗資源的應用中可能考慮手動干涉GC處理,使用 dalvik.system.VMRuntime類提供的setTargetHeapUtilization方法可以增強程序堆內存的處理效率。當然具體原理我們可以參考開源工程,這里我們僅說下使用方法: private final static floatTARGET_HEAP_UTILIZATION = 0.75f; 在程序onCreate時就可以調用 VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION); 即可。

介紹一下圖片佔用進程的內存演算法吧。
android中處理圖片的基礎類是Bitmap,顧名思義,就是點陣圖。佔用內存的演算法如下:
圖片的width*height*Config。
如果Config設置為ARGB_8888,那麼上面的Config就是4。一張480*320的圖片佔用的內存就是480*320*4 byte。
前面有人說了一下8M的概念,其實是在默認情況下android進程的內存佔用量為16M,因為Bitmap他除了java中持有數據外,底層C++的 skia圖形庫還會持有一個SKBitmap對象,因此一般圖片佔用內存推薦大小應該不超過8M。這個可以調整,編譯源代碼時可以設置參數。

I. bitmapfactory.decodefile是耗時操作嗎

android 中用bitmap 時很容易內存溢出,報如下錯誤:Java.lang.OutOfMemoryError : bitmap size exceeds VM budget ● 主要是加上這段: BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2; ● eg1:(通過Uri取圖片) private ImageView preview; BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2;//圖片寬高都為原來的二分之一,即圖片為原來的四分之一 Bitmap bitmap = BitmapFactory.decodeStream(cr .openInputStream(uri), null, options); preview.setImageBitmap(bitmap); 以上代碼可以優化內存溢出,但它只是改變圖片大小,並不能徹底解決內存溢出。 ● eg2:(通過路徑去圖片) private ImageView preview; private String fileName= "/sdcard/DCIM/Camera/2010-05-14 16.01.44.jpg"; BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2;//圖片寬高都為原來的二分之一,即圖片為原來的四分之一 Bitmap b = BitmapFactory.decodeFile(fileName, options); preview.setImageBitmap(b); filePath.setText(fileName); ★Android 還有一些性能優化的方法: ● 首先內存方面,可以參考 Android堆內存也可自己定義大小 和 優化Dalvik虛擬機的堆內存分配 ● 基礎類型上,因為Java沒有實際的指針,在敏感運算方面還是要藉助NDK來完成。Android123提示游戲開發者,這點比較有意思的是Google推出NDK可能是幫助游戲開發人員,比如OpenGL ES的支持有明顯的改觀,本地代碼操作圖形界面是很必要的。 ● 圖形對象優化,這里要說的是Android上的Bitmap對象銷毀,可以藉助recycle()方法顯示讓GC回收一個Bitmap對象,通常對一個不用的Bitmap可以使用下面的方式,如 if(bitmapObject.isRecycled()==false) //如果沒有回收 bitmapObject.recycle(); ● 目前系統對動畫支持比較弱智對於常規應用的補間過渡效果可以,但是對於游戲而言一般的美工可能習慣了GIF方式的統一處理,目前 Android系統僅能預覽GIF的第一幀,可以藉助J2ME中通過線程和自己寫解析器的方式來讀取GIF89格式的資源。 ● 對於大多數Android手機沒有過多的物理按鍵可能我們需要想像下了做好手勢識別 GestureDetector 和重力感應來實現操控。通常我們還要考慮誤操作問題的降噪處理。 Android堆內存也可自己定義大小 對於一些大型Android項目或游戲來說在演算法處理上沒有問題外,影響性能瓶頸的主要是Android自己內存管理機制問題,目前手機廠商對RAM都比較吝嗇,對於軟體的流暢性來說RAM對性能的影響十分敏感,除了上次Android開發網提到的 優化Dalvik虛擬機的堆內存分配外,我們還可以強制定義自己軟體的對內存大小,我們使用Dalvik提供的 dalvik.system.VMRuntime類來設置最小堆內存為例: private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ; VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE); //設置最小heap內存為6MB大小。當然對於內存吃緊來說還可以通過手動干涉GC去處理,我們將在下次提到具體應用。 優化Dalvik虛擬機的堆內存分配 對於Android平台來說,其託管層使用的Dalvik JavaVM從目前的表現來看還有很多地方可以優化處理,比如我們在開發一些大型游戲或耗資源的應用中可能考慮手動干涉GC處理,使用 dalvik.system.VMRuntime類提供的setTargetHeapUtilization方法可以增強程序堆內存的處理效率。當然具體原理我們可以參考開源工程,這里我們僅說下使用方法: private final static floatTARGET_HEAP_UTILIZATION = 0.75f; 在程序onCreate時就可以調用 VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION); 即可。

閱讀全文

與bitmap演算法java相關的資料

熱點內容
噴油螺桿製冷壓縮機 瀏覽:579
python員工信息登記表 瀏覽:377
高中美術pdf 瀏覽:161
java實現排列 瀏覽:513
javavector的用法 瀏覽:982
osi實現加密的三層 瀏覽:233
大眾寶來原廠中控如何安裝app 瀏覽:916
linux內核根文件系統 瀏覽:243
3d的命令面板不見了 瀏覽:526
武漢理工大學伺服器ip地址 瀏覽:149
亞馬遜雲伺服器登錄 瀏覽:525
安卓手機如何進行文件處理 瀏覽:71
mysql執行系統命令 瀏覽:930
php支持curlhttps 瀏覽:143
新預演算法責任 瀏覽:444
伺服器如何處理5萬人同時在線 瀏覽:251
哈夫曼編碼數據壓縮 瀏覽:426
鎖定伺服器是什麼意思 瀏覽:385
場景檢測演算法 瀏覽:617
解壓手機軟體觸屏 瀏覽:350