2012-08-02 41 views
0

通過以下this link,我編寫了以下代碼以顯示sdcard中的大圖像位圖。大型位圖無法從Android中的SD卡高效加載

try { 
    InputStream lStreamToImage = context.getContentResolver().openInputStream(Uri.parse(imagePath)); 
    BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    BitmapFactory.decodeStream(lStreamToImage, null, options); 
    options.inSampleSize = 8; //Decrease the size of decoded image 
    options.inPreferredConfig = Bitmap.Config.ARGB_4444; 
    options.inJustDecodeBounds = false; 
    bitmap = BitmapFactory.decodeStream(lStreamToImage, null, options); 
} catch(Exception e){} 
image.setImageBitmap(bitmap); 

但它沒有返回位圖(我的意思是返回null)。在logcat的是露出反覆

08-02 17:21:04.389: D/skia(19359): --- SkImageDecoder::Factory returned null 

下面的消息,如果我會評論的options.inJustDecodeBounds線並重新運行它,它工作正常,但速度緩慢。上面提供的開發人員指南鏈接I說,使用inJustDecodeBounds可以有效地加載位圖。

請告訴我我做錯了什麼。

回答

2

inJustDecodeBounds確實不是加載位圖。這就是它的重點。它加載位圖的尺寸而不加載實際的位圖,因此您可以在實際加載之前進行任何預處理或檢查位圖。這很有幫助,你說,有內存問題,你需要檢查加載位圖是否會導致程序崩潰。

您的位圖可能加載緩慢的原因是因爲它可能非常大,SD卡速度很慢。

編輯

From the documentation:

如果設置爲true,解碼器將返回null(無位),但出來...領域仍將設置,允許呼叫者查詢位圖而不必爲其像素分配內存。

編輯2:

看着谷歌提供的示例代碼,它看起來像你正在做的比較同樣的事情。它返回null的原因可能是你的InputStream在第一解碼已被修改,從而在該位圖的內存地址的開頭不啓動(他們使用的資源ID,而不是InputStream

從您提供此代碼,這裏的我想到的是,無論第一次解碼是什麼樣的,你總是將樣本大小設置爲8,Google第一次解碼的原因是找出位圖的實際大小與他們想要的大小之間的關係,位圖是ZxZ尺寸,他們想要YxY尺寸,所以他們計算出samplesize,他們應該從第二次解碼中使用,你沒有這樣做,你只是簡單地檢索位圖的尺寸而不使用它們。樣本大小爲硬編碼8,swappi將其轉換爲硬編碼的位圖,然後將完整的位圖解碼到內存中。換句話說,沒有使用這三條線:

BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inJustDecodeBounds = true; 
BitmapFactory.decodeStream(lStreamToImage, null, options); 

設置inJustDecodeBounds只是給你的位圖的尺寸,而不把位圖到內存中。它並沒有使它更有效率。它的意思是允許你在較小的內存空間中加載位圖,如果它們太大,因爲你可以預先決定它應該是多少而不需要解碼整個東西)。

解碼位圖速度慢的原因可能僅僅是CPU的問題。根據位圖的大小,您從SD卡中的InputStream加載位圖,這本身就是一個緩慢的操作。

+0

親愛的DeeV文檔說如果設置爲true,它將返回null,但它會預處理它。但是,如果你想獲得預處理的位圖,然後將其設置爲false並重新獲得它。我在上面做了什麼。請參閱上面給出的文檔鏈接,它也做同樣的事情。 – 2012-08-02 12:27:34

+0

我認爲他們說錯了「處理它」。它「處理」圖像的意義在於,它會給你圖像的大小而不完全解碼圖像。注意,我似乎還記得一個月前有人試圖重複使用同一個Options對象的問題,並且它一直在崩潰。最後,他必須創造一個新的。 – DeeV 2012-08-02 12:40:13

+0

這有史以來的工作?我正在查看你的代碼,並試圖找出哪裏出了問題。除了重新使用BitmapFactory.Options對象(由於某些原因導致問題)之外,我沒有看到提供的段。 – DeeV 2012-08-05 14:10:00