2011-01-28 66 views
20

感謝Schermvlieger詢問this問題上anddev.org速度優化使用BitmapFactory.Options.inSampleSize的

我只是複製他的問題,從而沒有人對對方回答網站,我也面臨同樣的問題。

我想知道什麼是BitmapFactory.Options.inSampleSize關於顯示圖像的速度的最佳使用。
說明文檔中提到使用是2的功率值,所以我用2,4,8,16等

我想知道的事情是工作:

  1. 我應該重新取樣下來到仍然大於屏幕分辨率的最小尺寸,或者我應該採樣到足夠大的尺寸以避免OutOfMemoryError
  2. 如何計算可以在內存不足的情況下仍可以顯示的圖像的最大尺寸?圖像的顏色深度是否也起作用以及顯示的深度?
  3. 通過兩種機制顯示圖像是否高效(大文件爲BitmapFactory,小文件爲setImageURI())順便說一句,我使用的是ImageSwitcher
  4. 它會幫助在應用程序的開始時創建Bitmap,BitmapFactory.OptionsinTempStorage,或者在需要時創建它們嗎?

回答

11

您應該總是嘗試加載和預先縮放圖像,以使它們儘可能接近其最終顯示的大小。在繪圖時縮放圖像非常昂貴,應該不惜一切代價避免。

考慮到圖像的內存成本,是的,顏色deptch起着非常重要的作用。 ALPHA_8格式的圖像使用每像素1字節,RGB_565或ARGB_4444中的圖像使用每像素2字節,而ARGB_8888中的圖像使用每像素4字節。顯示的深度根本不重要。你應該總是嘗試使用ARGB_8888以獲得最佳質量,但如果圖像不透明,565可以足夠好。

+0

當你說「在繪製時縮放圖像非常昂貴」,它是否包含options.inSampleSize? – kape123 2013-02-14 03:44:57

+0

inSampleSize用於在加載時縮放圖像,而不是在繪製時間。這是預分辨圖像的一種非常好的方法。 – 2013-02-14 17:51:23

3

在這裏你可以調用用戶定義的方法shrinkmehtod,實際上發送字符串文件的路徑和高度和寬度,以減少圖像的方法。

Bitmap bit=shrinkmethod(arrpath1[position], 100, 100); 


      //iv.setImageURI(Uri.parse(arrpath1[position])); 
      iv.setImageBitmap(bit); 

這是用戶定義的方法,以編程方式減少圖像的大小。

Bitmap shrinkmethod(String file,int width,int height){ 
     BitmapFactory.Options bitopt=new BitmapFactory.Options(); 
     bitopt.inJustDecodeBounds=true; 
     Bitmap bit=BitmapFactory.decodeFile(file, bitopt); 

     int h=(int) Math.ceil(bitopt.outHeight/(float)height); 
     int w=(int) Math.ceil(bitopt.outWidth/(float)width); 

     if(h>1 || w>1){ 
      if(h>w){ 
       bitopt.inSampleSize=h; 

      }else{ 
       bitopt.inSampleSize=w; 
      } 
     } 
     bitopt.inJustDecodeBounds=false; 
     bit=BitmapFactory.decodeFile(file, bitopt); 



     return bit; 

    } 

我希望這會幫助你減小尺寸。

4

您已經提出了很好的問題,但這一切取決於您的需求以及您使用的內存量。 我建議查看這個鏈接,瞭解關於位圖的許多提示:http://developer.android.com/training/displaying-bitmaps/index.html

總之,您應該考慮緩存,縮減採樣,並儘可能使用足夠好的位圖格式。

這裏是我的問題的答案:

  1. 爲什麼不能兩者兼而有之?如果您認爲可能存在OOM,請嘗試回收舊的未使用的位圖,然後再次檢查。

  2. 就可以計算出該位圖的(估計)大小:

    寬度×高度×bytesPerPixel

    其中bytesPerPixel通常是4或2(取決於位圖格式)。

  3. 從來沒有使用setImageURI,所以我不能幫你。我建議在後臺線程中下載圖像(使用asyncTask是一種方法),並在準備就緒時顯示它們。

  4. 如果只有少數你知道不會佔用很多內存,我想沒關係。我仍然認爲緩存可能會更好。