4

我正在使用来自 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 没有问题。这里有什么问题?

4

2 回答 2

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);
于 2012-11-19T14:04:03.590 回答
2

感谢您的自查!

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

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

谢谢!

于 2013-03-25T07:58:49.717 回答