Decode a bitmap part from a file on Android

I have a file with a very large image: for example, 9000x9000.

I cannot load the bitmap in memory because the heap size. But I need to display a small part of this bitmap, for example, rectangle width = 100-200 and height = 200-400 (resulting sub-bitmap size = 100x200)

How can I extract this bitmap from a file?

Note. I do not want to lose the image quality of 100x200.

thanks

+6
source share
6 answers

Is it possible that there is a solution for this?

e.g. BitmapRegionDecoder .

It should work for API10 and above ...

+12
source

This can be easily done using RapidDecoder .

In fact, I created 9000x9000 png, the file size of which is about 80 MB, and an area of ​​200x400 was successfully downloaded.

import rapid.decoder.BitmapDecoder; Bitmap bitmap = BitmapDecoder.from("big-image.png") .region(145, 192, 145 + 200, 192 + 400) .decode(); imageView.setImageBitmap(bitmap); 

It works for Android 2.2 and higher.

+4
source

I think you can use the BitmapFactory method, which allows you to specify the Rect that you want to decode.

 public static Bitmap decodeStream (InputStream is, Rect outPadding, BitmapFactory.Options opts) 
+2
source

Try this code:

 public static Bitmap decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight) { final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); final int height = options.outHeight; final int width = options.outWidth; options.inPreferredConfig = Bitmap.Config.RGB_565; int inSampleSize = 1; if (height > reqHeight) { inSampleSize = Math.round((float) height / (float) reqHeight); } int expectedWidth = width / inSampleSize; if (expectedWidth > reqWidth) { inSampleSize = Math.round((float) width / (float) reqWidth); } options.inSampleSize = inSampleSize; options.inJustDecodeBounds = false; return BitmapFactory.decodeFile(path, options); } 
+1
source

I do not think you can. Even on a PC, I don’t understand how you could do this without downloading the whole image: most image formats, such as PNG, have pixel data wired, so you need to at least unzip the IDAT block before you can start doing anything else, and it will basically decode the whole image.

In your shoes, I will try to have the server do this for me. Where do you get the image anyway? Not from the server? Then try making a WS request that will give you the correct part of the image. If the image does NOT come from the server, you can still send it to your server to return only that part of the image that you want.

0
source

try this code:

 private Bitmap decodeFile(File f) { Bitmap b = null; try { BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; FileInputStream fis = new FileInputStream(f); b=Bitmap.createBitmap(BitmapFactory.decodeStream(fis, null, o), 100, 200, 200, 400, null, null); fis.close(); } catch (IOException e) { } return b; } 

Not sure, but this may give you some idea.

0
source

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


All Articles