使用BitmapRegionDecoder加载jpeg会产生棋盘格扭曲

时间:2012-11-18 15:29:24

标签: android jpeg tiles

我正在使用来自URLConnection的InputStream从url加载一个大的jpeg文件。目标是使用图像数据获取int [],因为这比使用Bitmap进一步使用更有效。这里有两种选择。

第一种是创建一个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 个答案:

答案 0 :(得分:2)

发现它!显然,如果你将null提供给decoder.decodeRegion(tileBounds,null);它返回一个质量为Bitmap.Config.RGB_565的Bitmap(不确定这是否依赖于设备)。简单地为它提供一个新的选项集返回Bitmap.Config.RGB_ARGB8888质量的位图。默认情况下,此首选质量已设置。

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

答案 1 :(得分:2)

感谢您的自我调查!

虽然我建议避免依赖某些默认值并明确说明:

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

谢谢!