How to convert Bitmap to base64 string with keeping quality the same? - android

I've tried this code:
ByteArrayOutputStream bao = new ByteArrayOutputStream();
mylistImg.get(i).compress(Bitmap.CompressFormat.PNG, 100, bao);
byte[] ba = bao.toByteArray();
ba1 = Base64.encodeToString(ba, Base64.DEFAULT);
But it lowers the quality a lot. since I want to send a Base64 string to php, I must convert my Bitmap file to string without any quality reduction.
I've read these links but didn't get anything special!
How to convert Bitmap to string without losing quality
Edited
I'm sending ba1 variable to oracle database as a blob data
but when I see the result in database, the image quality is very low.
and I did not change anything inside my php code about image quality

Try this i just changed the way we get the byte array rather than using .compress method
//b is the Bitmap
Bitmap b=mylistImg.get(i);
//calculate how many bytes our image consists of.
int bytes = b.getByteCount();
//or we can calculate bytes this way. Use a different value than 4 if you don't use 32bit images.
//int bytes = b.getWidth()*b.getHeight()*4;
ByteBuffer buffer = ByteBuffer.allocate(bytes); //Create a new buffer
b.copyPixelsToBuffer(buffer); //Move the byte data to the buffer
byte[] ba= buffer.array();
ba1 = Base64.encodeToString(ba, Base64.DEFAULT);

Related

how to reduce size of image so that it can fit to blob type..?

I'm compressing an image by using this code
imageText=encodeToBase64(bitmap, Bitmap.CompressFormat.PNG,100);
but when I store this image into my database and attribute type blobmedium then it takes too much time for displaying (loading) the image.
Even if my original image size is 32 Kb, it stores as 259 Kb in the database.
When I use tinyblob or blob type for image attribute in database it stores the value but does not show any results in the UI.
How can I reduce the size of image so that it fit to tinyblobb or blob?
So that I can store and fetch image successfully.
use the below code to compress an image:
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
// call to base64 image conversion method:
String encodeToBase64 = bitmapToBase64(thumbnail);
and then encode it to the base64 format as:
private String bitmapToBase64(Bitmap bmp)
{
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream .toByteArray();
return Base64.encodeToString(byteArray, Base64.DEFAULT);
}
Note that: A BLOB can be 65535 bytes maximum. If you need more consider using a MEDIUMBLOB for 16777215 bytes or a LONGBLOB for 4294967295 bytes

Displaying an encrypted byte array of an image in android

I have an image which I turn into a byte array. I then encrypt this byte array with AES and I want a visual result to display representing this encryption.
The problem is all the header and meta information is also encrypted so this encrypted byte array, which is passed to byteToImage(), is not recognized as a valid representation of an image i.e. decodeByteArray() returns null.
I have tried cutting off the first 512 bytes of the original image and appending that back on to the start of the encrypted byte array in the hope that this will restore the header information - but it hasn't worked. I have this with .png and .bmp images. What I ideally want is a way to represent a RAW image in android and encrypt this information byte for byte - leaving out the need to fiddle around with headers etc.
I would really appreciate any help.
private static byte[] imageToBytes(ImageView iv){
byte[] imageInByte = null;
Bitmap originalImage;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BitmapDrawable drawable = (BitmapDrawable) iv.getDrawable();
originalImage = drawable.getBitmap();
originalImage.compress(Bitmap.CompressFormat.PNG, 0, baos); // was 70
imageInByte = baos.toByteArray();
return imageInByte;
}
private static Bitmap bytesToImage(byte data[]) {
// byte[] x = Base64.decode(data, Base64.DEFAULT); using x in place of data also fails
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
return bmp;
}
Your idea will not work. If you encrypt just a lot of bytes of a bitmap byte array you will demolish its structure and after that you don't have a bitmap anymore. So you cannot display it. If you want to be able to display the 'encrypted' image then do it pixel wise. Have a look at Bitmap.getPixel()/setPixel() or Bitmap.getPixels()/setPixels().

Image Size getting Smaller after Converting to Bytes

