1

I went through these topics but still didn't find an answer to the following problem.

Android rotate bitmap without making a copy

Android: rotate image without loading it to memory

Rotating images on android. Is there a better way?

JNI bitmap operations , for helping to avoid OOM when using large images


I have a Uri which represents a big image. I need to save a rotated copy of this image to SD card. But when I do

BitmapFactory.decodeStream(contentResolver.openInputStream(uri));

I get an OutOfMemoryError.

What I wanted do do is something like this

    ContentResolver resolver = getContentResolver();
    InputStream inputStream = null;
    FileOutputStream outputStream = null;
    File imageFile = null;
    try {
        inputStream = resolver.openInputStream(uri);


        //I don't know how to apply this matrix to the bytes of InputStream
        Matrix matrix = new Matrix();
        matrix.postRotate(90);

        imageFile = createImageFile();

        outputStream = new FileOutputStream(imageFile);
        byte[] buffer = new byte[1024];
        while (inputStream.read(buffer) != -1) {

            //I'd like to apply the 'matrix' to 'buffer' here somehow but I can't
            //since 'buffer' contains the bytes of the image, not the pixel values of the bitmap
            outputStream.write(buffer);
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    } finally {
        Util.closeQuietly(inputStream);
        Util.closeQuietly(outputStream);
    }

What is the solution for this, if any?

Community
  • 1
  • 1
  • 1
    The image is on disk in an encoded fashion (PNG, JPEG, etc.). You have to decode the image to rotate it. JNI does not allocate memory on the Java heap, and therefore should avoid OOM. – CommonsWare Dec 31 '14 at 14:13
  • @CommonsWare thanks, you probably mean this lib https://github.com/AndroidDeveloperLB/AndroidJniBitmapOperations It is the best thing that I can think of, but still it requires the `Bitmap` to be constructed on the Java side which means loading it into the memory. Doesn't work with 10Mb+ images... – Denys Kniazhev-Support Ukraine Dec 31 '14 at 14:20
  • 1
    C/C++ code exists to read in images files and process them (e.g., `libmagick`). Whether there exists an Android JNI bridge to that code, or if you would have to write one, I cannot say. – CommonsWare Dec 31 '14 at 14:48

1 Answers1

0

If you can accept a lower quality image you can read it in with BitmapFactory.Options Often you can't visually tell the difference when using these options

 BitmapFactory.Options options = new BitmapFactory.Options();
 options.inSampleSize = 2; //Scale it down
 options.inPreferredConfig = Bitmap.Config.RBG_565; // Less memory intensive color format
 Bitmap bitmap = BitmapFactory.decodeStream( fis, null, options );

Hope this helps.

I don't see how you can manipulate it without reading it in first.

mjstam
  • 1,049
  • 1
  • 6
  • 5