Not able to convert Bitmap to perfect Base64 String in Android?

匿名 (未验证) 提交于 2019-12-03 03:05:02

问题:

I am working on an application in which I need to capture an Image from camera. After capture, I have to convert the Bitmap to Base64. After converting to Base64, I have to send that String to SERVER. I am using below code for this task:

ByteArrayOutputStream baos = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.PNG, 100, baos); byte[] b = baos.toByteArray(); base64Image = Base64.encodeToString(b,Base64.DEFAULT); 

Problem : When I convert that Base64 to image, I am getting INCOMPLETE IMAGE. The same result is happening over server where my image is not perfectly re-constructed from Base64 String.

Please suggest me the solution. I have already search a-lot and getting same code which I am using right now.

Edited: please see the below incomplete Image

Code use to capture the Image:

intent = new Intent("android.media.action.IMAGE_CAPTURE"); startActivityForResult(intent, TAKE_PHOTO); 

回答1:

Create your own Base64 class and use this :

public class Base64 {    private Base64()   {     super();   }    /**    *  Encode some data and return a String.    */   public final static String encode(byte[] d)   {     if (d == null) return null;     byte data[] = new byte[d.length+2];     System.arraycopy(d, 0, data, 0, d.length);     byte dest[] = new byte[(data.length/3)*4];      // 3-byte to 4-byte conversion     for (int sidx = 0, didx=0; sidx < d.length; sidx += 3, didx += 4)     {       dest[didx]   = (byte) ((data[sidx] >>> 2) & 077);       dest[didx+1] = (byte) ((data[sidx+1] >>> 4) & 017 |                   (data[sidx] << 4) & 077);       dest[didx+2] = (byte) ((data[sidx+2] >>> 6) & 003 |                   (data[sidx+1] << 2) & 077);       dest[didx+3] = (byte) (data[sidx+2] & 077);     }      // 0-63 to ascii printable conversion     for (int idx = 0; idx <dest.length; idx++)     {       if (dest[idx] < 26)     dest[idx] = (byte)(dest[idx] + 'A');       else if (dest[idx] < 52)  dest[idx] = (byte)(dest[idx] + 'a' - 26);       else if (dest[idx] < 62)  dest[idx] = (byte)(dest[idx] + '0' - 52);       else if (dest[idx] < 63)  dest[idx] = (byte)'+';       else            dest[idx] = (byte)'/';     }      // add padding     for (int idx = dest.length-1; idx > (d.length*4)/3; idx--)     {       dest[idx] = (byte)'=';     }     return new String(dest);   }    /**    * Encode a String using Base64 using the default platform encoding    **/   public final static String encode(String s) {     return encode(s.getBytes());   }    /**    *  Decode data and return bytes.    */   public final static byte[] decode(String str)   {     if (str == null)  return  null;     byte data[] = str.getBytes();     return decode(data);   }    /**    *  Decode data and return bytes.  Assumes that the data passed    *  in is ASCII text.    */   public final static byte[] decode(byte[] data)   {     int tail = data.length;     while (data[tail-1] == '=')  tail--;     byte dest[] = new byte[tail - data.length/4];      // ascii printable to 0-63 conversion     for (int idx = 0; idx <data.length; idx++)     {       if (data[idx] == '=')    data[idx] = 0;       else if (data[idx] == '/') data[idx] = 63;       else if (data[idx] == '+') data[idx] = 62;       else if (data[idx] >= '0'  &&  data[idx] <= '9')         data[idx] = (byte)(data[idx] - ('0' - 52));       else if (data[idx] >= 'a'  &&  data[idx] <= 'z')         data[idx] = (byte)(data[idx] - ('a' - 26));       else if (data[idx] >= 'A'  &&  data[idx] <= 'Z')         data[idx] = (byte)(data[idx] - 'A');     }      // 4-byte to 3-byte conversion     int sidx, didx;     for (sidx = 0, didx=0; didx < dest.length-2; sidx += 4, didx += 3)     {       dest[didx]   = (byte) ( ((data[sidx] << 2) & 255) |               ((data[sidx+1] >>> 4) & 3) );       dest[didx+1] = (byte) ( ((data[sidx+1] << 4) & 255) |               ((data[sidx+2] >>> 2) & 017) );       dest[didx+2] = (byte) ( ((data[sidx+2] << 6) & 255) |               (data[sidx+3] & 077) );     }     if (didx < dest.length)     {       dest[didx]   = (byte) ( ((data[sidx] << 2) & 255) |               ((data[sidx+1] >>> 4) & 3) );     }     if (++didx < dest.length)     {       dest[didx]   = (byte) ( ((data[sidx+1] << 4) & 255) |               ((data[sidx+2] >>> 2) & 017) );     }     return dest;   }    /**    *  A simple test that encodes and decodes the first commandline argument.    */   public static final void main(String[] args)   {     if (args.length != 1)     {       System.out.println("Usage: Base64 string");       System.exit(0);     }     try     {       String e = Base64.encode(args[0].getBytes());       String d = new String(Base64.decode(e));       System.out.println("Input   = '" + args[0] + "'");       System.out.println("Encoded = '" + e + "'");       System.out.println("Decoded = '" + d + "'");     }     catch (Exception x)     {       x.printStackTrace();     }   } } 

First Convert your bitmap to byteArray by following code :

 ByteArrayOutputStream baos = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.PNG, 100, baos); byte[] b = baos.toByteArray(); 

To use this call pass byte[] of your bitmap image:

base64Image = Base64.encode(b)); 

You can check it by hitting following line in your browser, you will see image.

data:image/jpeg;base64,base64Image 


回答2:

Ok, i solved it. the problem was in the storing of the base64 string on the database. my column was declare as "TEXT" and it cuts the other picture's parts because the lenght of the string. so i changes it to "LONGTEXT" and now it's work perfectly!



回答3:

When I convert that Base64 to image, I am getting INCOMPLETE IMAGE

Try to do this with your image Bitmap and check if something is not as expected:

Bitmap originalBitmap = (Bitmap) data.getExtras().get("data"); //or whatever image you want Log.d(TAG, "original bitmap byte count: " + originalBitmap.getByteCount());  ByteArrayOutputStream baos = new ByteArrayOutputStream(); originalBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); Log.d(TAG, "byte array output stream size: " + baos.size());  byte[] outputByteArray = baos.toByteArray(); Log.d(TAG, "output byte array length: " + outputByteArray.length);  String base64EncodedString = Base64.encodeToString(outputByteArray, Base64.DEFAULT); Log.d(TAG, "base64 encoded string length: " + base64EncodedString.length());  byte[] inputByteArray = Base64.decode(base64EncodedString, Base64.DEFAULT); Log.d(TAG, "input byte array length: " + inputByteArray.length);  ByteArrayInputStream bais = new ByteArrayInputStream(inputByteArray); Log.d(TAG, "byte array input stream size: " + bais.available());  Bitmap decodedBitmap = BitmapFactory.decodeStream(bais); Log.d(TAG, "decoded bitmap byte count: " + decodedBitmap.getByteCount());  Log.d(TAG, "decoded bitmap same as original bitmap? " + decodedBitmap.sameAs(originalBitmap)); 

If all is ok then the problem is not the base64 encoding. Let me know!



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!