[android] Android Bitmap to Base64 String

How do I convert a large Bitmap (photo taken with the phone's camera) to a Base64 String?

This question is related to android bitmap base64 android-bitmap

The answer is


I have fast solution. Just create a file ImageUtil.java

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Base64;
import java.io.ByteArrayOutputStream;

public class ImageUtil
{
    public static Bitmap convert(String base64Str) throws IllegalArgumentException
    {
        byte[] decodedBytes = Base64.decode(
            base64Str.substring(base64Str.indexOf(",")  + 1),
            Base64.DEFAULT
        );

        return BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length);
    }

    public static String convert(Bitmap bitmap)
    {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);

        return Base64.encodeToString(outputStream.toByteArray(), Base64.DEFAULT);
    }

}

Usage:

Bitmap bitmap = ImageUtil.convert(base64String);

or

String base64String = ImageUtil.convert(bitmap);

Now that most people use Kotlin instead of Java, here is the code in Kotlin for converting a bitmap into a base64 string.

import java.io.ByteArrayOutputStream

private fun encodeImage(bm: Bitmap): String? {
        val baos = ByteArrayOutputStream()
        bm.compress(Bitmap.CompressFormat.JPEG, 100, baos)
        val b = baos.toByteArray()
        return Base64.encodeToString(b, Base64.DEFAULT)
    }

All of these answers are inefficient as they needlessly decode to a bitmap and then recompress the bitmap. When you take a photo on Android, it is stored as a jpeg in the temp file you specify when you follow the android docs.

What you should do is directly convert that file to a Base64 string. Here is how to do that in easy copy-paste (in Kotlin). Note you must close the base64FilterStream to truly flush its internal buffer.

fun convertImageFileToBase64(imageFile: File): String {

    return FileInputStream(imageFile).use { inputStream ->
        ByteArrayOutputStream().use { outputStream ->
            Base64OutputStream(outputStream, Base64.DEFAULT).use { base64FilterStream ->
                inputStream.copyTo(base64FilterStream)
                base64FilterStream.close()
                outputStream.toString()
            }
        }
    }
}

As a bonus, your image quality should be slightly improved, due to bypassing the re-compressing.


Use this code..

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Base64;
import java.io.ByteArrayOutputStream;

public class ImageUtil 
{ 
    public static Bitmap convert(String base64Str) throws IllegalArgumentException 
    { 
        byte[] decodedBytes = Base64.decode( base64Str.substring(base64Str.indexOf(",") + 1), Base64.DEFAULT );
        return BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length);
    } 

    public static String convert(Bitmap bitmap) 
    { 
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
        return Base64.encodeToString(outputStream.toByteArray(), Base64.DEFAULT);
    }
}

The problem with jeet's answer is that you load all bytes of the image into a byte array, which will likely crash the app in low-end devices. Instead, I would first write the image to a file and read it using Apache's Base64InputStream class. Then you can create the Base64 string directly from the InputStream of that file. It will look like this:

//Don't forget the manifest permission to write files
final FileOutputStream fos = new FileOutputStream(yourFileHere); 
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);

fos.close();

final InputStream is = new Base64InputStream( new FileInputStream(yourFileHere) );

//Now that we have the InputStream, we can read it and put it into the String
final StringWriter writer = new StringWriter();
IOUtils.copy(is , writer, encoding);
final String yourBase64String = writer.toString();

As you can see, the above solution works directly with streams instead, avoiding the need to load all the bytes into a variable, therefore making the memory footprint much lower and less likely to crash in low-end devices. There is still the problem that putting the Base64 string itself into a String variable is not a good idea, because, again, it might cause OutOfMemory errors. But at least we have cut the memory consumption by half by eliminating the byte array.

If you want to skip the write-to-a-file step, you have to convert the OutputStream to an InputStream, which is not so straightforward to do (you must use PipedInputStream but that is a little more complex as the two streams must always be in different threads).


Try this, first scale your image to required width and height, just pass your original bitmap, required width and required height to the following method and get scaled bitmap in return:

For example: Bitmap scaledBitmap = getScaledBitmap(originalBitmap, 250, 350);

private Bitmap getScaledBitmap(Bitmap b, int reqWidth, int reqHeight)
{
    int bWidth = b.getWidth();
    int bHeight = b.getHeight();

    int nWidth = bWidth;
    int nHeight = bHeight;

    if(nWidth > reqWidth)
    {
        int ratio = bWidth / reqWidth;
        if(ratio > 0)
        {
            nWidth = reqWidth;
            nHeight = bHeight / ratio;
        }
    }

    if(nHeight > reqHeight)
    {
        int ratio = bHeight / reqHeight;
        if(ratio > 0)
        {
            nHeight = reqHeight;
            nWidth = bWidth / ratio;
        }
    }

    return Bitmap.createScaledBitmap(b, nWidth, nHeight, true);
}

Now just pass your scaled bitmap to the following method and get base64 string in return:

For example: String base64String = getBase64String(scaledBitmap);

private String getBase64String(Bitmap bitmap)
{
    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);

    byte[] imageBytes = baos.toByteArray();

    String base64String = Base64.encodeToString(imageBytes, Base64.NO_WRAP);

    return base64String;
}

To decode the base64 string back to bitmap image:

byte[] decodedByteArray = Base64.decode(base64String, Base64.NO_WRAP);
Bitmap decodedBitmap = BitmapFactory.decodeByteArray(decodedByteArray, 0, decodedString.length);

Examples related to android

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How to implement a simple scenario the OO way My eclipse won't open, i download the bundle pack it keeps saying error log getting " (1) no such column: _id10 " error java doesn't run if structure inside of onclick listener Cannot retrieve string(s) from preferences (settings) strange error in my Animation Drawable how to put image in a bundle and pass it to another activity FragmentActivity to Fragment A failure occurred while executing com.android.build.gradle.internal.tasks

Examples related to bitmap

How to solve java.lang.OutOfMemoryError trouble in Android Save and retrieve image (binary) from SQL Server using Entity Framework 6 How to create bitmap from byte array? Fastest way to convert Image to Byte array How to save a bitmap on internal storage Android set bitmap to Imageview Save bitmap to file function How to resize Image in Android? Android Bitmap to Base64 String Android load from URL to Bitmap

Examples related to base64

How to convert an Image to base64 string in java? How to convert file to base64 in JavaScript? How to convert Base64 String to javascript file object like as from file input form? How can I encode a string to Base64 in Swift? ReadFile in Base64 Nodejs Base64: java.lang.IllegalArgumentException: Illegal character Converting file into Base64String and back again Convert base64 string to image How to encode text to base64 in python Convert base64 string to ArrayBuffer

Examples related to android-bitmap

Android:java.lang.OutOfMemoryError: Failed to allocate a 23970828 byte allocation with 2097152 free bytes and 2MB until OOM Saving and Reading Bitmaps/Images from Internal memory in Android "Bitmap too large to be uploaded into a texture" Android Bitmap to Base64 String Get Bitmap attached to ImageView How to get Bitmap from an Uri? Strange out of memory issue while loading an image to a Bitmap object