2012-11-18 14 views
4

我正在使用URLConnection中的InputStream從URL加載大的jpeg文件。目標是獲得一個int []與圖像數據,因爲這比使用Bitmap進一步使用效率更高。這裏有兩個選項。使用BitmapRegionDecoder加載jpeg會產生棋盤失真

首先是創建一個Bitmap對象並將結果複製到一個int []中。這在我的應用程序中起作用,但是當圖像數據被複制到int []圖像時,完整圖像在加載後會在內存中兩次。

Bitmap full = BitmapFactory.decodeStream(conn.getInputStream()); 
full.getPixels(image, 0, width, 0, 0, width, height); 

爲了節省內存,我嘗試使用BitmapRegionDecoder以平鋪方式執行此過程。

int block = 256; 
BitmapRegionDecoder decoder = BitmapRegionDecoder. 
    newInstance(conn.getInputStream(), false); 
Rect tileBounds = new Rect(); 
// loop blocks 
for (int i=0; i<height; i+=block) { 
    // get vertical bounds limited by image height 
    tileBounds.top = i; 
    int h = i+block<height ? block : height-i; 
    tileBounds.bottom = i+h; 
    for (int j=0; j<width; j+=block) { 
     // get hotizontal bounds limited by image width 
     tileBounds.left = j; 
     int w = j+block<width ? block : width-j; 
     tileBounds.right = j+w; 
     // load tile 
     tile = decoder.decodeRegion(tileBounds, null); 
     // copy tile in image 
     int index = i*width + j; 
     tile.getPixels(image, index, width, 0, 0, w, h); 
    } 
} 

從技術上講,這工作,我得到了int []圖像的完整圖像。此外,瓷磚無縫地插入到圖像中。

現在我的問題。第二種方法導致圖像具有某種奇怪的棋盤格失真。像素似乎在稍暗或稍輕之間交替。 BitmapRegionDecoder應該支持jpeg,並且BitmapFactory.decodeStream沒有問題。這裏有什麼問題?

回答

2

找到了!顯然,如果你將null提供給decoder.decodeRegion(tileBounds,null);它會返回一個質量爲Bitmap.Config.RGB_565的位圖(不確定這是否取決於設備)。簡單地給它一個新的選項集返回一個Bitmap.Config.RGB_ARGB8888質量的位圖。默認情況下,此首選質量已設置。

BitmapFactory.Options options = new BitmapFactory.Options(); 
... 
// load tile 
tile = decoder.decodeRegion(tileBounds, options); 
2

感謝您的自我調查!

雖然我會建議避免依賴於一些默認,並明確:

BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inPreferredConfig=Config.ARGB_8888; //explicit setting! 
result_bitmap=regionDecoder.decodeRegion(cropBounds, options); 

謝謝!