Need MD5 hash for an in memory System.Drawing.Image
Asked
Active
Viewed 9,012 times
8
-
Where are you stuck? It's relatively straightforward. – µBio Aug 04 '10 at 22:20
-
1The title *doesn't* say it all... why do you need a hash? Does it need to be identical to the hash of an equivalent on-disk file? Presumably you're going to be comparing the hash to something at some point... – JaredReisinger Aug 04 '10 at 22:24
-
@Jared - http://uploadscreenshot.com/api-documentation#variables Now, you know what I know: I have a System.Drawing.Image in memory and need to send an MD5 hash of the Image object to that API. – Ronnie Overby Aug 04 '10 at 23:42
-
Okay... so the API should really call it the "MD5 hash of the file being uploaded", rather than of the image. You'll have to serialize the image (to a stream or file) to POST it anyway, so *that's* the data that you'll need to hash, using almost any of the answers below. – JaredReisinger Aug 05 '10 at 01:25
3 Answers
7
Here is a basic snippet. See also @JaredReisinger 's comment for some questions.
using System.Security.Cryptography;
using System.Text;
using System.Drawing.Imaging;
// ...
// get the bytes from the image
byte[] bytes = null;
using( MemoryStream ms = new MemoryStream() )
{
image.Save(ms,ImageFormat.Gif); // gif for example
bytes = ms.ToArray();
}
// hash the bytes
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
byte[] hash = md5.ComputeHash(bytes);
// make a hex string of the hash for display or whatever
StringBuilder sb = new StringBuilder();
foreach (byte b in hash)
{
sb.Append(b.ToString("x2").ToLower());
}

µBio
- 10,668
- 6
- 38
- 56
-
1Thanks for just answering the question and not spending all of your energy worrying about why I need to know. I wish that more people on SO were more like you. Also, you can avoid the StringBuilder and foreach loop. See my answer. – Ronnie Overby Aug 05 '10 at 00:10
-
The bad thing about this approach is that image.Save() does not provide uniform result, i.e. hashes are just different if image is created programmatically (two absolutely identical instances are created using Graphics.FromImage and painting a few lines). – olegz Jun 13 '12 at 03:13
3
A simple sample, based on the sample in MSDN; note that this hash is dependent on the internal representation of the image and will not correspond to the hash created from a file.
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Security.Cryptography;
using System.Text;
class Program
{
static string getMd5Hash(byte[] buffer)
{
MD5 md5Hasher = MD5.Create();
byte[] data = md5Hasher.ComputeHash(buffer);
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
return sBuilder.ToString();
}
static byte[] imageToByteArray(Image image)
{
MemoryStream ms = new MemoryStream();
image.Save(ms, ImageFormat.Bmp);
return ms.ToArray();
}
static void Main(string[] args)
{
Image image = Image.FromFile(@"C:\tmp\Jellyfish.jpg");
byte[] buffer = imageToByteArray(image);
string md5 = getMd5Hash(buffer);
}
}
To be able to use the MD5
class you need to add a reference to System.Security
.
Depending on what you are going to use the hash for you should consider the fact that MD5 is no longer state of the art and that there are better hash functions available if you need a strong hash.

Dirk Vollmar
- 172,527
- 53
- 255
- 316
-
I have to say this is nicely put together .... on que with what the textbooks teach also for exam takers. – IbrarMumtaz Aug 05 '10 at 00:35
1
Thanks to the other fellows who answered. Here's what I ended up doing:
MemoryStream ms = new MemoryStream()
image.Save(ms, ImageFormat.Png);
byte[] imgBytes = ms.ToArray();
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
byte[] hash = md5.ComputeHash(imgBytes);
string imageMD5 = BitConverter.ToString(hash).Replace("-", "").ToLower();
ms.Dispose();

Ronnie Overby
- 45,287
- 73
- 267
- 346