Explain Codes LogoExplain Codes Logo

Converting Java bitmap to byte array

java
bitmap
byte-array
memory-management
Alex KataevbyAlex Kataev·Aug 11, 2024
TLDR

Convert a Bitmap to a byte array using Bitmap.compress() and ByteArrayOutputStream:

ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); // "Because 100 is the best!" - Ancient Developer Proverb byte[] bytes = baos.toByteArray();

This snippet takes your Bitmap, gives it a good ol' squeeze down to PNG format at full quality, and exports it as a pixel parcel - a byte array using baos.toByteArray().

Byte me: Memory considerations

Working with Bitmaps and ByteArrayOutputStreams is like juggling with so many little pixels. And just like in a circus, you don't want to drop the balls and cause a spectacle (in this case, a crash due to an OutOfMemoryException). So, let's see how you can efficiently manage the task.

Bitmap null-check and memory recycling

When compressing the Bitmap to convert it into a byte array, you should check if the Bitmap isn't playing hide & seek with you (or in technical terms, isn't null):

if(bitmap != null){ // Go on with the conversion process }

If you're done playing with the Bitmap and don't need it again, make sure to recycle it to free the memory. Otherwise, your memory might end up looking like the aftermath of a teenager's house party:

bitmap.recycle();

Choosing your pixel parcel's wrapper

Depending on how you wish to wrap up your pixel parcel (i.e., your byte array), you can pick between different compress formats - PNG, JPEG, or WEBP:

bitmap.compress(Bitmap.CompressFormat.PNG, quality, baos); bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos); bitmap.compress(Bitmap.CompressFormat.WEBP, quality, baos);

Here, quality decides the balance between the fidelity of your artwork and the size of your bag of bytes. A value of 100 retains the original masterpiece in the byte array.

Pixel whispering: Advanced memory and format management

For folks who take joy in the nitty-gritty of bit manipulation and pixel whispering:

ByteBuffer: For the brave pixel tamers

In the mind-boggling world of Raw Pixel Tamers, you might feel the need to access the uncompressed raw data of the Bitmap for granular manipulation. Enter ByteBuffer, your magic wand:

int bitmapBytes = bitmap.getByteCount(); ByteBuffer buffer = ByteBuffer.allocate(bitmapBytes); // Making room for the Bitmap bitmap.copyPixelsToBuffer(buffer); // Getting the Bitmap onto the buffer buffer.rewind(); // "Buffer, you have something on your face. Let me wipe it off for you." - Every Careful Programmer byte[] rawBytes = new byte[bitmapBytes]; buffer.get(rawBytes);

Handling big canvases: Where art meets memory limitations

For high-res masterpieces, you might run into the notorious "java.lang.OutOfMemoryError". During such times, consider strategically resizing the Bitmap or decoding it with tailored options to reduce memory usage.

Look back to validate: Because we value our pixels

Just like at a crime scene, it's a good idea to validate your work by decoding your compressed byte array back into a Bitmap:

Bitmap decodedBitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); // Compare the original and decoded Bitmaps. Plot twist, anybody?

The art of choosing: Image format selection and performance tips

Art is always about choice. And just as an artist chooses his brush, colors, and strokes, you too must make key choices on the format and manage performance to create your final masterpiece.

Image format: A three-course menu, please

Selecting the right image format is like choosing from a three-course menu. Each comes with its own trade-offs between quality and size. PNG offers lossless compression, JPEG provides lossy compression, and WEBP gives the best of both worlds.

Bitmap dimensions: Watch your scale

Look at your Bitmap like a piece of cloth. The dimensions (width and height) and the pixel density (color depth, etc.) determine how much space it will take in your memory wardrobe. So make sure you have enough hangers (memory) for your collection.

Compression speed: Avoid The Flash

The compress method can act like The Flash. It can be fast, but energy-consuming. Balance your performance requirements and use this method wisely.

Zero-filled byte arrays: Don't let them fool you

Byte arrays aren't sugar cubes, so a byte array full of zeros generally means the Bitmap did a little magic trick and disappeared during conversion. Make sure to validate the output of your conversion process.

Converting back: Create, destroy, create again

To convert your byte array back to a Bitmap for inspection (because we like double-checking), use the ByteBuffer.wrap() method:

ByteBuffer wrappedBytes = ByteBuffer.wrap(bytes); Bitmap bitmapFromBytes = Bitmap.createBitmap(width, height, config); bitmapFromBytes.copyPixelsFromBuffer(wrappedBytes); // Parseltongue for "Welcome back, lost pixels!"

Testing: Because pixels don't forgive

Pixels are a territorial bunch. Mix them up, and they start acting weird. So, never forget to test your conversion code with various types of Bitmaps to ensure consistent results.