c#高效比对大量图片
比较图片的方法
以前传统的比较方式是遍历图片中的每一个像素,然后进行比对。这样的比对在少量图片的比对上虽然效率低一点,但是也没有什么不好。但是在大量图片比对的时候,过长的反应时间和对服务器比较高的消耗肯定是不行的。
所以微软给我们提供了另外一种比对的方法,能够正确,高效的比对出两张图片的是否相同。这种方法的原理是:将图片保存到数据流中然后使用Convert.ToBase64String将数据流转换为字符串,那么我们只需要比对两张图片的字符串就ok了。代码如下:
public bool CheckImg(string filePath1, string filePath2)
{ MemoryStream ms1 = new MemoryStream();
Image image1 = Image.FromFile(filePath1);
image1.Save(ms1, System.Drawing.Imaging.ImageFormat.Jpeg); string img1 = Convert.ToBase64String(ms1.ToArray()); Image image2 = Image.FromFile(filePath2);
image2.Save(ms1, System.Drawing.Imaging.ImageFormat.Jpeg);
string img2 = Convert.ToBase64String(ms1.ToArray()); if (img1.Equals(img2))
{
return true;
}
else
{
return false;
}
}
比较图片
这种方法我使用控制台测试了下时间,时间大概为0.015s左右比较一张图片的时间。还是比较高效的。
大量图片的比较
比较两张图片能够满足需求,那么大量呢? 我这边也做了这种测试的。在450张图片中,选择出其中重复的图片,并展示出来。大概时间是16s左右,基本能够满足大部分的需求了。
比较方法是,先讲450张图片,全部一次性转换为string类型,存放到一个数组里面,这样就避免了每次循环都要额外的去转换,使程序的效率降低很多。
public static List<Dictionary<string, string>> chekImgss(string filePath)
{ List<Dictionary<string, string>> liststr = new List<Dictionary<string, string>>();
DirectoryInfo dir = new DirectoryInfo(filePath);
FileInfo[] files = dir.GetFiles();
foreach (FileInfo fileInfo in files)
{
Dictionary<string, string> dic = new Dictionary<string, string>();
string ex = fileInfo.Extension;
if (ex == ".jpg" || ex == ".png")
{
MemoryStream ms1 = new MemoryStream();
Image image2 = Image.FromFile(filePath + fileInfo.Name);
image2.Save(ms1, System.Drawing.Imaging.ImageFormat.Jpeg); string imgBase64 = Convert.ToBase64String(ms1.ToArray()); dic["base64"] = imgBase64;
dic["imgName"] = fileInfo.Name;
liststr.Add(dic);
}
} return liststr;
}
将图片的base64string和图片的名称存储在一个dictionary中,然后存储到list数组中。这样我们在比较的时候,只需要判断两个字符串是否相等就可以了。
/// <summary>
/// 对数组进行深拷贝
/// </summary>
/// <param name="files"></param>
/// <returns></returns>
public static List<Dictionary<string, string>> CopyList(List<Dictionary<string, string>> files)
{
MemoryStream ms = new MemoryStream();//序列化
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, files);
ms.Position = ; List<Dictionary<string, string>> array3 = (List<Dictionary<string, string>>)bf.Deserialize(ms); //反序列化
return array3;
} /// <summary>
/// 比较图片
/// </summary>
/// <param name="listDic"></param>
/// <param name="filePath"></param>
/// <returns></returns>
public static List<Dictionary<object, string>> chekImg2(List<Dictionary<string, string>> listDic,string filePath)
{
List<Dictionary<object, string>> list = new List<Dictionary<object, string>>(); DirectoryInfo dir = new DirectoryInfo(filePath);
var files = dir.GetFiles().ToList(); for (int j = ; j < listDic.Count; j++)
{
var file = listDic[j]; var fileList = CopyList(listDic);
var index = ;
var isFirst = false;
Dictionary<object, string> dic = new Dictionary<object, string>();
for (int i = ; i < fileList.Count; i++)
{
var fileInfo = fileList[i]; if (file["imgName"] == fileInfo["imgName"])
{
fileList.Remove(fileInfo);
i -= ;
continue;
}
//使用equals比普通的,string==string 高效很多倍
if (file["base64"].Equals(fileInfo["base64"]))
{
if (!isFirst)
{
dic[++index] = file["imgName"];
isFirst = true;
}
dic[++index] = fileInfo["imgName"]; fileList.Remove(fileInfo); listDic.Remove(listDic.Where(c => c.Values.Contains(fileInfo["imgName"])).FirstOrDefault());
i -= ;
}
else
{
fileList.Remove(fileInfo);
i -= ;
} } if (dic.Keys.Count > )
{
list.Add(dic);
listDic.Remove(file);
j -= ;
}
else
{
listDic.Remove(file);
j -= ;
}
}
return list;
}
这样,我们就可以将完全相同的图片都取出来存放在一个dictionary中,每一组相同的都是一个dictionary,然后存放到list数组中。需要的时候遍历出来就可以了。
总结
大量比对的时候,最好先将图片转换为string吧。如果在两个for里面实现这个转换,时间会是现在的很多倍,因为造成了许多重复的转换。然后在比对的过程中,尽量将已经比对过的图片从数组中剔除,这样比对,你会发现越来越快。
c#高效比对大量图片的更多相关文章
- (源代码分析)Android-Universal-Image-Loader (图片异步载入缓存库)的使用配置
转载请注明出处:http://blog.csdn.net/u011733020 前言: 在Android开发中,对于图片的载入能够说是个老生常谈的问题了,图片载入是一个比較坑的地方.处理不好,会有各种 ...
- [翻译]开发文档:android Bitmap的高效使用
内容概述 本文内容来自开发文档"Traning > Displaying Bitmaps Efficiently",包括大尺寸Bitmap的高效加载,图片的异步加载和数据缓存 ...
- Android高效加载大图、多图解决方案,有效避免程序OOM
高效加载大图片 我们在编写Android程序的时候经常要用到许多图片,不同图片总是会有不同的形状.不同的大小,但在大多数情况下,这些图片都会大于我们程序所需要的大小.比如说系统图片库里展示的图片大都是 ...
- Android高效加载大图、多图解决方案,有效避免程序OOM(转)
本篇文章主要内容来自于Android Doc,我翻译之后又做了些加工,英文好的朋友也可以直接去读原文. http://developer.android.com/training/displaying ...
- 【译】快速高效学习Java编程在线资源Top 20
想要加强你的编程能力吗?想要提升你的 Java 编程技巧和效率吗? 不用担心.本文将会提供快速高效学习 Java 编程的 50 多个网站资源: 开始探索吧: 1.MKyong:许多开发者在这里可以找到 ...
- 快速高效学习Java编程在线资源Top 20(转载)
想要加强你的编程能力吗?想要提升你的 Java 编程技巧和效率吗? 不用担心.本文将会提供快速高效学习 Java 编程的 50 多个网站资源: 开始探索吧: 1.MKyong:许多开发者在这里可以找到 ...
- 如何高效、快速学习Flutter?如何避坑?(文末送服福利)
稳住,今天是周末,不过我今天要上班....啊..啊... 对于 Flutter 我没有太多的发言权,不过GSY是对 Flutter 充分理解并精深掌握的前辈了,所以转一篇他对 Flutter 的一些解 ...
- 从I/O复用谈epoll为什么高效
上一篇文章中,谈了一些网络编程的基本概念.在现实使用中,用的最多的就是I/O复用了,无非就是select,poll,epoll 很多人提到网络就说epoll,认为epoll效率是最高的.单纯的这么认为 ...
- 利用on和off方法编写高效的js代码
先说下将这个话题的起因:最近发现公司的功能代码,很多在dom对象删除以后,其声明的绑定在window上的resize事件还一直存在,导致相同的功能代码执行了几次.对于我这种轻微代码洁癖的人来说,简直是 ...
随机推荐
- 查看linux的版本
1. uname -a ~$ uname -a Linux lubuntu-Vostro-A840 3.19.0-73-generic #81-Ubuntu SMP Tue Oct 18 16:02: ...
- 为什么选择 Yeoman 及 Yeoman 的安装
今天向您介绍一个我刚接触到的比较新的网络前端开发工具: Yeoman . 什么是Yeoman? Yeoman是Google的团队和外部贡献者团队合作开发的一个项目.通过内部三个工具(yo,grunt, ...
- springmvc 注解 RequestParam/RequestHeader/CookieValue
RequestParam注解: 示例: @RequestMapping("/testRequestParam") public String testRequestParam(@R ...
- [SQL]SQL语言入门级教材_SQL语言快速入门(五)
SQL语言快速入门(一) SQL是英文Structured Query Language的缩写,意思为结构化查询语言. SQL语言的主要功能就是同各种数据库建立联系,进行沟通.按照ANSI(美国国家标 ...
- poj 1328 Radar Installation(nyoj 287 Radar):贪心
点击打开链接 Radar Installation Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 43490 Accep ...
- uva 11488 Hyper Prefix Sets(狂水)
题意: 获得集合中最长前缀长度*有该前缀个数的最大值 Prefix goodness of a set string is length of longest common prefix*number ...
- [Android疑难杂症]动态改变Background后Padding无效的问题
前言 在Layout中指定好background和padding以后,程序里面动态修改background之后padding就失效了,貌似是一个BUG,这里找到了一篇英文文章,简单翻译分享一下. 声明 ...
- JAVA设计模式之调停者模式
在阎宏博士的<JAVA与模式>一书中开头是这样描述调停者(Mediator)模式的: 调停者模式是对象的行为模式.调停者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显引用.从 ...
- OC基础(8)
自定义代码段 实例变量修饰符 依赖关系 *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bott ...
- windows中 dll 的解读
背景: dll 可以认为是exe 的分割,分割的好处就是多个exe 可以共用一个dll.所以就有了dll的依赖问题 问题来源: 当我们安装软件时(windows系统下),报出:XX.dll 缺失,或 ...