Convert PNG image to Base64 - android

I am converting drawable resource png image to bitmap and then converting that bitmap to base64 and sending it to server by web service.
The image is stored on server at some address and in response i am getting URL where the image is stored.
The problem is after sending image to server the url which i am getting with that url i am setting image to other imageview but the transperent part of image is becoming black colored,
i think the problem is with converting png image to base64,
my code:
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
bitmap = Bitmap.createScaledBitmap(bitmap, 300, 300, false);
mImageView.setImageBitmap(bitmap);
ByteArrayOutputStream bao = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 90, bao);
byte[] ba = bao.toByteArray();
base64Image = Base64.encodeToString(ba, Base64.DEFAULT);
please give me solution ASAP

Everything you are doing seems right. Depending on the version of Android you are compiling with, decodeResource can have different default behavior. You can force the BitmapFactory to use an alpha channel when decoding with the following code.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
options.inDither = false;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher, options);

Related

Byte array to bitmap converting issue

I am trying to implement Converting bitmap to byteArray android. I need to convert my byte[] to bitmap without compression. But everytime im getting whole black image. How to do it?
What I am doing:
int bytes = bmp.getByteCount();
ByteBuffer buffer = ByteBuffer.allocate(bytes);
bmp.copyPixelsToBuffer(buffer);
byte[] resarray = buffer.array();
And here how I get it to bitmap:
BitmapFactory.Options options = new
BitmapFactory.Options();
options.inScaled = false;
Bitmap bmp = BitmapFactory.decodeByteArray(barray,0, barray.length,options);
ImageView imageView = (ImageView) findViewById(R.id.resdetayimage);
imageView.setImageBitmap(bmp);`
EDIT
Bitmap factory decode only compressed things. Thats why my code not work. So I need something like:
Bitmap.Config configBmp = Bitmap.Config.valueOf(bitmap.getConfig().name());
Bitmap bitmap_tmp = Bitmap.createBitmap(width, height, configBmp);
ByteBuffer buffer = ByteBuffer.wrap(byteArray);
bitmap_tmp.copyPixelsFromBuffer(buffer);
But the code still not working. How can I implement this ? I got byte[] from intent.
Convert bitmap to byteArray
ByteArrayOutputStream bStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 90, bStream);
byte[] mByteArray = bStream.toByteArray();
Convert byteArray to Bitmap
Bitmap bitmap = BitmapFactory.decodeByteArray(mByteArray , 0, mByteArray.length);
Use copyPixelsFromBuffer() as it is the reverse of copyPixelsToBuffer().

java.lang.OutOfMemoryError: (Heap Size=17863KB, Allocated=11272KB, Bitmap Size=12444KB)

I am using Base64 Encoded String to convert image and then create it at Windows Server.
It is working fine in most of devices but It is giving error java.lang.OutOfMemoryError in android Version 2.3.5. I tried android:largeHeap="true" but it din't work.
Android Code:
BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
Bitmap bitmap = drawable.getBitmap();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] data = baos.toByteArray();
strBase64 = Base64.encodeToString(data, Base64.DEFAULT);
I want to give crop image option to user and then store it at windows server. Is there any easy and better way for this ?
My code at asp.net:
public System.Drawing.Image Base64ToImage(string base64String)
{
byte[] imageBytes = Convert.FromBase64String(base64String);
using (var ms = new MemoryStream(imageBytes, 0, imageBytes.Length))
{
ms.Write(imageBytes, 0, imageBytes.Length);
System.Drawing.Image image = System.Drawing.Image.FromStream(ms, true);
return image;
}
}
System.Drawing.Image convertedImage = Base64ToImage(Photo);
convertedImage.Save(Server.MapPath("~\\images\\profileImg\\jeeten.jpg"), System.Drawing.Imaging.ImageFormat.Jpeg);
I tried some cropping image codes but It gave error : A generic error occurred in GDI+.
I would make these changes:
Instead of getting the image from the ImageView, consider using it's original source (file system? asset?). Then you dont have to re-compress the image.
Do not compress JPGs at 100% quality. There is large cost for un-noticeable image quality gains. If you need 100%, use PNG, otherwise use an 85% quality JPG.
You have several copies of the image in memory - in the drawable, in your byte array, in your base 64 string, etc. You can eliminate some of these.
Why convert to base 64? Just send the bytes to the server - Here's an example using PHP, but in .NET use HttpPostedFile to receive it.
Before Compressing the bitmap you can follow this:
//Put your image in file.
File file = new File("/mnt/sdcard/image.jpg");
//Pass your file in decodeImage method (your file, with its width and height as you want to display)
Bitmap bitmapImg=decodeImage(file,100,100);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmapImg.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] byteArray = stream.toByteArray();
String encodedString = Base64.encodeToString(byteArray, Base64.DEFAULT);
//Body of decodeFile(File f,int WIDTH,int HIGHT)
public Bitmap decodeFile(File f,int WIDTH,int HIGHT)
{
try {
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f),null,o);
//The new size we want to scale to
final int REQUIRED_WIDTH=WIDTH;
final int REQUIRED_HIGHT=HIGHT;
//Find the correct scale value. It should be the power of 2.
int scale=1;
while(o.outWidth/scale/2>=REQUIRED_WIDTH && o.outHeight/scale/2>=REQUIRED_HIGHT)
scale*=2;
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
b1= BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (Exception e) {}
return b1;
}

How to keep image quality same in BitmapFactory

I've converted an bitmap image into string to save it:
............
Bitmap photo = extras.getParcelable("data");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
photo.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] b = baos.toByteArray();
String encodedImage = Base64.encodeToString(b, Base64.DEFAULT);
Then I retrieve the bitmap from string to set an activity's background just like that:
byte[] temp = Base64.decode(encodedImage, Base64.DEFAULT);
Options options = new BitmapFactory.Options();
options.inScaled = false;
Bitmap bitmap = BitmapFactory.decodeByteArray(temp, 0,
temp.length, options);
Drawable d = new BitmapDrawable(getResources(), bitmap);
getWindow().setBackgroundDrawable(d);
Everything works fine but the image quality reduces tremendously. How can I keep the image quality same as the original image? Did I do something wrong here that have reduced the quality?
JPEG is lossy, no matter what quality settings you use. If you want to keep the image unchanged, you have to use lossless compression. for example Bitmap.CompressFormat.PNG
You are having here a tradeoff situation between picture quality and memory usage. Take a look at this line:
photo.compress(Bitmap.CompressFormat.JPEG, 100, baos);
photo.compress is obviously decreasing your image resolution in a factor given by the second parameter, unfortunately, this is the best quality you can get, since between 0 - 100, 100 stands for the best quality you can get. Now, you have another option, depending on the original picture's size you can just save the image without compressing it, but be aware that most cases this doesn't work and Jalvik can throw an OutofMemoryException,
hope this helps.

How to efficiently decode JPEG from Base64?

In my android app I capture an image from the camera, compress it to jpeg, send it to the server and save it on hdd. There it takes 48,9kb (e.g.). I send it back in a Base64-String and decode it on the Android side like this:
byte[] img;
img = Base64.decode(base64, Base64.DEFAULT);
ByteArrayInputStream in = new ByteArrayInputStream(img);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 3;
Bitmap bmp = BitmapFactory.decodeStream(in, null, options);
return bmp;
Values bigger than 3 for
options.inSampleSize
will make the image look ugly. But if i now look at the size of
bmp
it is 156kb. Why does the size increase? How can I decode it, so that it keeps its original size and doesnt look ugly (too hard downsampling)?

load bmp image from byte array in android?

I am new to android,I developed one sample application which load the image from sd card and display as a bitmap image using image view controll.
Now i want to modify my application like load the bmp from byte array i have the raw image ,width and height ,do any one have sample for this?
Use below Code for Convert Byte Array to Bitmap and display this bitmap into ImageView.
Bitmap bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
ImageView image = (ImageView) findViewById(R.id.imageView1);
image.setImageBitmap(bmp);
and see below SO link for more information.
Convert ByteArray to Bitmap
I think you can use BitmapFactory.
public static Bitmap decodeByteArray (byte[] data, int offset, int length)
For more info, look here
if your image is in Drawable folder try this code
Drawable drawable= getResources().getDrawable(R.drawable.yourimage);
//Type cast to BitmapDrawable
Bitmap bitmap = ((BitmapDrawable)drawable).getBitmap();
//Write a compressed version of the bitmap to the specified outputstream via compress method.
ByteArrayOutputStream out = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
byte[] buffer = stream.toByteArray();

Categories

Resources