[C#]几种Bitmap比较方式

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

大小:

关键代码:

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;
        }
    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }测试结果:

希望有所帮助!

[C#]几种Bitmap比较方式,布布扣,bubuko.com

时间: 2024-10-18 18:05:41

[C#]几种Bitmap比较方式的相关文章

ASP.NET MVC下的四种验证编程方式[续篇]

在<ASP.NET MVC下的四种验证编程方式>一文中我们介绍了ASP.NET MVC支持的四种服务端验证的编程方式("手工验证"."标注ValidationAttribute特性"."让数据类型实现IValidatableObject或者IDataErrorInfo"),那么在ASP.NET MVC框架内部是如何提供针对这四种不同编程方式的支持的呢?接下来我们就来聊聊这背后的故事. 一.ModelValidator与ModelVal

LVS:三种负载均衡方式比较+另三种负载均衡方式

转:http://blog.csdn.net/u013256816/article/details/50705578 什么是LVS? ??首先简单介绍一下LVS (Linux Virtual Server)到底是什么东西,其实它是一种集群(Cluster)技术,采用IP负载均衡技术和基于内容请求分发技术.调度器具有很好的吞吐率,将请求均衡地转移到不同的服务器上执行,且调度器自动屏蔽掉服务器的故障,从而将一组服务器构成一个高性能的.高可用的虚拟服务器.整个服务器集群的结构对客户是透明的,而且无需修

android五种数据存储方式

在Android中提供了如下五种数据存储方式: SharedPreferences 文件存储 SQLite数据库方式 内容提供器(ContentProvider) 网络存储 下面具体介绍一下这五种数据存储方式的用法. 1. SharedPreferences SharedPreferences是android平台上的一个轻量级存储类,主要保存一些常用的配置信息.可以保存long.int.String类型数据. SharedPreferences以键值对方式读取和存入,最终会以XML方式保存数据,

HBuilder开发App教程08-几种页面打开方式

说明 上节说了list页面的实现,其中关于几种页面的打开方式没有详细述说, 本节详细述说下几种页面打开方式的区别. 几种打开页面的方式 1.初始化时创建子页面 2.直接打开新页面 3.预加载页面 示例 1.初始化时创建子页面 mui.init({ subpages: [{ url: your - subpage - url, //子页面HTML地址,支持本地地址和网络地址 id: your - subpage - id, //子页面标志 styles: { top: subpage - top

jQuery自动补全插件使用,三种获取数据源方式

jQuery有很多很多的已经实现,很漂亮的插件,autocomplete就是其中之一.jQuery ui autocomplete主要支持字符串Array.JSON两种数据格式. 主要参数: Source:数据源,类型为String.Array.Function,其中String为ajax请求的服务器端地址,返回Array/JSON格式,Array即为数组,静态定义到页面中的数据,下面会有具体的  demo, Function(request,response):通过request.term获得

三种加载方式

重点总结:    即:三种加载方式    1>传统加载方式------默认路径:tomcat/bin/目录    2>使用ServletContext对象-----默认路径:web应用(工程)目录    3>使用类加载器------默认路径:WEB-INF/classes/目录 一.利用ServletContext对象读取资源文件--默认目录为:工程(应用)路径                重点方法:                        InputStream getReso

.NET中的三种接口实现方式

摘自:http://www.cnblogs.com/zhangronghua/archive/2009/11/25/1610713.html 一般来说.NET提供了三种不同的接口实现方式,分别为隐式接口实现.显式接口实现.混合式接口实现.这三种方式各有各的特点. 首先来看隐式接口实现,这恐怕是我们使用最多的一种接口实现,因为隐匿接口实现是.NET的默认接口实现方式.下面让我们来看一个隐式接口实现的例子: using System; internal class MyClass { public

即时通讯软件开发 几种网络编程方式

即时通讯软件开发 几种网络编程方式: ISAPI.CGI.WinInet.Winsock 它们之间的区别: 1)ISAPI主要是开发基于浏览器客户端与服务器端程序.效率比CGI方式高,而且也扩展了CGI没有的一些功能.(基于TCP/IP模型中的应用层) 2) CGI主要是开发基于浏览器客户端与服务器端程序.(基于TCP/IP模型中的应用层) 3) WinInet主要是开发客户端程序.(基于TCP/IP模型中的应用层) 4) Winsock主要是基于socket来开发客户端与服务器端程序.(基于T

Android4种网络连接方式HttpClient、HttpURLConnection、OKHttp和Volley优缺点和性能对比

比较的指标: 1.cpu 2.流量 3.电量 4.内存占用 5.联网时间 功能点: 1.重试机制 2.提供的扩展功能 3.易用性 4.是否https 5.是否支持reflect api,OkHttp有配套方法 6.缓存.重试 7.cookie支持session  id会话支持 8.弱网性能和稳定性 9.超时时间,几种超时时间   连接超时,响应超时 10.适配各种机型.4.4和之前版本  2.3  4.1 5.0 4种网络连接方式提供的功能对比表格: 缓存 重试 Https/Http 稳定性 C