I made a Bitmap out of a byte array. I want to save the bitmap to a file. I then want to retrieve that Bitmap and restore the original byte array. I thought I could just simply save the file and then read it, but apparently the bytes are different...
Saving bitmap:
// create the bitmap
final Bitmap bitmap = Bitmap.createBitmap(width, newHeight, Bitmap.Config.ARGB_8888);
ByteBuffer buffer = ByteBuffer.wrap(originalBytes);
bitmap.copyPixelsFromBuffer(buffer);
...
// save the bitmap to file
String dir_path = Environment.getExternalStorageDirectory().getAbsolutePath();
File dir = new File(dir_path);
if(!dir.exists())
{
dir.mkdirs();
}
File file = new File(dir, "meh.png");
FileOutputStream fOut = null;
try {
fOut = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
I then read this file
// read the file
String file_path = Environment.getExternalStorageDirectory().getAbsolutePath();
Bitmap bitmap = BitmapFactory.decodeFile(file_path + "/" + "meh.png");
// get the bytes
ByteBuffer buffer = ByteBuffer.allocate(bitmap.getByteCount());
bitmap.copyPixelsToBuffer(buffer);
byte[] retrievedBytes = buffer.array();
When I compare originalBytes with retrievedBytes, the lengths are the same, but the content is not. I thought Bitmap.CompressFormat.PNG guarantees no compression? What am I missing here?
EDIT:
Here are parts of the both byte arrays converted to hex
original bytes hex: 8D7D A111 DE1D 105F 0B58 86A0 5F4D 035A D9A6 ...
retrieved bytes hex: 0406 0711 1F1D 105F 0B58 86A0 054D 035A 3C09 ...
Do not use Bitmap and BitmapFactory to save a byte array to file or loading a file in a byte array. As you saw that will change the bytes.
Better directly save the byte array to file. And load the contents of a file directly in a byte array.
Will be much quicker too.
Related
I save image from custom camera:
public String getFilename() {
File file = new File(Environment.getExternalStorageDirectory().getPath(), "Products/Images");
if (!file.exists()) {
file.mkdirs();
}
String uriSting = (file.getAbsolutePath() + "/" + System.currentTimeMillis() + ".jpg");
return uriSting;
}
Now:
public String saveImage(Bitmap bitmap) {
FileOutputStream out = null;
String filename = getFilename();
try {
out = new FileOutputStream(filename);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
} catch (FileNotFoundException e) {
Log.e("Error",e.toString());
e.printStackTrace();
return "";
}
return filename;
}
I use this filename in exifInterface after saving image
exif = new ExifInterface(filePath);
But every time it shows in my log Raw image not detected, Exif: 0
You compress a bitmap to a jpg file.
Bitmaps dont contain exif information.
And compressing a bitmap to a jpg file does not add an exif header to the file.
BitmapFactory.decodeByteArray(data, 0, data.length);
You have a nice byte array called data.
This byte array contains the bytes of a jpg file with exif header.
If you wanna save the data to file then do not make an intermediate bitmap first as at that moment you lost the exif header.
Instead save the bytes in your data array directly to file.
Then you will have a jpg file with an exif header.
When we convert the file (say - image)
To byteArray how can be approximately compared between them (image file and byteArray) ?
Is there also a way to first convert image file to byteArray and this byteArray has to be written in a text-file..
Again after this read these lines of byteArray from text-file and make byteArray and hence converted to image file...... I'm beginner and just for knowledge purpose i want to know....
You can convert your image to byte array like this.
BufferedImage bImage = ImageIO.read(new File("sample.jpg"));
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageIO.write(bImage, "jpg", bos );
byte [] data = bos.toByteArray();
Yes you can directly compare 2 byteArray.
Just do something like
if (bytearray1.length == bytearray2.length)
//its same
Try this to write the ByteArray in text file
public void writeToFile(byte[] array)
{
try
{
String path = "/data/data/YOURFILE.txt"; //provide your path here
File file = new File(path);
if (!file.exists()) { //just to check if file is actually present
file.createNewFile();
}
FileOutputStream stream = new FileOutputStream(path);
stream.write(array);
} catch (FileNotFoundException e1)
{
e1.printStackTrace();
}
}
I make canvas view which I want to send in server using retrofit library. I get canvas view in bitmap format. Now I want to convert bitmap to file format so that I can upload in server in file format.
File file = new File(context.getCacheDir(), filename);
file.createNewFile();
/* Convert bitmap to byte array */
Bitmap bitmap = bitmap; //bitmap is your bitmap file which you want to convert
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 0 , bos);
byte[] bitmapdata = bos.toByteArray();
/* write the bytes in file */
FileOutputStream fos = new FileOutputStream(file);
fos.write(bitmapdata);
fos.flush();
fos.close();
Always close and flush the FileOutputStream.
Convert ua bitmap to base64 String like below and send it using string
public static String bitmapToBase64(Bitmap image, Bitmap.CompressFormat compressFormat, int quality)//u can pass 100 in quality or any integer
{
ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
image.compress(compressFormat, quality, byteArrayOS);
return Base64.encodeToString(byteArrayOS.toByteArray(), Base64.DEFAULT);
}
Hi I am working on application which gets .png files in byte stream from server. When I got it I try to make from it bmp and later convert it to .png file, but the following method ( Bitmap img = BitmapFactory.decodeByteArray(result, 0, result.length); ) returns me null.
Here is my code:
byte[] result
Bitmap img = BitmapFactory.decodeByteArray(result, 0, result.length);
try {
File filename = new File(imageUri.getPath()+name);
File parentFile = new File(imageUri.getPath());
parentFile.mkdirs();
FileOutputStream out = new FileOutputStream(filename);
img.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (FileNotFoundException e) {
Log.e("imageDownloaded", e.toString());
} catch (Exception e) {
Log.e("imageDownloaded", e.toString());
}
but the img Bitmap is always, null. I uploaded the image as multi part data and it was png file parsed to byte array, but now when i want to retrieve it i get this ugly null. Thanks for any help.
Im attempting to save the actual image from my applications resources to a file on the SD card so it is accessible by the messaging application but I'm getting the error of - The method write(byte[]) in the type FileOutputStream is not applicable for the arguments (Drawable) - where its supposed to save it. I believe that I'm not using the appropriate method to save the actual image itself and I'm having difficulty finding a solution.
// Selected image id
int position = data.getExtras().getInt("id");
ImageAdapter imageAdapter = new ImageAdapter(this);
ChosenImageView.setImageResource(imageAdapter.mThumbIds[position]);
Resources res = getResources();
Drawable drawable = res.getDrawable(imageAdapter.mThumbIds[position]); //(imageAdapter.mThumbIds[position]) is the resource ID
try {
File file = new File(dataFile, FILENAME);
file.mkdirs();
FileOutputStream fos = new FileOutputStream(file);
fos.write(drawable); // supposed to save the image here, getting the error at fos.write
fos.close();
}catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
You error does explain it all, A fileOuputStream can not take a Drawable, it needs a byte array.
So you need to get the bytes from your Drawable.
try:
Drawable drawable = res.getDrawable(imageAdapter.mThumbIds[position]);
Bitmap bitmap = ((BitmapDrawable)drawable).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] bitmapdata = stream.toByteArray();
....
fos.write(bitmapdata);
And while you are at it, put the fos.close() in the Finally bock