[C#] byte[] 비교하기(Image 비교하기)

Posted at 2013.02.11 12:33 | Posted in 프로그래밍

중복된 앨범 아트를 제거할 일이 생겨 비트 하나 하나를 문자열로 바꿔서 비교하는 방법을 시도해봤는데, 터무니 없이 오래 걸리는 시간과 부정확성에 포기하고 다음 메서드를 찾았다.

//stackoverflow.com/questions/2173414/c-sharp-byte-comparison-without-bound-checks
public static unsafe bool Compare(byte[] a, byte[] b) {
	if(a.Length != b.Length) return false;
	var len = a.Length;
	fixed(byte* ap = a, bp = b) {
		long* alp = (long*) ap, blp = (long*) bp;
		for(; len >= 8; len -= 8) {
			if(*alp != *blp) return false;
			alp++;
			blp++;
		}
		byte* ap2 = (byte*) alp, bp2 = (byte*) blp;
		for(; len > 0; len--) {
			if(*ap2 != *bp2) return false;
			ap2++;
			bp2++;
		}
	}
	return true;
}

unsafe 키워드가 붙어있으므로 프로젝트 속성에서 빌드 탭의 일반 항목에 있는 안전하지 않은 코드 허용에 체크해야된다.

위 메서드로 두 개의 이미지가 같은지 확인하려면 다음처럼 작성한다. ImageFormat은 대충보고 알맞은 거로 골라 작성하시라. 테스트 해봤을 땐 bmp가 가장 빠르고 다음이 jpeg, gif, png 순이더랍니다.

public void Duplicate(Image oImage, Image cImage) {
	using(var rel = new MemoryStream()) {
		oImage.Save(rel, ImageFormat.Bmp);
		using(var comp = new MemoryStream()) {
			cImage.Save(comp, ImageFormat.Bmp);
			if(Compare(rel.ToArray(), comp.ToArray())) MessageBox.Show("같다!");
			else MessageBox.Show("다르다!");
		}
	}
}

byteComparer.dll사용하기 쉽게 dll로 컴파일해 올려본다. IDE가 Visual Studio면 솔루션 탐색기의 프로젝트에서 참조를 우클릭하여 참조 추가를 하고, 찾아보기에서 이 dll을 찾아 추가하고 소스코드에서 byteComparer.Long.Compare(byte[], byte[]); 하면 bool값이 리턴된다.

저작자 표시 비영리
신고
  1. 심청사달
    이미지값 비교하는 것 잘봤습니다. 그런데 찾다보니 VS C# 내부적으로 배열값 비교를 지원해주는 함수가 있네요. 아무래도 이게 편하겠죠.^^;
    SequanceEqual()입니당

    http://blog.naver.com/progsta/50159675366
  2. 잠탱
    SequanceEqual 은 LINQ사용이 가능해야 되므로 ..net 3.5 이상이 필요합니다.
    또한 xx%일치 같은건 산출이 안되는 문제가 있습니다.

Name __

Password __

Link (Your Website)

Comment