2

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 ...

Rafal
  • 85
  • 7
  • No compression doesn't mean format/order of bytes is the same: http://stackoverflow.com/questions/2384111/png-file-format-endianness http://stackoverflow.com/questions/419584/what-is-the-difference-between-jpg-jpeg-png-bmp-gif-tiff-i – Morrison Chang Apr 16 '15 at 20:20
  • So there is no way to maintain the order? Is there another way of saving/restoring the byte array? I would like to keep it as an "openable" picture if possible. – Rafal Apr 16 '15 at 20:24
  • What do you mean by "openable"? If the bits are not in the correct order any other PNG viewer won't get the right image. – Morrison Chang Apr 16 '15 at 20:26
  • The png that I store right now I can open in Android gallery. It represent the bitmap correctly. Only when I read it in code and retrieve the bytes they are not matching the original bytes used. I don't understand how to fix that. – Rafal Apr 16 '15 at 20:31
  • Could you post an excerpt of the first couple of bytes of both arrays as hexadecimal values? Just to verify that the problem is really the byte order. – tiguchi Apr 16 '15 at 20:32
  • Hmm... since it's PNG it might as well be the alpha channel that changes here. It could be that saving / decoding premultiplies the RGB color channels with the alpha value, therefore you don't get the original back – tiguchi Apr 16 '15 at 20:38
  • http://developer.android.com/reference/android/graphics/Bitmap.html#setPremultiplied%28boolean%29 – tiguchi Apr 16 '15 at 20:38

1 Answers1

0

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.

greenapps
  • 10,799
  • 2
  • 13
  • 19
  • I suppose that would be an alternative. The thing is, this whole process is a part of image encryption. I wanted to encrypt an image, store it on disk, and then retrieve it to decrypt it. I wanted to keep the encrypted byte array as an image since it is supposed to represent an encrypted image. – Rafal Apr 16 '15 at 21:01