Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Save a Bitmap as a Byte array or image File #6

Closed
jcastrov opened this issue May 30, 2014 · 7 comments
Closed

Save a Bitmap as a Byte array or image File #6

jcastrov opened this issue May 30, 2014 · 7 comments

Comments

@jcastrov
Copy link

Your algorithm helps me a lot saving memory in my app, Thank you; I used your algorithm like this:

public Bitmap getRotatedBitmap(Bitmap bitmap)
{
    JniBitmapHolder bitmapHolder = new JniBitmapHolder();
    bitmapHolder.storeBitmap(bitmap);
    bitmapHolder.rotateBitmapCw90();
    bitmap.recycle();
    return bitmapHolder.getBitmapAndFree();
}

Now, the next step is save this bitmap without lose quality. I'll try this:

public void saveBitmap1(Bitmap bitmap)
{
    bitmap = getRotatedBitmap(bitmap);
    String name = "desiredFilename.png";
    FileOutputStream fos = openFileOutput(name, Context.MODE_PRIVATE);
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
    fos.flush();
    fos.close();
}

The algorithm works fine, but this is too slow when the bitmap is compressing in PNG or WEBP. JPEG with 100 quality it's faster, anyway, the bitmap will lost quality. I'll try this too

public void saveBitmap2(Bitmap bitmap)
{
    bitmap = getRotatedBitmap(bitmap);
    int bytes = bitmap.getByteCount();
    ByteBuffer buffer = ByteBuffer.allocate(bytes);
    bitmap.copyPixelsToBuffer(buffer);
    byte[] array = buffer.array();
    String name = "desiredFilename.png";
    FileOutputStream fos = openFileOutput(name, Context.MODE_PRIVATE);
    fos.write(array);
    fos.flush();
    fos.close();
}

This solution have problems with big bitmaps, i.e. 5312 x 2988. When the buffer is allocating the bytes throws an OutOfMemoryException. And I can't resize the picture; I must rotate the picture without resize or lost quality.

So, Is there a form to get a byte array from your native library? Or Could you help me how I can save the bitmap as a File, avoiding memory exceptions?

I'll be very grateful if you can solve my problem

@AndroidDeveloperLB
Copy link
Owner

If you wish to have the bitmap on the heap (Java world) you are limited to the size of the heap.
I can't help you with that. That's the way Android works. The only thing you can do to increase the size of the heap is to use the "largeHeap" flag which doesn't promise you anything about how large the heap will get:
http://developer.android.com/guide/topics/manifest/application-element.html#largeHeap

However, if it's ok with you to have the content on the JNI world (C/C++), you can pass the data using one of the next techniques :

  1. use the native code of Android to decode the image file, within the JNI world, . I planned on reading it and researching it, but it can take a long time.
    If you like, I wrote about it on StackOverflow:
    http://stackoverflow.com/questions/17885201/image-decoding-and-manipulation-using-jni-on-android
  2. If your minimal SDK is API10, you can decode parts of the large image, using BitmapRegionDecoder:
    http://developer.android.com/reference/android/graphics/BitmapRegionDecoder.html
    You divide the original image into multiple patches, and move them to the JNI world. On the JNI world, the patches will be merged into a single bitmap.

In case you wish to encode the bitmap to a file, sadly this is something that Android also has on the native code, which I didn't do the needed research.

I really wish I could do the decoding&encoding on the JNI world, and have the Java world only as something to view the content.

If you research this and find the answers, please let me know.

BTW, about the quality loss of encoding images to files, JPEG is considered lossy format, which will always lose quality (even if you don't notice it).
PNG (and WEBP, if you use 100 for the quality) do not lose the quality, but usually take more space than JPEG.

@jcastrov
Copy link
Author

You're right. I increased the size of the heap, and some devices throws an OutOfMemoryException. I've little experience with native development, so I don't know how get a byte array on JNI world. BitmapRegionDecoder helped me, and the only choice was to compress the image in JPEG. I appreciate the help you gave me, so far I top my target off.

@AndroidDeveloperLB
Copy link
Owner

You could save on memory using the next tip too:
if you don't need transparency, check if it's ok to use a bitmap config that takes 2 bytes, which is called 565 .
This will reduce the memory usage of the bitmap by 2 ( because for each pixel you will use 2 bytes instead of 4) .
However, my library doesn't support this config of a bitmap (unless you change it, and maybe it's not that hard).

@ali1995reza
Copy link

Hi guys . I need to save 2 bitmaps into just one Image file and show them in the file , please if any onw know how i can do it help me . more description here : http://stackoverflow.com/questions/39028509/android-save-2-bitmap-into-just-one-image-file?noredirect=1#comment65421469_39028509

@AndroidDeveloperLB
Copy link
Owner

@ali1995reza First, you should create a new thread.
Second, if you got a solution, why ask about it here?
Third, this project is for JNI handling of bitmaps. If you wish, you can change the code inside, to create a new bitmap in JNI itself to combine the 2 bitmaps. You could even avoid having 2 bitmaps in memory at the same time, if you wish.

@ali1995reza
Copy link

But i never got solution . I have a big view over than 10000×10000 pixels and i want to save it to an Image file . I must create bitmap from part of this and then save dat ! Because of this size i never cant create a bitmap for entire of view . Hoe i can do it ?

@AndroidDeveloperLB
Copy link
Owner

OK, I answered there. Please avoid writing in existing threads.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants