cfhpanteracfh
cfhpanteracfh

Reputation: 115

Android base64 decoding/encoding image to string

Ok, I have read all questions and answers about this topic. I have been reading them for a few days and nothing worked for me so I have one straight question. This code generates one String

public String getStringImage(Bitmap bmp){
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
    byte[] imageBytes = baos.toByteArray();
    input = Base64.encodeToString(imageBytes, Base64.DEFAULT);
    return input;
}

And this code generate other String from the same PICTURE,

  <?php

$data = file_get_contents('Lake_mapourika_NZ.jpeg');
$nova = base64_encode($data);

    echo $nova;

?>

When I insert them into this code back in Java :

  public void decodeImage()
{
    byte[] decodedByte = Base64.decode(input, Base64.DEFAULT);
    bitmap = BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length);
    imageView.setImageBitmap(bitmap);
}

First String wont work second works fine. Why ? Why java to java wont work and PHP to java works fine ?

Of course Strings are different that is also good question. Why are they different when they are generated from same bitmap ? To me it seems that Java decode works fine but encode wont work.

I'm using this code to send my pictures from app to server so I cant use online converters every time it has to be encoded to string from app. I don't get any errors and for pictures taken with my phone camera I get out of memory exception. But when change quality to 50 then I get decoded string but it wont work as usual.

Is there any other way to do it ?

Upvotes: 3

Views: 4432

Answers (2)

Dalija Prasnikar
Dalija Prasnikar

Reputation: 28517

There is error in your code, but not the code you have posted. Check the content of bitmap you encode, and check that you are using correct input string variable while decoding.

Your encoding, decoding part works fine. That code would be better if you would not rely on member fields, though.

public String getStringImage(Bitmap bmp)
{
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
    byte[] imageBytes = baos.toByteArray();
    String input = Base64.encodeToString(imageBytes, Base64.DEFAULT);
    return input;
}

public void decodeImage(ImageView iv, String input)
{
    byte[] decodedByte = Base64.decode(input, Base64.DEFAULT);
    Bitmap bitmap = BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length);
    iv.setImageBitmap(bitmap);
}

Test code for above encoding/decoding methods - modified to use parameters instead of member fields.

Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.thn);
ImageView iv = (ImageView)findViewById(R.id.image_view1);
iv.setImageBitmap(bm);

iv = (ImageView)findViewById(R.id.image_view2);
String b = getStringImage(bm);
decodeImage(iv, b);

Answer to why you are getting different base64 string from Java encoding and PHP encoding is rather simple. With PHP you are taking image file and encode it as-is, and with Java you are maybe starting with same image file, but then you are first decoding it to bitmap and then you are encoding that bitmap to JPEG stream (that will produce different JPEG image from the one you have started with) that you finally encode to base 64.

PHP: JPEG file -> base64

Java: JPEG file -> Bitmap -> JPEG stream (different from JPEG file) -> base 64

Upvotes: 2

e4c5
e4c5

Reputation: 53734

This is not a direct answer to the question but, I think still the right answer! Base64 encoding/decoding is absolutely not needed for this task.

Images and other files are uploaded to web servers using the multipart/form-data encoding

The content type "application/x-www-form-urlencoded" is inefficient for sending large quantities of binary data or text containing non-ASCII characters. The content type "multipart/form-data" should be used for submitting forms that contain files, non-ASCII data, and binary data.

The good news is that you don't need to do the encoding yourself. All popular http client libraries handle it internally. You just need to tell them what files to upload. Here is an answer showing how to do it with Volley. Here is an answer that shows how to do it with loopj async http client.

It seems that you are using PHP at the server side. As you very well know, PHP has excellent built in support for accepting file uploads.

Base64 encoding/decoding is not needed at either end. Please also note that when you base64 encode a binary file it's size increases by about 30% so your base64 encoded post will increase memory, cpu and data usage on the device.

Upvotes: 1

Related Questions