Find Match between two Bitmap - CSharp System.Drawing

CSharp examples for System.Drawing:Bitmap

Description

Find Match between two Bitmap

Demo Code


using System.Drawing.Imaging;
using System.Drawing;
using System.Text;
using System.Collections.Generic;
using System;//from  w w w.  ja va2 s  .  c  o m

public class Main{
        static public unsafe Rectangle FindMatch2D(Bitmap bigImage, Rectangle findIn,
            Bitmap smallImage, Rectangle findWhat)
        {
            if (bigImage.PixelFormat != smallImage.PixelFormat)
            {
                throw new ArgumentException("Bitmaps need to be in same format.");
            }

            if (findIn.IsEmpty)
            {
                findIn = new Rectangle(Point.Empty, bigImage.Size);
            }
            if (findWhat.IsEmpty)
            {
                findWhat = new Rectangle(Point.Empty, smallImage.Size);
            }

            Rectangle result = Rectangle.Empty;

            BitmapData bmpdBig = bigImage.LockBits(findIn, ImageLockMode.ReadOnly, bigImage.PixelFormat);
            BitmapData bmpdSmall = smallImage.LockBits(findWhat, ImageLockMode.ReadOnly, smallImage.PixelFormat);

            byte* pointerBig = (byte*)bmpdBig.Scan0;
            byte* pointerSmall = (byte*)bmpdSmall.Scan0;

            int bpp = BitsPerPixel(bigImage.PixelFormat);
            Size bigSize = bigImage.Size;
            bigSize.Width = bigSize.Width * bpp / 8;
            Size smallSize = smallImage.Size; 
            smallSize.Width = smallSize.Width * bpp / 8;

            findIn.X = findIn.X * bpp / 8;
            findIn.Width = findIn.Width * bpp / 8;
            findWhat.X = findWhat.X * bpp / 8;
            findWhat.Width = findWhat.Width * bpp / 8;

            result = FindMatch2D(pointerBig, bigSize, findIn, pointerSmall, smallSize, findWhat);

            result.X = result.X * 8 / bpp;
            result.Width = result.Width * 8 / bpp;

            return result;
        }
        static public unsafe Rectangle FindMatch2D(byte* bigImage, Size bigSize, Rectangle findIn, 
            byte* smallImage, Size smallSize, Rectangle findWhat)
        {
            Rectangle result = Rectangle.Empty;
            if (findIn.IsEmpty)
            {
                findIn = new Rectangle(Point.Empty, bigSize);
            }
            else if (!FitsIn(ref bigSize, ref findIn))
            {
                throw new ArgumentException("Rectangle to find in does not fit to the big image");
            }

            if (findWhat.IsEmpty)
            {
                findWhat = new Rectangle(Point.Empty, smallSize);
            }
            else if (!FitsIn(ref smallSize, ref findWhat))
            {
                throw new ArgumentException("Rectangle to find does not fit to the small image");
            }

            //add test for small rect not fitting to big rect here
                        
            for (int y = findIn.Y; y < findIn.Bottom - findWhat.Height + 1; y++)
            {
                byte* rowPointer = bigImage + y * bigSize.Width + findIn.X;
                for (int x = findIn.X; x < findIn.Right - findWhat.Width + 1; x++)
                {
                    //inner loops, could use some optimation
                    for (int y2 = findWhat.Y; y2 < findWhat.Bottom; y2++)
                    {
                        for (int x2 = findWhat.X; x2 < findWhat.Right; x2++)
                        {
                            //do the comparing
                            if (rowPointer[y2 * bigSize.Width + x2]
                                != smallImage[y2 * smallSize.Width + x2])
                            {
                                goto noMatch;
                            }
                        }
                    }
                    //only way here is to pass the test
                    result.X = x;
                    result.Y = y;
                    result.Width = findWhat.Width;
                    result.Height = findWhat.Height;
                    goto matchFound;
                noMatch:
                    rowPointer++;
                }
            }
            matchFound:
            return result;
        }
}

Related Tutorials