Dart/Flutter Image library decode Bitmap fails - android

I am trying to read a bitmap generated on the platform site
here is the code I use to generate a byte array in android:
ByteBuffer byteBuffer = ByteBuffer.allocate(bitmap.getByteCount());
bitmap.copyPixelsToBuffer(byteBuffer);
return byteBuffer.array();
When I try to decode it with the image library it fails (dart code):
Image img = decodeBmp(bitmapData);
The method 'getBytes' was called on null.
bitmap data is not empty and looks proper for me
If I instead compress image on the android side to png or jpg than decodeImage (or -Png or -Jpg) works
but I dont want to use bitmap.compress
this code would work with compress
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bufferedBmp.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] imageData = baos.toByteArray();
return imageData;

Related

How to covert Image to byte[] or bitmap in Android Studio?

Can someone help me to solve a problem in Android Studio? I am creating an app in which I have a photo in JPEG format(Comming from the camera, not from file) and I want to convert it to bitmap.
You can use this method to convert image to byte[]. Like this:
public byte[] getBytesFromBitmap(Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 100, stream);
return stream.toByteArray();
}
// Here image variable is a JPEG file/image.
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(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().

Pass Drawable to iTextPdf instead of an Image - Android

I am using iTextPdf to create a check-in application. I've added the an image already using the image object :
imagePath = "/sdcard/Mugshot.jpg";
Image image = Image.getInstance(imagePath);
image.setAbsolutePosition(165f, 465f);
image.scaleToFit(290f,290f);
document.add(image);
I would prefer to add the image in the same way before adding any content, as I expect any subsequent stuff would write over existing stuff.
As per the API Documentation of iTextPdf you can also contruct using byte[] array
Convert drawable to byte[]
Drawable d = getResources ().getDrawable (R.drawable.your_drawable)
Bitmap bitmap = ((BitmapDrawable)d).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] bitmapData = stream.toByteArray();
Then
Image image = Image.getInstance(bitmapData);

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.

ParseFile on Android

I'm using the Parse SDK to build my app.
I can easily get a Bitmap out of the gallery by using Intents. I want to use them as a profile picture for my users.
However, in order to upload it I must convert it into a byte array. Also, when I download it it comes in the form of a byte array, and I must convert it back to a Drawable.
In order to convert it into a byte array, I'm doing this:
public static byte[] bitmapToByteArray(Bitmap bmp)
{
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
return byteArray;
}
I cannot find how to convert this byte[] back into a Bitmap without having to save it first. How can this process be achieved?
Just do the following:
Bitmap bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);

Categories

Resources