Home » Android » Android Bitmap to Base64 String

Android Bitmap to Base64 String

Posted by: admin March 11, 2020 Leave a comment

Questions:

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

How to&Answers:

use following method to convert bitmap to byte array:

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();  
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream .toByteArray();

to encode base64 from byte array use following method

String encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);

Answer:

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);

Answer:

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).

Answer:

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);

Answer:

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.

Answer:

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)
    }

Answer:

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);
    }
}