Loading jpeg using BitmapRegionDecoder gives checkerboard distortion

I am loading a large jpeg file from url using InputStream from URLConnection. The goal is to get int [] with image data, as it is more efficient than using Bitmap for future reference. There are two options.

First, you need to create a Bitmap object and copy the results to int []. This works in my application, but the full image is in memory twice during loading, when the image data is copied to the int [] image.

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

To save memory, I am trying to execute this process in a tiled manner using 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); } } 

Technically this works, and I get the full image in the int [] image. Also tiles without visible inserts in the image.

Now my problem. The second method leads to an image that has some strange distortion of a chessboard. The pixels seem to alternate between being slightly darker or slightly lighter. BitmapRegionDecoder is supposed to support jpeg, and BitmapFactory.decodeStream has no problems. What is the problem?

+4
source share
2 answers

Found! obviously if you feed null into decoder.decodeRegion (tileBounds, null); it returns a bitmap with quality Bitmap.Config.RGB_565 (not sure if it depends on the device). Simple suppression of a new set of parameters returns Bitmap of Bitmap.Config.RGB_ARGB8888. By default, this preferred quality is set.

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

Thank you for your self-study!

Although I would recommend not relying on some default and make it clear:

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

Thanks!

+2
source

Source: https://habr.com/ru/post/1446772/


All Articles