My app reads several BASE64 encoded images one by one from DB. But for some images(<0.1%), it fails to load. The method, BitmapFactory.decodeByteArray() return null which means its invalid format. But when I created a separate app with hard-coded culprit image, it worked. Now I have one big app where the same image didn't work and in my test app it works. Can anyone tell me why in God's name this is happening? Here is my code:
byte[] decodedString = Base64.decode(encodedImage, Base64.DEFAULT);
Bitmap setBMPPath = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
if (setBMPPath != null) {
qImage.setImageBitmap(setBMPPath);
}
Is there any other method that I can use to convert byte array to Bitmap?
You can try adding Base64.NO_WRAP:
byte[] decodeResponse = Base64.decode(base64Image, Base64.DEFAULT | Base64.NO_WRAP);
Bitmap bitmap = BitmapFactory.decodeByteArray(decodeResponse, 0, decodeResponse.length);
Hope this helps someone.
Related
So in my app I have possibility to take photo. What I want to do later is to sent this photo to server using API as Base64 String. Here's my code to encode bitmap (photo) to String :
public static String convertPhotoToBase(Bitmap bmp) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream.toByteArray();
Log.e(TAG, Base64.encodeToString(byteArray, Base64.DEFAULT));
return Base64.encodeToString(byteArray, Base64.DEFAULT);
}
Looks ok, right ? Well, it's not and I don't why String I'm receiving is not encoded correctly. I add, that bitmap is ok , cuz I can display it in ImageView without any problems.
String I'm getting looks like this :
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 UHOSaACXt9dDDgZlJXClyxBszo4tmGKJp
It looks like correct Base64 string but if you check it - it's not. Do you have any idea why is that ? Is it bitmap issue ,or what ? Any help, please ?
use this method to encode the bitmap you want
public static String enBitmap64(Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
bitmap.recycle();
byte[] array = stream.toByteArray();
return Base64.encodeToString(array, 0);
}
and this method to decode the string
public static Bitmap deBitmap64(String string) {
byte[] decodedString = Base64.decode(string, Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
return decodedByte;
}
However, before using encode64 you need to know few things
Encode and decode bitmaps needs to be done in background (NOT IN THE MAIN THREAD) it hangs the UI specially if the bitmap was large, use Asynctask, Service or Runnable (Asynctask is best choice).
It's not recommended to encode large images and upload it as string to server, encode and decode only in two cases.
First, if all you images are small.
Second, if you have large images and somewhere you app you display it as thumbnail For exp; In friends search of Facebook you see small images(thumbnail) you click it becomes large(original image). so there is small image and large image, when you are in friends search page you only request(download) the small image (low resolution) from the server no need to request(download) such large image(high resolution), but the two images are stored in the server. the small one could be saved as encoded but NOT the large one, large images is to be upload to server though HttpClient, Volley or HttpURLConnection.. there are more
I have almost the same issue,
encoding and decoding were working perfectly on the java side.
But my Base64 string couldn't be decoded on the server side.
comparing different base64s helped me to see that my base64 break into lines so using following code helped to correct base64
base64string.replace("\n", ""));
I'm trying to convert base64 image into bitmap image and then load it using picasso library into a recycler view. However, I get an error whenever I run my code saying I need to pass in a URI into the picasso method.
public String getImage(){
Context context =null;
byte[] decodedString = Base64.decode(image, Base64.URL_SAFE);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
decodedByte.compress(Bitmap.CompressFormat.PNG, 100, bytes);
path = MediaStore.Images.Media.insertImage(context.getContentResolver(), decodedByte, null, null);
return Uri.parse(path);
}
DataAdapter:
Picasso.with(context).load(data.get(i).getImage()).into(holder.reportImage);
Once you have downloaded and decoded a bitmap, there is no point of using an image loading library. All of the benefits (request queue and cache) are lost. You can simply use holder.reportImage.setImageBitmap(bmp);
Another approach would be to write a custom RequestHandler, that will decode the base64 data after downloading.
Assuming that you are using base64 image as a placeholder for your item in recycler view I suggest you use this method to convert base64 string to bitmap -
fun fromBase64ToBitmap(context: Context, base64string: String?): BitmapDrawable {
val decodedString = Base64.decode(string, Base64.DEFAULT)
val bitmap = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.size)
return BitmapDrawable(context.resources, bitmap)
}
and set
picasso.load(your_high_quality_image)
.placeholder(bitmapDrawableFromAboveMethod)
.into(imageHolder)
Hope this helps.
Note: Code is in Kotlin but you can easily convert it in java
I use Retrofit to transfer Data(class) from android to Server.Generally we create Same class on Client and Server side which contain data type like int,String same on both side.Now I need to send Image in class to Server.Also I just don't want to send just image to server but I want to send class which contain 1 image as datatype.So how can I do that ?or any suggestion how can I do this with some other tool ?
Suppose you already have a File pointing to the image:
final File imageFile = ...;
Note: How to get this file depends on whether you only allow local files in your file chooser (or e. g. images that are actually in Google Drive) and on which Android version you are on, etc.
To upload the image you need to use Retrofit's TypedFile - here is what worked for me:
#POST("/api/image/upload")
#Multipart
public void submitPictureToVoting(#Part("user_id") Integer userId,
#Part("image_title") String imageTitle,
#Part("file") TypedFile file,
Callback<UploadImageResponse> callback);
And then:
final TypedFile typedImageFile = new TypedFile("application/octet-stream", imageFile);
mApiClient.submitPictureToVoting(
1234567,
"This is me!",
typedImageFile,
new Callback<UploadImageResponse> {
// ...
});
I dont think this is answer but by doing this we can solve proble of Retrofit easily
Hi I tried this by Encoding Image to String ,so that we can easily send this "String" data type like other String, & when we want image back,we can decode it.
1.Code for Encoding
Here Image taken from ImageView.
BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
Bitmap bitmap = drawable.getBitmap();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
photo.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] imageBytes = baos.toByteArray();
String encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT);
2.Code for Decoding
byte[] decodedByte = Base64.decode(encodedImage, 0);
Bitmap decodedImg= BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length);
imageView.setImageBitmap(decodedImg);
I have the code below to decode a bitmap to a base64 string.
for(String e:paths)
{
String usepath=e.replace("%", "//");
Bitmap m=BitmapFactory.decodeFile(usepath);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
m.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] b = baos.toByteArray();
String bb= Base64.encodeToString(b, Base64.NO_WRAP);
Log.e("Photo", bb);
String usepath prints like
/mnt/sdcard/DCIM/Camera/IMG_20140424_132023.jpg
I have saved the image on my pc and used an online tool to decode it to base64 and i got a long string of around 650kb(after uploading to google app engine) yet the string i get using the above code is like 10% of that and does not display the image .
But i can use the same image path to set an image view and it works like below
Bitmap bm= BitmapFactory.decodeFile(usepath);
holder.imageItem.setImageBitmap(bm);
Any reasons why the base64 encoding failing?
Ronald
Try adding the flag Base64.URL_SAFE to the encoding method.
Consider also that if the image is too large you may not get all the bytes you need in the String (you may try writing to a temp file previous to send the content).
I am new to iPhone development.Currently I am working on an application in which I need to send an image as well as text. So I thought of using json technology by sending the string as json data. Now I need to append this image to this string. Can anyone suggest a method to do this?
This application should also be able to bump with an android phone. Is there any method to do this?
I heard of converting the image to base64 and send as string. Is that the right method to do it?
converting image to base64 is the right method for this. please have look at following code snippet
public String convertToBase64(Bitmap bm){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] image = baos.toByteArray();
String encodedImage = Base64.encodeToString(image, Base64.DEFAULT);
return encodedImage;
}
You can use this string to send through JSON data
Edited Part
For iPhone Try this code
-(NSString *)getStringFromImage:(UIImage *)image{
if(image){
NSData *dataObj = UIImagePNGRepresentation(image);
return [dataObj base64Encoding];
} else {
return #"";
}
}
Hope this will solve your problem