In my android application i want to convert image into byte array and encode into string so that i can save it on database. But after compressing image it's size becomes too small..i want to keep original size.. please help me..
final Bitmap image=(images.get(position));
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.PNG, 100, bytes);
byte[] b = bytes.toByteArray();
encodedImageString = Base64.encodeToString(b, Base64.DEFAULT);
You can use the following to store it in the database without compression:
Bitmap bitmap; // obtain bitmap object
int size = bitmap.getRowBytes() * bitmap.getHeight();
ByteBuffer b = ByteBuffer.allocate(size);
bitmap.copyPixelsToBuffer(b);
byte[] bytes = new byte[size];
b.get(bytes, 0, bytes.length);
Then you can store bytes in the database.

Decode large base64 string

I have created a base64 string from a picture on the SD card using this(below) code, and it works but when I try to decode it (even further below) I get a java.lang.outOfMemoryException, presumably because I am not splitting the string into a reasonable size before I decode it as I am before I encode it.
byte fileContent[] = new byte[3000];
StringBuilder b = new StringBuilder();
try{
FileInputStream fin = new FileInputStream(sel);
while(fin.read(fileContent) >= 0) {
b.append(Base64.encodeToString(fileContent, Base64.DEFAULT));
}
}catch(IOException e){
}
The above code works well, but the problem comes when I try to decode the image with the following code;
byte[] imageAsBytes = Base64.decode(img.getBytes(), Base64.DEFAULT);
ImageView image = (ImageView)this.findViewById(R.id.ImageView);
image.setImageBitmap(
BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length)
);
I have tried this way too
byte[] b = Base64.decode(img, Base64.DEFAULT);
Bitmap bitmap = BitmapFactory.decodeByteArray(b, 0, b.length);
image.setImageBitmap(bitmap);
Now I assume that I need to split the string up into sections like my image encoding code, but I have no clue how to go about doing it.
You need decode the image in Background thread like AsyncTask
or
you need reduce your image quality using BitmapFactory .
Example:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
options.inPurgeable=true;
Bitmap bm = BitmapFactory.decodeFile("Your image exact loaction",options);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos); //bm is the bitmap object
byte[] b = baos.toByteArray();
String encodedImage = Base64.encodeToString(b, Base64.DEFAULT);
You have two problem
base64 encoding requires much more space. 3 bytes convert to 4 chars (Factor 8/3)
you read the whole file at once
in same way your first approach solved this issues. So just use that version
By that way, why are you using decodeByteArray and not decodeFile
You might try to decode to a temporary file and create image from that file.
As to base64, it is 6 bits per character, or 6x4=24 bits=3 bytes per 4 characters.
So if you take 4 characters of base64, you will not break the corresponding 3 bytes.
That is, you may split the base64-encoded data at character indices that are a multiple of 4.

Converting bitmap to byteArray android

I have a bitmap that I want to send to the server by encoding it to base64 but I do not want to compress the image in either png or jpeg.
Now what I was previously doing was.
ByteArrayOutputStream byteArrayBitmapStream = new ByteArrayOutputStream();
bitmapPicture.compress(Bitmap.CompressFormat.PNG, COMPRESSION_QUALITY, byteArrayBitmapStream);
byte[] b = byteArrayBitmapStream.toByteArray();
//then simple encoding to base64 and off to server
encodedImage = Base64.encodeToString(b, Base64.NO_WRAP);
Now I just dont want to use any compression nor any format plain simple byte[] from bitmap that I can encode and send to the server.
Any pointers?
You can use copyPixelsToBuffer() to move the pixel data to a Buffer, or you can use getPixels() and then convert the integers to bytes with bit-shifting.
copyPixelsToBuffer() is probably what you'll want to use, so here is an example on how you can use it:
//b is the Bitmap
//calculate how many bytes our image consists of.
int bytes = b.getByteCount();
//or we can calculate bytes this way. Use a different value than 4 if you don't use 32bit images.
//int bytes = b.getWidth()*b.getHeight()*4;
ByteBuffer buffer = ByteBuffer.allocate(bytes); //Create a new buffer
b.copyPixelsToBuffer(buffer); //Move the byte data to the buffer
byte[] array = buffer.array(); //Get the underlying array containing the data.
instead of the following line in #jave answer:
int bytes = b.getByteCount();
Use the following line and function:
int bytes = byteSizeOf(b);
protected int byteSizeOf(Bitmap data) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1) {
return data.getRowBytes() * data.getHeight();
} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
return data.getByteCount();
} else {
return data.getAllocationByteCount();
}
BitmapCompat.getAllocationByteCount(bitmap);
is helpful to find the required size of the ByteBuffer

Categories

Resources