[C#]几种Bitmap比较方式

这里选取图片,规格如下:

image

大小:

image

关键代码:

using System;

using System.Diagnostics;

using System.Drawing;

using System.Drawing.Imaging;

using System.IO;

using System.Runtime.InteropServices;



namespace ConsoleApplication27

{

    class Program

    {

        static void Main(string[] args)

        {

            try

            {

                Stopwatch _watch = new Stopwatch();

                _watch.Start();

                bool _compareByMenCmpResult = Resource1.cat.CompareByMemCmp(Resource1.cat);

                _watch.Stop();

                Console.WriteLine(string.Format("CompareByMemCmp: {0} {1}", _compareByMenCmpResult, _watch.ElapsedMilliseconds));

                _watch.Reset();

                _watch.Start();

                bool _compareByPixel = Resource1.cat.CompareByPixel(Resource1.cat);

                _watch.Stop();

                Console.WriteLine(string.Format("CompareByPixel: {0} {1}", _compareByPixel, _watch.ElapsedMilliseconds));

                _watch.Reset();

                _watch.Start();

                bool _compareByBase64String = Resource1.cat.CompareByBase64String(Resource1.cat);

                _watch.Stop();

                Console.WriteLine(string.Format("CompareByBase64String: {0} {1}", _compareByBase64String, _watch.ElapsedMilliseconds));

                _watch.Reset();

                _watch.Start();

                bool _compareByArray = Resource1.cat.CompareByArray(Resource1.cat);

                _watch.Stop();

                Console.WriteLine(string.Format("CompareByArray: {0} {1}", _compareByArray, _watch.ElapsedMilliseconds));

            }

            catch (Exception ex)

            {

                Console.WriteLine(ex.Message);

            }

            finally

            {

                Console.ReadLine();

            }

        }

    }

    public static class ImageTool

    {

        [DllImport("msvcrt.dll")]

        private static extern int memcmp(IntPtr b1, IntPtr b2, long count);

        /// <summary>

        /// Bitmap比较

        /// </summary>

        /// <param name="b1">Bitmap1</param>

        /// <param name="b2">Bitmap2</param>

        /// <returns>比较结果</returns>

        public static bool CompareByMemCmp(this Bitmap b1, Bitmap b2)

        {

            /*说明

             *参考链接:

             *http://stackoverflow.com/questions/2031217/what-is-the-fastest-way-i-can-compare-two-equal-size-bitmaps-to-determine-whethe

             */

            if ((b1 == null) != (b2 == null)) return false;

            if (b1.Size != b2.Size) return false;



            BitmapData _bdata1 = b1.LockBits(new Rectangle(new Point(0, 0), b1.Size), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

            BitmapData _bdata2 = b2.LockBits(new Rectangle(new Point(0, 0), b2.Size), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);



            try

            {

                IntPtr _bd1scan0 = _bdata1.Scan0;

                IntPtr _bd2scan0 = _bdata2.Scan0;

                int _stride = _bdata1.Stride;

                int _len = _stride * b1.Height;

                return memcmp(_bd1scan0, _bd2scan0, _len) == 0;

            }

            finally

            {

                b1.UnlockBits(_bdata1);

                b2.UnlockBits(_bdata2);

            }

        }

        /// <summary>

        /// 通过比较bitmap两者ToBase64String来判断是否相等

        /// </summary>

        /// <param name="b1">Bitmap1</param>

        /// <param name="b2">Bitmap2</param>

        /// <returns>比较结果</returns>

        public static bool CompareByBase64String(this Bitmap b1, Bitmap b2)

        {

            /*说明

            *参考链接:

            *http://blogs.msdn.com/b/domgreen/archive/2009/09/06/comparing-two-images-in-c.aspx

            */

            string _b1Base64String, _b2Base64String;

            MemoryStream _ms = new MemoryStream();

            try

            {

                b1.Save(_ms, ImageFormat.Png);

                _b1Base64String = Convert.ToBase64String(_ms.ToArray());

                _ms.Position = 0;



                b2.Save(_ms, ImageFormat.Png);

                _b2Base64String = Convert.ToBase64String(_ms.ToArray());

            }

            finally

            {

                _ms.Close();

            }

            return _b1Base64String.Equals(_b2Base64String);

        }

        /// <summary>

        /// 通过比较bitmap两者像素颜色来判断两者是否相等

        /// </summary>

        /// <param name="b1">Bitmap1</param>

        /// <param name="b2">Bitmap2</param>

        /// <returns>比较结果</returns>

        public static bool CompareByPixel(this Bitmap b1, Bitmap b2)

        {

            /*说明

             *参考链接:

             *http://blogs.msdn.com/b/domgreen/archive/2009/09/06/comparing-two-images-in-c.aspx

             */

            bool _flag = false;

            if (b1.Width == b2.Width && b1.Height == b2.Height)

            {

                _flag = true;

                Color _pixel1;

                Color _pixel2;

                for (int i = 0; i < b1.Width; i++)

                {

                    for (int j = 0; j < b1.Height; j++)

                    {

                        _pixel1 = b1.GetPixel(i, j);

                        _pixel2 = b2.GetPixel(i, j);

                        if (_pixel1 != _pixel2)

                        {

                            _flag = false;

                            break;

                        }

                    }

                }

            }

            return _flag;

        }

        /// <summary>

        /// memcmp API

        /// </summary>

        /// <param name="b1">字节数组1</param>

        /// <param name="b2">字节数组2</param>

        /// <returns>如果两个数组相同,返回0;如果数组1小于数组2,返回小于0的值;如果数组1大于数组2,返回大于0的值。</returns>

        [DllImport("msvcrt.dll")]

        private static extern IntPtr memcmp(byte[] b1, byte[] b2, IntPtr count);

        /// <summary>

        /// 通过比较bitmap两者byte[]来判断是否相等

        /// </summary>

        /// <param name="b1">Bitmap1</param>

        /// <param name="b2">Bitmap2</param>

        /// <returns>比较结果</returns>

        public static bool CompareByArray(this Bitmap b1, Bitmap b2)

        {

            /*说明

            *参考链接:

            *http://www.cnblogs.com/zgqys1980/archive/2009/07/13/1522546.html

            */

            IntPtr _result = new IntPtr(-1);

            MemoryStream _ms = new MemoryStream();

            try

            {

                b1.Save(_ms, ImageFormat.Png);

                byte[] _b1Array = _ms.ToArray();

                _ms.Position = 0;



                b2.Save(_ms, ImageFormat.Png);

                byte[] _b2Array = _ms.ToArray();



                _result = memcmp(_b1Array, _b2Array, new IntPtr(_b1Array.Length));

            }

            finally

            {

                _ms.Close();

            }

            return _result.ToInt32() == 0;

        }

    }

}
测试结果:

image

希望有所帮助!

你可能感兴趣的:(bitmap)