C# 比较位图列表中图像的最佳方法是什么
我正在开发一个应用程序,在这个应用程序中,我可以在一个列表中加载多张图片,并将该列表中的每张图片相互比较,以便找到重复的图片 因此,首先我成功地获取了图片并将其加载到C# 比较位图列表中图像的最佳方法是什么,c#,algorithm,performance,C#,Algorithm,Performance,我正在开发一个应用程序,在这个应用程序中,我可以在一个列表中加载多张图片,并将该列表中的每张图片相互比较,以便找到重复的图片 因此,首先我成功地获取了图片并将其加载到IList: 我会避免对同一个图像多次计算哈希值,并且只在图像中循环一次: public static void Main(string[] args) { var files = new Dictionary<string, string>(); foreach (var file in Directo
IList
:
我会避免对同一个图像多次计算哈希值,并且只在图像中循环一次:
public static void Main(string[] args)
{
var files = new Dictionary<string, string>();
foreach (var file in Directory.GetFiles("c:\\", "*.png"))
{
files.Add(file, CalculateHash(file));
}
var duplicates = files.GroupBy(item => item.Value).Where(group => group.Count() > 1);
}
private static string CalculateHash(string file)
{
using (var stream = File.OpenRead(file))
{
var sha = new SHA256Managed();
var checksum = sha.ComputeHash(stream);
return BitConverter.ToString(checksum).Replace("-", String.Empty);
}
}
publicstaticvoidmain(字符串[]args)
{
var files=newdictionary();
foreach(Directory.GetFiles(“c:\\”,“*.png”)中的var文件)
{
文件.Add(文件,CalculateHash(文件));
}
var duplicates=files.GroupBy(item=>item.Value).Where(group=>group.Count()>1);
}
私有静态字符串CalculateHash(字符串文件)
{
使用(var stream=File.OpenRead(File))
{
var sha=新的SHA256Managed();
var校验和=sha.ComputeHash(流);
返回BitConverter.ToString(校验和)。替换(“-”,String.Empty);
}
}
您已经在计算每个图像的哈希值,因此可以将其转换为例如
字符串
,然后只需使用字典
,其中键
将是哈希值。您可以使用ContainsKey
快速确定图像哈希是否已在列表中
由于您是通过流打开图像文件,因此有一种更简单的方法可以从
stream
计算哈希值,如下所述。您可能需要倒带流来读取图像。而不是列表
,我会将其保存为定义为{image,Hash}
的自定义类,以便哈希只需计算一次。如果处理图像,该类也可以负责。其他信息,如路径名,可能也很方便,这取决于应用程序的功能。你不应该在列表中浏览两次,因为list[a]=list[b]
应该等于list[b]=list[a]
@RubensFarias是的,这是我试图避免做的第一件事哦,这是一个有趣的方法,我没有想到过,谢谢但是这不起作用,因为两个具有相同元素的byte[]
数组被认为是不相等的(对于GroupBy也是如此),所以这段代码不会检测到重复的数组(同样,Directory.GetFiles
也会因为这样的参数而失败,但这不是很重要)。我刚修好。
public static CompareResult Compare(Bitmap bmp1, Bitmap bmp2)
{
CompareResult cr = CompareResult.ciCompareOk;
//Test to see if we have the same size of image
if (bmp1.Size != bmp2.Size)
{
cr = CompareResult.ciSizeMismatch;
}
else
{
//Convert each image to a byte array
System.Drawing.ImageConverter ic =
new System.Drawing.ImageConverter();
byte[] btImage1 = new byte[1];
btImage1 = (byte[])ic.ConvertTo(bmp1, btImage1.GetType());
byte[] btImage2 = new byte[1];
btImage2 = (byte[])ic.ConvertTo(bmp2, btImage2.GetType());
//Compute a hash for each image
SHA256Managed shaM = new SHA256Managed();
byte[] hash1 = shaM.ComputeHash(btImage1);
byte[] hash2 = shaM.ComputeHash(btImage2);
//Compare the hash values
for (int i = 0; i < hash1.Length && i < hash2.Length
&& cr == CompareResult.ciCompareOk; i++)
{
if (hash1[i] != hash2[i])
cr = CompareResult.ciPixelMismatch;
}
}
return cr;
}
public void ComparePictureList()
{
IList<Bitmap> picturesList = getPictures();
foreach (var picture1 in picturesList)
{
foreach( var picture2 in picturesList)
{
Compare(picture1, picture2);
}
}
}
public Bitmap ConvertToBitmap(string fileName)
{
Bitmap bitmap;
using (Stream bmpStream = System.IO.File.Open(fileName, System.IO.FileMode.Open))
{
Image image = Image.FromStream(bmpStream);
bitmap = new Bitmap(image);
}
return bitmap;
}
public static void Main(string[] args)
{
var files = new Dictionary<string, string>();
foreach (var file in Directory.GetFiles("c:\\", "*.png"))
{
files.Add(file, CalculateHash(file));
}
var duplicates = files.GroupBy(item => item.Value).Where(group => group.Count() > 1);
}
private static string CalculateHash(string file)
{
using (var stream = File.OpenRead(file))
{
var sha = new SHA256Managed();
var checksum = sha.ComputeHash(stream);
return BitConverter.ToString(checksum).Replace("-", String.Empty);
}
}