markus / ImageComparer / Markus.ImageComparer / ImageComparer.cs @ 6b6e937c
이력 | 보기 | 이력해설 | 다운로드 (12.3 KB)
1 |
using Emgu.CV; |
---|---|
2 |
using Emgu.CV.Structure; |
3 |
using System; |
4 |
using System.Collections.Generic; |
5 |
using System.Drawing; |
6 |
using System.Drawing.Imaging; |
7 |
using System.Linq; |
8 |
using System.Text; |
9 |
using System.Threading.Tasks; |
10 |
|
11 |
namespace Markus.Image |
12 |
{ |
13 |
public class ImageComparer : ImageComparerBase |
14 |
{ |
15 |
/// <summary> |
16 |
/// 이미지를 비교 후 원본 이미지에 Rect를 그린다. |
17 |
/// </summary> |
18 |
/// <param name="Originalbitmap">원본 이미지</param> |
19 |
/// <param name="TargatBitmap">비교대상 이미지</param> |
20 |
/// <param name="ResultRectSize">반환되는 Rect의 사이즈</param> |
21 |
/// <returns></returns> |
22 |
public Bitmap CompareDrawRects(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize) |
23 |
{ |
24 |
var rects = CompareReturnRects(Originalbitmap, TargatBitmap, ResultRectSize); |
25 |
|
26 |
if (rects.Count != 0) |
27 |
{ |
28 |
using (Graphics g = Graphics.FromImage(Originalbitmap)) |
29 |
{ |
30 |
var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height)); |
31 |
|
32 |
g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray()); |
33 |
g.Save(); |
34 |
|
35 |
g.Dispose(); |
36 |
} |
37 |
} |
38 |
|
39 |
return Originalbitmap; |
40 |
} |
41 |
|
42 |
public System.Windows.Media.Imaging.BitmapSource CompareDrawRects(System.Windows.Media.Imaging.BitmapSource Originalbitmap, System.Windows.Media.Imaging.BitmapSource TargatBitmap, Size ResultRectSize) |
43 |
{ |
44 |
var _Originalbitmap = CreateBitmapFromSource(Originalbitmap); |
45 |
var _TargatBitmap = CreateBitmapFromSource(TargatBitmap); |
46 |
|
47 |
var rects = CompareReturnRects(_Originalbitmap, _TargatBitmap, ResultRectSize); |
48 |
|
49 |
if (rects.Count != 0) |
50 |
{ |
51 |
using (Graphics g = Graphics.FromImage(_Originalbitmap)) |
52 |
{ |
53 |
var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height)); |
54 |
|
55 |
g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray()); |
56 |
g.Save(); |
57 |
|
58 |
g.Dispose(); |
59 |
} |
60 |
} |
61 |
|
62 |
return CreateBitmapSourceFromBitmap(_Originalbitmap); |
63 |
} |
64 |
|
65 |
public List<System.Windows.Rect> CompareReturnRects(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize) |
66 |
{ |
67 |
List<System.Windows.Rect> result = new List<System.Windows.Rect>(); |
68 |
|
69 |
Bitmap Originalbitmap = null; |
70 |
Bitmap TargatBitmap = null; |
71 |
|
72 |
try |
73 |
{ |
74 |
|
75 |
Originalbitmap = LoadPicture(OriginalbitmapUri); |
76 |
TargatBitmap = LoadPicture(TargatBitmapUri); |
77 |
|
78 |
result = CompareReturnRects(Originalbitmap, TargatBitmap, ResultRectSize); |
79 |
} |
80 |
catch (Exception) |
81 |
{ |
82 |
throw; |
83 |
} |
84 |
finally |
85 |
{ |
86 |
Originalbitmap.Dispose(); |
87 |
TargatBitmap.Dispose(); |
88 |
} |
89 |
|
90 |
return result; |
91 |
} |
92 |
|
93 |
/// <summary> |
94 |
/// 이미지를 비교 후 해당 영역을 Rect로 반환한다. |
95 |
/// </summary> |
96 |
/// <param name="Originalbitmap">원본 이미지</param> |
97 |
/// <param name="TargatBitmap">비교대상 이미지</param> |
98 |
/// <param name="ResultRectSize">반환되는 Rect의 사이즈</param> |
99 |
/// <returns></returns> |
100 |
public List<System.Windows.Rect> CompareReturnRects(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize) |
101 |
{ |
102 |
List<System.Windows.Rect> result = new List<System.Windows.Rect>(); |
103 |
|
104 |
try |
105 |
{ |
106 |
byte[,,] data = MathchesImageData(Originalbitmap, TargatBitmap); |
107 |
|
108 |
result = GetMatchPixels(data, ResultRectSize); |
109 |
} |
110 |
catch (Exception ex) |
111 |
{ |
112 |
throw ex; |
113 |
} |
114 |
finally |
115 |
{ |
116 |
|
117 |
} |
118 |
|
119 |
return result; |
120 |
} |
121 |
|
122 |
/// <summary> |
123 |
/// 이미지를 비교 후 원본 이미지에 Rect를 그린다. |
124 |
/// 메모리 문제 발생 |
125 |
/// </summary> |
126 |
/// <param name="Originalbitmap">원본 이미지</param> |
127 |
/// <param name="TargatBitmap">비교대상 이미지</param> |
128 |
/// <param name="ResultRectSize">반환되는 Rect의 사이즈</param> |
129 |
/// <returns></returns> |
130 |
public async Task<Bitmap> CompareDrawRectsAsync(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize) |
131 |
{ |
132 |
System.Drawing.Bitmap cloneOriginal = Originalbitmap; |
133 |
|
134 |
var rects = await CompareReturnRectsAsync(cloneOriginal, TargatBitmap, ResultRectSize); |
135 |
|
136 |
if (rects.Count != 0) |
137 |
{ |
138 |
using (Graphics g = Graphics.FromImage(cloneOriginal)) |
139 |
{ |
140 |
var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height)); |
141 |
|
142 |
g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray()); |
143 |
g.Save(); |
144 |
|
145 |
g.Dispose(); |
146 |
} |
147 |
} |
148 |
|
149 |
return cloneOriginal; |
150 |
} |
151 |
|
152 |
/// <summary> |
153 |
/// 이미지를 비교 후 원본 이미지에 Rect를 그린다. |
154 |
/// 메모리 문제 발생 |
155 |
/// </summary> |
156 |
/// <param name="Originalbitmap">원본 이미지</param> |
157 |
/// <param name="TargatBitmap">비교대상 이미지</param> |
158 |
/// <param name="ResultRectSize">반환되는 Rect의 사이즈</param> |
159 |
/// <returns></returns> |
160 |
public async Task<System.Windows.Media.Imaging.BitmapSource> CompareDrawRectsAsync(System.Windows.Media.Imaging.BitmapSource Originalbitmap, System.Windows.Media.Imaging.BitmapSource TargatBitmap, Size ResultRectSize) |
161 |
{ |
162 |
|
163 |
var _Originalbitmap = CreateBitmapFromSource(Originalbitmap); |
164 |
var _TargatBitmap = CreateBitmapFromSource(TargatBitmap); |
165 |
|
166 |
var rects = await CompareReturnRectsAsync(_Originalbitmap, _TargatBitmap, ResultRectSize); |
167 |
|
168 |
if (rects.Count != 0) |
169 |
{ |
170 |
using (Graphics g = Graphics.FromImage(_Originalbitmap)) |
171 |
{ |
172 |
var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height)); |
173 |
|
174 |
g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray()); |
175 |
g.Save(); |
176 |
|
177 |
g.Dispose(); |
178 |
} |
179 |
} |
180 |
|
181 |
return CreateBitmapSourceFromBitmap(_Originalbitmap); |
182 |
} |
183 |
|
184 |
public Bitmap CreateBitmapFromSource(System.Windows.Media.Imaging.BitmapSource bitmapsource) |
185 |
{ |
186 |
//convert image format |
187 |
var src = new System.Windows.Media.Imaging.FormatConvertedBitmap(); |
188 |
src.BeginInit(); |
189 |
src.Source = bitmapsource; |
190 |
src.DestinationFormat = System.Windows.Media.PixelFormats.Bgr24; |
191 |
src.EndInit(); |
192 |
|
193 |
//copy to bitmap |
194 |
Bitmap bitmap = new Bitmap(src.PixelWidth, src.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb); |
195 |
var data = bitmap.LockBits(new Rectangle(Point.Empty, bitmap.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); |
196 |
src.CopyPixels(System.Windows.Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride); |
197 |
bitmap.UnlockBits(data); |
198 |
|
199 |
return bitmap; |
200 |
} |
201 |
|
202 |
/// <summary> |
203 |
/// 메모리 문제 발생 |
204 |
/// </summary> |
205 |
/// <param name="bitmap"></param> |
206 |
/// <returns></returns> |
207 |
public System.Windows.Media.Imaging.WriteableBitmap CreateWriteableBitmapFromBitmap(Bitmap bitmap) |
208 |
{ |
209 |
System.Windows.Media.Imaging.WriteableBitmap result = null; |
210 |
|
211 |
if (bitmap == null) |
212 |
throw new ArgumentNullException("bitmap"); |
213 |
|
214 |
try |
215 |
{ |
216 |
int bytesPerPixel = 4; |
217 |
|
218 |
result = new System.Windows.Media.Imaging.WriteableBitmap(bitmap.Width, bitmap.Height, |
219 |
bitmap.HorizontalResolution ,bitmap.VerticalResolution, |
220 |
bitmap.PixelFormat.Convert(), null); |
221 |
|
222 |
Rectangle colorBitmapRectangle = new Rectangle(0, 0, bitmap.Width, bitmap.Height); |
223 |
System.Windows.Int32Rect colorBitmapInt32Rect = new System.Windows.Int32Rect(0, 0, bitmap.Width, bitmap.Height); |
224 |
|
225 |
BitmapData data = bitmap.LockBits(colorBitmapRectangle, ImageLockMode.WriteOnly, bitmap.PixelFormat); |
226 |
|
227 |
result.WritePixels(colorBitmapInt32Rect, data.Scan0, data.Width * data.Height * bytesPerPixel, data.Stride); |
228 |
|
229 |
bitmap.UnlockBits(data); |
230 |
} |
231 |
catch (Exception ex) |
232 |
{ |
233 |
//throw ex; |
234 |
} |
235 |
finally |
236 |
{ |
237 |
bitmap.Dispose(); |
238 |
bitmap = null; |
239 |
//GC.Collect(2); |
240 |
} |
241 |
|
242 |
return result; |
243 |
} |
244 |
|
245 |
/// <summary> |
246 |
/// 메모리 문제 발생 |
247 |
/// </summary> |
248 |
/// <param name="bitmap"></param> |
249 |
/// <returns></returns> |
250 |
public System.Windows.Media.Imaging.BitmapSource CreateBitmapSourceFromBitmap(Bitmap bitmap) |
251 |
{ |
252 |
System.Windows.Media.Imaging.BitmapSource result = null; |
253 |
|
254 |
if (bitmap == null) |
255 |
throw new ArgumentNullException("bitmap"); |
256 |
|
257 |
try |
258 |
{ |
259 |
using (var hbitmap = new SafeHBitmapHandle(bitmap.GetHbitmap(), true)) |
260 |
{ |
261 |
|
262 |
result = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap( |
263 |
hbitmap.DangerousGetHandle(), |
264 |
IntPtr.Zero, |
265 |
System.Windows.Int32Rect.Empty, |
266 |
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions()); |
267 |
|
268 |
|
269 |
} |
270 |
} |
271 |
catch (Exception ex) |
272 |
{ |
273 |
//throw ex; |
274 |
} |
275 |
finally |
276 |
{ |
277 |
bitmap.Dispose(); |
278 |
bitmap = null; |
279 |
//GC.Collect(2); |
280 |
} |
281 |
|
282 |
return result; |
283 |
} |
284 |
|
285 |
public async Task<List<System.Windows.Rect>> CompareReturnRectsAsync(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize) |
286 |
{ |
287 |
List<System.Windows.Rect> result = new List<System.Windows.Rect>(); |
288 |
|
289 |
Bitmap Originalbitmap = null; |
290 |
Bitmap TargatBitmap = null; |
291 |
|
292 |
try |
293 |
{ |
294 |
|
295 |
Originalbitmap = LoadPicture(OriginalbitmapUri); |
296 |
TargatBitmap = LoadPicture(TargatBitmapUri); |
297 |
|
298 |
result = await CompareReturnRectsAsync(Originalbitmap, TargatBitmap, ResultRectSize); |
299 |
} |
300 |
catch (Exception) |
301 |
{ |
302 |
throw; |
303 |
} |
304 |
finally |
305 |
{ |
306 |
Originalbitmap.Dispose(); |
307 |
TargatBitmap.Dispose(); |
308 |
} |
309 |
|
310 |
return result; |
311 |
} |
312 |
|
313 |
/// <summary> |
314 |
/// 이미지를 비교 후 해당 영역을 Rect로 반환한다. |
315 |
/// </summary> |
316 |
/// <param name="Originalbitmap">원본 이미지</param> |
317 |
/// <param name="TargatBitmap">비교대상 이미지</param> |
318 |
/// <param name="ResultRectSize">반환되는 Rect의 사이즈</param> |
319 |
/// <returns></returns> |
320 |
public async Task<List<System.Windows.Rect>> CompareReturnRectsAsync(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize) |
321 |
{ |
322 |
List<System.Windows.Rect> result = new List<System.Windows.Rect>(); |
323 |
|
324 |
try |
325 |
{ |
326 |
byte[,,] data = MathchesImageData(Originalbitmap, TargatBitmap); |
327 |
|
328 |
result = await GetMatchPixelsAsnc(data, ResultRectSize); |
329 |
|
330 |
data = null; |
331 |
} |
332 |
catch (Exception ex) |
333 |
{ |
334 |
throw ex; |
335 |
} |
336 |
finally |
337 |
{ |
338 |
} |
339 |
|
340 |
return result; |
341 |
} |
342 |
|
343 |
|
344 |
protected override void Dispose(bool disposing) |
345 |
{ |
346 |
base.Dispose(disposing); |
347 |
} |
348 |
} |
349 |
} |