|
以前傳統(tǒng)的比較方式是遍歷圖片中的每一個(gè)像素,然后進(jìn)行比對(duì)。這樣的比對(duì)在少量圖片的比對(duì)上雖然效率低一點(diǎn),但是也沒有什么不好。但是在大量圖片比對(duì)的時(shí)候,過長(zhǎng)的反應(yīng)時(shí)間和對(duì)服務(wù)器比較高的消耗肯定是不行的。 所以微軟給我們提供了另外一種比對(duì)的方法,能夠正確,高效的比對(duì)出兩張圖片的是否相同。這種方法的原理是:將圖片保存到數(shù)據(jù)流中然后使用Convert.ToBase64String將數(shù)據(jù)流轉(zhuǎn)換為字符串,那么我們只需要比對(duì)兩張圖片的字符串就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); if (img1.Equals(img2)) 這種方法我使用控制臺(tái)測(cè)試了下時(shí)間,時(shí)間大概為0.015s左右比較一張圖片的時(shí)間。還是比較高效的。 大量圖片的比較 比較方法是,先講450張圖片,全部一次性轉(zhuǎn)換為string類型,存放到一個(gè)數(shù)組里面,這樣就避免了每次循環(huán)都要額外的去轉(zhuǎn)換,使程序的效率降低很多。 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; return liststr; 將圖片的base64string和圖片的名稱存儲(chǔ)在一個(gè)dictionary中,然后存儲(chǔ)到list數(shù)組中。這樣我們?cè)诒容^的時(shí)候,只需要判斷兩個(gè)字符串是否相等就可以了。 /// <summary> /// 對(duì)數(shù)組進(jìn)行深拷貝 /// </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 = 0; List<Dictionary<string, string>> array3 = (List<Dictionary<string, string>>)bf.Deserialize(ms); //反序列化 /// <summary> DirectoryInfo dir = new DirectoryInfo(filePath); for (int j = 0; j < listDic.Count; j++) if (file["imgName"] == fileInfo["imgName"]) fileList.Remove(fileInfo); listDic.Remove(listDic.Where(c => c.Values.Contains(fileInfo["imgName"])).FirstOrDefault()); } if (dic.Keys.Count > 0) 這樣,我們就可以將完全相同的圖片都取出來存放在一個(gè)dictionary中,每一組相同的都是一個(gè)dictionary,然后存放到list數(shù)組中。需要的時(shí)候遍歷出來就可以了。 總結(jié) 大量比對(duì)的時(shí)候,最好先將圖片轉(zhuǎn)換為string吧。如果在兩個(gè)for里面實(shí)現(xiàn)這個(gè)轉(zhuǎn)換,時(shí)間會(huì)是現(xiàn)在的很多倍,因?yàn)樵斐闪嗽S多重復(fù)的轉(zhuǎn)換。然后在比對(duì)的過程中,盡量將已經(jīng)比對(duì)過的圖片從數(shù)組中剔除,這樣比對(duì),你會(huì)發(fā)現(xiàn)越來越快。 |
|
|