Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

how to compare two bitmaps?

214 views
Skip to first unread message

Jianren Lu

unread,
Jun 29, 2003, 11:04:38 AM6/29/03
to
Dear All,
I have two bitmaps, rawBitmap and newBitmap, one is another's
copy. But later the newBitmap may have some change, how can I compare
them the same picture or not?
the following is my code.


rawBitmap = new Bitmap(newBitmap.Width, newBitmap.Height);
Graphics g=Graphics.FromImage(rawBitmap);
g.DrawImage(newBitmap, 0, 0, newBitmap.Width,
newBitmap.Height);
g.Dispose();
later, newBitmap may have some change, for example, change to gray
scale, something like that, how can I compare them still the same
picture?

jianren

Chris Hornberger

unread,
Jun 29, 2003, 8:36:39 PM6/29/03
to
Maybe something like rolling your own hash code or maybe even a bit
sampling. Say, every 10th byte and see if it matches from one to the
other. Or a random sampling of byte matches.


l...@ils.uec.ac.jp (Jianren Lu) wrote in message news:<150b8982.03062...@posting.google.com>...

Chris R. Timmons

unread,
Jun 29, 2003, 9:20:15 PM6/29/03
to
l...@ils.uec.ac.jp (Jianren Lu) wrote in
news:150b8982.03062...@posting.google.com:

Jianren,

I've appended a class (BitmapHasher) to the end of this message that
can be used to get a unique hash value for a bitmap. Here's how to
use it:

System.UInt32 rawHash = BitmapHasher.GetBitmapHashValue(rawBitmap);
System.UInt32 newHash = BitmapHasher.GetBitmapHashValue(newBitmap);

if (rawHash != newHash)
// The bitmaps are different.


Hope this helps.

Chris.
-------------
C.R. Timmons Consulting, Inc.
http://www.crtimmonsinc.com/

///////////////////////////////////////////

using System;
using System.Drawing;

namespace CrtInc.Utils
{
/// <summary>
/// BitmapHasher provides one static method to determine the
/// 32-bit hash (unique) value of a given bitmap.
/// <para>
/// The code for the class was ported directly from a C code
/// algorithm for the PNG graphics format at
/// <see href="http://www.libpng.org/pub/png/spec/PNG-
/// CRCAppendix.html">
/// http://www.libpng.org/pub/png/spec/PNG-CRCAppendix.html</see>.
/// A few C# specific constructs were added, and the code was
/// shortened somewhat, but otherwise remains as close as
/// possible to the original C code.
/// </para>
/// </summary>
public sealed class BitmapHasher
{
// Don't allow instances of this class to be created.
private BitmapHasher() : base() {}

// Use a lookup table for speed.
private static readonly uint[] CRCTable = new uint[256];

static BitmapHasher()
{
uint c;

// Populate the CRC table.
for (uint n = 0; n < 256; n++)
{
c = n;
for (uint k = 0; k < 8; k++)
{
if ((c & 1) == 1)
c = 0xEDB88320 ^ (c >> 1);
else
c = c >> 1;
}
BitmapHasher.CRCTable[n] = c;
}
}

/// <summary>
/// Static method which returns the unsigned 32-bit integer
/// hash value of a bitmap.
/// </summary>
/// <param name="image">A <see cref="System.Drawing.Bitmap"/>
/// object.</param>
/// <returns>A <c>uint (System.UInt32)</c> hash value for the
/// <c>image</c> bitmap.</returns>
/// <remarks>
/// I'm not going to pretend that I know exactly how this
/// code works.
/// I didn't write it (I only ported it from C), and all
/// the bit-shifting and exclusive-OR (^) operations
/// leaves me dizzy.
/// Therefore, I can safely claim ignorance :).
/// <para>
/// However, it does appear to work. My testing so far has
/// been limited to the code's functionality, and not its speed.
/// </para>
/// <para>
/// Note that this method is not Common Language
/// Specification (CLS) compliant because it returns an
/// unsigned 32-bit integer. If you want to call
/// this code from a non-C# language that does not support the
/// System.UInt32 data type, the call probably won't work.
/// </para>
/// </remarks>
/// <example>
/// <code lang="C#">
/// // Example 1:
/// System.UInt32 hash = BitmapHasher.GetBitmapHashValue(
/// myImageList.Images[1] as Bitmap);
/// <para>
/// // Example 2:
/// Icon icon = new Icon("C:\IMAGES\FLOWER.ICO");
/// System.UInt32 hash = BitmapHasher.GetBitmapHashValue(
/// icon.ToBitmap());
/// </para>
/// </code>
/// </example>
[CLSCompliant(false)]
public static uint GetBitmapHashValue(
Bitmap image)
{
uint result = 0xFFFFFFFF;

for (int x = 0; x < image.Width; x++)
for (int y = 0; y < image.Height; y++)
result =
BitmapHasher.CRCTable[
(result ^ image.GetPixel(x, y).ToArgb()) & 0xFF] ^
(result >> 8);

return result ^ 0xFFFFFFFF;
}
}
}

Bill Woodruff

unread,
Jun 30, 2003, 12:56:25 AM6/30/03
to
Jianren,

Do a search on messages in this newsgroup with the word "checksum" in the title
and you will find how to use the cryptography namespace in C# and source code :

http://groups.google.com/groups?q=checksum+group:microsoft.public.dotnet.languages.csharp&hl=en&lr=&ie=UTF-8&oe=UTF-8&group=microsoft.public.dotnet.languages.csharp&sa=G&scoring=d

Looks like these solutions require that you get your bitmap into a byte array format.

best, Bill Woodruff
dotScience
Chaing Mai, Thailand

"Jianren Lu" <l...@ils.uec.ac.jp> wrote in message news:150b8982.03062...@posting.google.com...

0 new messages