日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

bitmap设置图片尺寸缩小,避免内存溢出/OutOfMemoryError的优化方法

發(fā)布時間:2024/9/20 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 bitmap设置图片尺寸缩小,避免内存溢出/OutOfMemoryError的优化方法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

2019獨角獸企業(yè)重金招聘Python工程師標準>>>

我們都知道Android的Dalvik VM為一個應用提供了大約16MB的內存,一般我們處理超過8MB的圖片將會出現(xiàn)OutOfMemoryError異常(內存溢出異常),報如下錯誤:

?

20155392-byte external allocation too large for this process.

VM won't let us allocate 20155392 bytes

?
Java.lang.OutOfMemoryError : bitmap size exceeds VM budget????

?

Java代碼?
  • FileInputStream?in; ??
  • in?=?new?FileInputStream(path); ??
  • byte[]?buffer?=?new?byte[1024]; ??
  • ByteArrayOutputStream?out?=?new?ByteArrayOutputStream(); ??
  • int?len?=?0; ??
  • while?((len?=?in.read(buffer))?!=?-1)?{ ??
  • ????out.write(buffer,?0,?len); ??
  • } ??
  • imageData?=?out.toByteArray(); ??
  • Bitmap?bitMap?=?BitmapFactory.decodeByteArray(imageData,?0,imageData.length);
  • ?以上是第一次開始寫瀏覽圖片,只看到decodeByteArray方法就直接把從SD卡獲取圖片路徑轉換為byte[]然后再賦給Bitmap,原來還有一個直接從路徑獲取Bitmap的方法:

    Java代碼?
  • Bitmap?bitMap?=?BitmapFactory.decodeByteArray(paht)?;?
  • ?

    但由于需要顯示的圖片太大,預覽圖片就提示內存溢出(但找到資料說處理超過8MB的圖片將會出現(xiàn)OutOfMemoryError異常,開始第一段話),不過我顯示的圖片為4M也出現(xiàn)

    ?

    20155392-byte external allocation too large for this process.

    VM won't let us allocate 20155392 bytes

    ?

    可能是?20155392算出來大概19M的大少,可能超出了分配給程序的16M大少

    ?

    我們解碼(預覽顯示)一個圖片為了防止內存不足的異常我們可以使用BitmapFactory.Options?的屬性解決,代碼如下:

    ?

    1、通過路徑獲取圖片

    Java代碼? ?
  • ImageView?imageView=(ImageView)findViewById(R.id.image);??
  • BitmapFactory.Options?options?=?new?BitmapFactory.Options();??
  • options.inSampleSize=2;//圖片高寬度都為原來的二分之一,即圖片大小為原來的大小的四分之一??
  • options.inTempStorage?=?new?byte[5*1024];?//設置16MB的臨時存儲空間(不過作用還沒看出來,待驗證)??
  • Bitmap?bitMap?=?BitmapFactory.decodeFile(文件路徑,?options);???
  • imageView.setImageBitmap(bitMap);??
  • ??

    ?

    2、通過Uri取圖片

    ?

    Java代碼? ?
  • Bitmap?bitmap?=?BitmapFactory.decodeStream(cr.openInputStream(uri),?null,?options);???
  • 以上代碼可以優(yōu)化內存溢出,但它只是改變圖片大小,并不能徹底解決內存溢出。

    ?

    ?

    ?

    以下是網上找到的資料:

    ★Android 還有一些性能優(yōu)化的方法:

    ●? 首先內存方面,可以參考 Android堆內存也可自己定義大小 和 優(yōu)化Dalvik虛擬機的堆內存分配?
    ●? 基礎類型上,因為Java沒有實際的指針,在敏感運算方面還是要借助NDK來完成。這點比較有意思的是Google推出NDK可能是幫助游戲開發(fā)人員,比如OpenGL ES的支持有明顯的改觀,本地代碼操作圖形界面是很必要的。?
    ●? 圖形對象優(yōu)化,這里要說的是Android上的Bitmap對象銷毀,可以借助recycle()方法顯示讓GC回收一個Bitmap對象,通常對一個不用的Bitmap可以使用下面的方式,如?

    Java代碼? ?
  • if(bitmapObject.isRecycled()==false)?//如果沒有回收?????????
  • ?????????bitmapObject.recycle();???
  • ?●? 目前系統(tǒng)對動畫支持比較弱智對于常規(guī)應用的補間過渡效果可以,但是對于游戲而言一般的美工可能習慣了GIF方式的統(tǒng)一處理,目前 Android系統(tǒng)僅能預覽GIF的第一幀,可以借助J2ME中通過線程和自己寫解析器的方式來讀取GIF89格式的資源。?
    ● 對于大多數(shù)Android手機沒有過多的物理按鍵可能我們需要想象下了做好手勢識別 GestureDetector 和重力感應來實現(xiàn)操控。通常我們還要考慮誤操作問題的降噪處理。?
    Android堆內存也可自己定義大小?
    ?? 對于一些大型Android項目或游戲來說在算法處理上沒有問題外,影響性能瓶頸的主要是Android自己內存管理機制問題,目前手機廠商對RAM都比較吝嗇,對于軟件的流暢性來說RAM對性能的影響十分敏感,除了上次Android開發(fā)網提到的 優(yōu)化Dalvik虛擬機的堆內存分配外,我們還可以強制定義自己軟件的對內存大小,我們使用Dalvik提供的dalvik.system.VMRuntime類來設置最小堆內存為例:?

    Java代碼? ?
  • private?final?static?int?CWJ_HEAP_SIZE?=?6*?1024*?1024?;?????????
  • VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE);?//設置最小heap內存為6MB大小。??????
  • private?final?static?int?CWJ_HEAP_SIZE?=?6*?1024*?1024?;?VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE);?//設置最小heap內存為6MB大小。??
  • ?

    當然對于內存吃緊來說還可以通過手動干涉GC去處理,我們將在下次提到具體應用。?
    優(yōu)化Dalvik虛擬機的堆內存分配?
    對于Android平臺來說,其托管層使用的Dalvik JavaVM從目前的表現(xiàn)來看還有很多地方可以優(yōu)化處理,比如我們在開發(fā)一些大型游戲或耗資源的應用中可能考慮手動干涉GC處理,使用 dalvik.system.VMRuntime類提供的setTargetHeapUtilization方法可以增強程序堆內存的處理效率。當然具體原理我們可以參考開源工程,這里我們僅說下使用方法:??

    Java代碼? ?
  • private?final?static?floatTARGET_HEAP_UTILIZATION?=?0.75f;????????
  • private?final?static?floatTARGET_HEAP_UTILIZATION?=?0.75f;??
  • 在程序onCreate時就可以調用?

    Java代碼? ?
  • VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION);????????
  • VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION);???
  • ?android系統(tǒng)中讀取位圖Bitmap時.分給虛擬機中圖片的堆棧大小只有8M。所以不管是如何調用的圖片,太多太大虛擬機肯定會報那個錯誤。超出圖片內存預算那個錯誤.:java.lang.OutOfMemoryError: bitmap size exceeds VM budget?

    遇到這個問題是因為沒有回收資源.

    Java代碼? ?
  • public?void?distoryBitmap(){???????
  • ????if(null!=bmb&&!bmb.isRecycled())???????
  • ????????bmb.recycle();???????
  • 調用上面的代碼可以基本解決這個問題.但是千萬不要在view中的onDraw()中調用.因為onDraw()方法是系統(tǒng)循環(huán)調用.只要圖片打開,系統(tǒng)就不停的調用該方法.?

    最好的解決方案是在自定義的View中添加一個init()初始化方法的頭部調用.或者在構造函數(shù)的頂部調用。

    轉載于:https://my.oschina.net/kangchunhui/blog/73442

    總結

    以上是生活随笔為你收集整理的bitmap设置图片尺寸缩小,避免内存溢出/OutOfMemoryError的优化方法的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。