3

So a few days ago I asked this question here on SO about generating a md5 sum from a android.graphics.Bitmap object. User Leonidos was a big help and his suggested method works. But the md5 sum I generated beforehand, using the same picture, gives a different sum.

The Android code I'm using is as follows:

public String md5ForBitmap(Bitmap bitmap)
{
    String hash = "";
    try
    {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
        byte[] bitmapBytes = stream.toByteArray();

        MessageDigest messageDigest = MessageDigest.getInstance("MD5");
        messageDigest.update(bitmapBytes);
        byte[] digestedBytes = messageDigest.digest();

        BigInteger intRep = new BigInteger(1, digestedBytes);
        hash = intRep.toString(16);
    }
    catch (NoSuchAlgorithmException e)
    {
        e.printStackTrace();
    }
    return hash;
}

While the python script looks like this:

def begin(path):
    os.chdir(path)
    files = glob.glob("*")

    for file in files:
        processFile(file, path)

def processFile(file, folder):
    with open(file, "r") as picture:
        fileContents = picture.read()
        md5 = hashlib.md5()
        md5.update(fileContents)
        hash = md5.hexdigest()
        print file + "   :   " + hash

The Android app receives a json string from a server that contains the url to the image and the md5 sum. The md5 sum having been calculated with the python script beforehand. After the image has been downloaded I'm left with a Bitmap object that I then use in the app.

Leonidos suggested that the Bitmap object isn't treated the same way as python treats the image data and that I'll need to find the md5 sum of the raw image data in Android. This sound, to me, to be a perfectly plausible explanation. It's just that I'm really really lost when it comes to all of this.

So what is the correct way to do this?

Community
  • 1
  • 1
Bjorninn
  • 4,027
  • 4
  • 27
  • 39
  • Does your bitmap start out as a File? if so I can post a java, and python snippet that I have used to get md5 of image file, and it is working for me (both return same value for same file). Mine starts from a file path though, if you are getting a bitmap without a file then it will not be of use. – FoamyGuy Mar 04 '13 at 19:41
  • You should probably open the file in "rb" mode, not "r" in the Python script. The b means that it is a binary file. – Justin Peel Mar 04 '13 at 19:50
  • I am saving each Bitmap on the phone so I could possibly load it as a java.io.File right after saving it. I was hoping I wouldn't have to do that. But if you have a code snippet that's working and no one has another solution I'd do just that. So please by all means, if it's not a hassle, post your snippet :) – Bjorninn Mar 04 '13 at 19:52
  • @Justin, I tried changing it to "rb" but it still gives me the same values. – Bjorninn Mar 04 '13 at 20:00
  • Am I missing something? From a cursory reading of your java code it seems pretty obvious that you're compressing the bitmap using JPEG - even if the bitmap was already stored as JPEG (no idea about the android class), you're unlikely to use exactly the same parameters for the compression. – Voo Mar 04 '13 at 20:38

1 Answers1

1

Well that's only an educated guess and all, but it seems pretty obvious to me that you shouldn't compress the bitmap using JPEG if you want to get the same MD5 hash as an uncompressed file.

The easiest you can probably do is to use copyPixelsToBuffer and adapt your python code to only read the actual pixels and ignore the header, etc. too. Easy enough using PIL.

The bitmap class internally probably really is nothing other than an uncompressed pixel buffer, so you can't even get the original file contents from it. Using the actual pixel values for the hash avoids the problem all together as long as both the bitmap class and PIL uncompress the original file identically (which seems likely).

Voo
  • 29,040
  • 11
  • 82
  • 156
  • I'll look into these methods. I need to finish something before I can get back to this. I'll post my findings afterwards. – Bjorninn Mar 05 '13 at 20:44