프로젝트

일반

사용자정보

통계
| 브랜치(Branch): | 개정판:

markus / Markus.ImageComparer / ImageCompare.cs @ 52b1f175

이력 | 보기 | 이력해설 | 다운로드 (17.6 KB)

1 24c5e56c taeseongkim
using System;
2
using System.Collections.Generic;
3
using System.Drawing;
4
using System.Drawing.Imaging;
5
using System.Linq;
6
using System.Text;
7
using System.Threading.Tasks;
8
9
namespace Markus.Image
10
{
11
    public class ImageCompare : ImageCompareBase
12
    {
13
        /// <summary>
14
        /// 이미지를 비교 후 원본 이미지에 Rect를 그린다.
15
        /// </summary>
16
        /// <param name="Originalbitmap">원본 이미지</param>
17
        /// <param name="TargatBitmap">비교대상 이미지</param>
18
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
19 0c575433 taeseongkim
        /// <param name="ResultImageSize">반환되는 이미지 사이즈. 없으면 targat사이즈로 반환</param>
20
        /// <returns>TargetBitmap에 ResultRectSize의 크기로 변환된 부분이 표시되어 반환</returns>
21
        public Bitmap CompareDrawRects(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize, Size? ResultImageSize = null)
22 24c5e56c taeseongkim
        {
23 0c575433 taeseongkim
            Size resultImageSize = TargatBitmap.Size;
24
25
            if (ResultImageSize.HasValue)
26
            {
27
                resultImageSize = ResultImageSize.Value;
28
            }
29
30
            var rects =  CompareReturnRects(Originalbitmap, TargatBitmap, ResultRectSize , resultImageSize);
31 24c5e56c taeseongkim
32
            if (rects.Count != 0)
33
            {
34 0c575433 taeseongkim
                Bitmap newBitmap = new Bitmap(resultImageSize.Width, resultImageSize.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
35 c1659a98 taeseongkim
           
36
                using (Graphics g = Graphics.FromImage(newBitmap))
37 38d69491 taeseongkim
                {
38 0c575433 taeseongkim
                    g.DrawImage(TargatBitmap, 0, 0);
39 38d69491 taeseongkim
                }
40
41 c1659a98 taeseongkim
                using (Graphics g = Graphics.FromImage(newBitmap))
42 24c5e56c taeseongkim
                {
43
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height)).ToList();
44
45
                    g.DrawRectangles(new Pen(Brushes.Red, 5f), rect.ToArray());
46
                    g.Save();
47
48
                    g.Dispose();
49
                }
50 c1659a98 taeseongkim
51
                Originalbitmap = newBitmap;
52 24c5e56c taeseongkim
            }
53
54
            return Originalbitmap;
55
        }
56
57 0c575433 taeseongkim
        public System.Windows.Media.Imaging.BitmapSource CompareDrawRects(System.Windows.Media.Imaging.BitmapSource Originalbitmap, System.Windows.Media.Imaging.BitmapSource TargatBitmap,  Size ResultRectSize, Size? ResultImageSize = null)
58 24c5e56c taeseongkim
        {
59
            var _Originalbitmap = CreateBitmapFromSource(Originalbitmap);
60
            var _TargatBitmap = CreateBitmapFromSource(TargatBitmap);
61
62 0c575433 taeseongkim
            var rects = CompareReturnRects(_Originalbitmap, _TargatBitmap, ResultRectSize,ResultImageSize);
63 24c5e56c taeseongkim
         
64
            if (rects.Count != 0)
65
            {
66 0c575433 taeseongkim
                using (Graphics g = Graphics.FromImage(_TargatBitmap))
67 24c5e56c taeseongkim
                {
68
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
69
70
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
71
                    g.Save();
72
73
                    g.Dispose();
74
                }
75
            }
76
77 0c575433 taeseongkim
            return CreateBitmapSourceFromBitmap(_TargatBitmap);
78 24c5e56c taeseongkim
        }
79
80 0c575433 taeseongkim
        public List<System.Windows.Rect> CompareReturnRects(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize, Size? ResultImageSize = null)
81 24c5e56c taeseongkim
        {
82
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
83
84
            Bitmap Originalbitmap = null;
85
            Bitmap TargatBitmap = null;
86
87
            try
88
            {
89
                Originalbitmap = LoadPicture(OriginalbitmapUri);
90
                TargatBitmap = LoadPicture(TargatBitmapUri);
91
92 0c575433 taeseongkim
                result = CompareReturnRects(Originalbitmap, TargatBitmap, ResultRectSize, ResultImageSize);
93
            }
94
            catch (Exception)
95
            {
96
                throw;
97
            }
98
            finally
99
            {
100
                Originalbitmap.Dispose();
101
                TargatBitmap.Dispose();
102
            }
103
104
            return result;
105
        }
106
107
108
        public List<System.Windows.Rect> CompareReturnRects(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize, bool IsResultTargetSize = false)
109
        {
110
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
111
112
            Bitmap Originalbitmap = null;
113
            Bitmap TargatBitmap = null;
114
115
            try
116
            {
117
                Originalbitmap = LoadPicture(OriginalbitmapUri);
118
                TargatBitmap = LoadPicture(TargatBitmapUri);
119
120
                Size resultImageSize = Originalbitmap.Size;
121
122
                if (IsResultTargetSize)
123
                {
124
                    resultImageSize = TargatBitmap.Size;
125
                }
126
127
                result = CompareReturnRects(Originalbitmap, TargatBitmap, ResultRectSize, resultImageSize);
128 24c5e56c taeseongkim
            }
129
            catch (Exception)
130
            {
131
                throw;
132
            }
133
            finally
134
            {
135
                Originalbitmap.Dispose();
136
                TargatBitmap.Dispose();
137
            }
138
139
            return result;
140
        }
141 a860bafc taeseongkim
        public List<System.Windows.Rect> CompareReturnRects(System.Windows.Media.Imaging.BitmapFrame OriginalbitmapFrame, System.Windows.Media.Imaging.BitmapFrame TargatBitmapFrame, Size ResultRectSize, Size? ResultImageSize = null)
142
        {
143
            return CompareReturnRects(Converter.ConvertBitmapFrameToBitmap(OriginalbitmapFrame), Converter.ConvertBitmapFrameToBitmap(TargatBitmapFrame), ResultRectSize, ResultImageSize);
144
        }
145 24c5e56c taeseongkim
146
        /// <summary>
147
        /// 이미지를 비교 후 해당 영역을 Rect로 반환한다.
148
        /// </summary>
149
        /// <param name="Originalbitmap">원본 이미지</param>
150
        /// <param name="TargatBitmap">비교대상 이미지</param>
151
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
152
        /// <returns></returns>
153 0c575433 taeseongkim
        public List<System.Windows.Rect> CompareReturnRects(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize , Size? ResultImageSize = null)
154 24c5e56c taeseongkim
        {
155
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
156
157
            try
158
            {
159 0c575433 taeseongkim
                Size resultImageSize = TargatBitmap.Size;
160 24c5e56c taeseongkim
161 0c575433 taeseongkim
                if (ResultImageSize.HasValue)
162
                {
163
                    resultImageSize = ResultImageSize.Value;
164
                }
165
166
                List<System.Windows.Rect> rects = new List<System.Windows.Rect>();
167 c1659a98 taeseongkim
168 0c575433 taeseongkim
                var data = MathchesImageData(Originalbitmap, TargatBitmap, resultImageSize);
169
                
170 24c5e56c taeseongkim
                result =  GetMatchPixels(data, ResultRectSize);
171
172 0c575433 taeseongkim
173
                //var data2 = MathchesImageData(TargatBitmap,Originalbitmap, Originalbitmap.Size);
174
175
                //result.AddRange(GetMatchPixels(data2, ResultRectSize));
176
177
                //result = result.Distinct().ToList();
178 24c5e56c taeseongkim
                //if (rects.Count() > 0)
179
                //{
180
                //    result = Merge(rects, ResultRectSize.Height);
181
                //}
182
183
                //result = JoinRectList(rects);
184
            }
185
            catch (Exception ex)
186
            {
187
                throw ex;
188
            }
189
            finally
190
            {
191 a860bafc taeseongkim
                Originalbitmap.Dispose();
192
                TargatBitmap.Dispose();
193 24c5e56c taeseongkim
            }
194
195
            return result;
196
        }
197
198
        /// <summary>
199
        /// 이미지를 비교 후 원본 이미지에 Rect를 그린다.
200
        /// 메모리 문제 발생
201
        /// </summary>
202
        /// <param name="Originalbitmap">원본 이미지</param>
203
        /// <param name="TargatBitmap">비교대상 이미지</param>
204
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
205
        /// <returns></returns>
206 0c575433 taeseongkim
        public async Task<Bitmap> CompareDrawRectsAsync(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize, Size? ResultImageSize = null)
207 24c5e56c taeseongkim
        {
208
            System.Drawing.Bitmap cloneOriginal = Originalbitmap;
209
210 0c575433 taeseongkim
            var rects = await CompareReturnRectsAsync(cloneOriginal, TargatBitmap, ResultRectSize, ResultImageSize);
211 24c5e56c taeseongkim
212
            if (rects.Count != 0)
213
            {
214
                using (Graphics g = Graphics.FromImage(cloneOriginal))
215
                {
216
               
217
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
218
219
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
220
                    g.Save();
221
222
                    g.Dispose();
223
                }
224
            }
225
226
            return cloneOriginal;
227
        }
228
229
        /// <summary>
230
        /// 이미지를 비교 후 원본 이미지에 Rect를 그린다.
231
        /// 메모리 문제 발생
232
        /// </summary>
233
        /// <param name="Originalbitmap">원본 이미지</param>
234
        /// <param name="TargatBitmap">비교대상 이미지</param>
235
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
236
        /// <returns></returns>
237 0c575433 taeseongkim
        public async Task<System.Windows.Media.Imaging.BitmapSource> CompareDrawRectsAsync(System.Windows.Media.Imaging.BitmapSource Originalbitmap, System.Windows.Media.Imaging.BitmapSource TargatBitmap, Size ResultRectSize, Size? ResultImageSize = null)
238 24c5e56c taeseongkim
        {
239
240
            var _Originalbitmap = CreateBitmapFromSource(Originalbitmap);
241
            var _TargatBitmap = CreateBitmapFromSource(TargatBitmap);
242
243 0c575433 taeseongkim
            var rects = await CompareReturnRectsAsync(_Originalbitmap, _TargatBitmap, ResultRectSize,ResultImageSize);
244 24c5e56c taeseongkim
245
            if (rects.Count != 0)
246
            {
247
                using (Graphics g = Graphics.FromImage(_Originalbitmap))
248
                {
249
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
250
251
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
252
                    g.Save();
253
254
                    g.Dispose();
255
                }
256
            }
257
258
            return CreateBitmapSourceFromBitmap(_Originalbitmap);
259
        }
260
261
        public Bitmap CreateBitmapFromSource(System.Windows.Media.Imaging.BitmapSource bitmapsource)
262
        {
263
            //convert image format
264
            var src = new System.Windows.Media.Imaging.FormatConvertedBitmap();
265
            src.BeginInit();
266
            src.Source = bitmapsource;
267
            src.DestinationFormat = System.Windows.Media.PixelFormats.Bgr24;
268
            src.EndInit();
269
270
            //copy to bitmap
271
            Bitmap bitmap = new Bitmap(src.PixelWidth, src.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
272
            var data = bitmap.LockBits(new Rectangle(Point.Empty, bitmap.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
273
            src.CopyPixels(System.Windows.Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
274
            bitmap.UnlockBits(data);
275
276
            return bitmap;
277
        }
278
279
        /// <summary>
280
        /// 메모리 문제 발생
281
        /// </summary>
282 c1659a98 taeseongkim
        /// <param name="nwdBitmap"></param>
283 24c5e56c taeseongkim
        /// <returns></returns>
284
        public System.Windows.Media.Imaging.WriteableBitmap CreateWriteableBitmapFromBitmap(Bitmap bitmap)
285
        {
286
            System.Windows.Media.Imaging.WriteableBitmap result = null;
287
288
            if (bitmap == null)
289
                throw new ArgumentNullException("bitmap");
290
291
            try
292
            {
293
                int bytesPerPixel = 4;
294
295 c1659a98 taeseongkim
                Bitmap newBitmap = new Bitmap(bitmap.Width, bitmap.Height, PixelFormat.Format32bppArgb);
296
                using (Graphics g = Graphics.FromImage(newBitmap))
297
                {
298
                    g.DrawImage(bitmap, 0, 0);
299
                }
300
301
                result = new System.Windows.Media.Imaging.WriteableBitmap(newBitmap.Width, newBitmap.Height,
302
                                                                   newBitmap.HorizontalResolution , newBitmap.VerticalResolution,
303
                                                                   newBitmap.PixelFormat.Convert(), null);
304 24c5e56c taeseongkim
305 c1659a98 taeseongkim
                Rectangle colorBitmapRectangle = new Rectangle(0, 0, newBitmap.Width, newBitmap.Height);
306
                System.Windows.Int32Rect colorBitmapInt32Rect = new System.Windows.Int32Rect(0, 0, newBitmap.Width, newBitmap.Height);
307 24c5e56c taeseongkim
308 c1659a98 taeseongkim
                BitmapData data = newBitmap.LockBits(colorBitmapRectangle, ImageLockMode.WriteOnly, newBitmap.PixelFormat);
309 24c5e56c taeseongkim
310
                result.WritePixels(colorBitmapInt32Rect, data.Scan0, data.Width * data.Height * bytesPerPixel, data.Stride);
311
312 c1659a98 taeseongkim
                newBitmap.UnlockBits(data);
313 24c5e56c taeseongkim
            }
314
            catch (Exception ex)
315
            {
316
                //throw ex;
317
            }
318
            finally
319
            {
320
                bitmap.Dispose();
321
                bitmap = null;
322
                //GC.Collect(2);
323
            }
324
325
            return result;
326
        }
327
    
328
        /// <summary>
329
        /// 메모리 문제 발생
330
        /// </summary>
331
        /// <param name="bitmap"></param>
332
        /// <returns></returns>
333
        public System.Windows.Media.Imaging.BitmapSource CreateBitmapSourceFromBitmap(Bitmap bitmap)
334
        {
335
            System.Windows.Media.Imaging.BitmapSource result = null;
336
            
337
            if (bitmap == null)
338
                throw new ArgumentNullException("bitmap");
339
340
            try
341
            {
342
                using (var hbitmap = new SafeHBitmapHandle(bitmap.GetHbitmap(), true))
343
                {
344
345
                    result = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
346
                        hbitmap.DangerousGetHandle(),
347
                        IntPtr.Zero,
348
                        System.Windows.Int32Rect.Empty,
349
                        System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
350
351
                   
352
                }
353
            }
354
            catch (Exception ex)
355
            {
356
                //throw ex;
357
            }
358
            finally
359
            {
360
                bitmap.Dispose();
361
                bitmap = null;
362
                //GC.Collect(2);
363
            }
364
365
            return result;
366
        }
367
368 0c575433 taeseongkim
        public async Task<List<System.Windows.Rect>> CompareReturnRectsAsync(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize, Size? ResultImageSize = null)
369 24c5e56c taeseongkim
        {
370
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
371
372
            Bitmap Originalbitmap = null;
373
            Bitmap TargatBitmap = null;
374
375
            try
376
            {
377
378
                Originalbitmap = LoadPicture(OriginalbitmapUri);
379
                TargatBitmap = LoadPicture(TargatBitmapUri);
380
381 0c575433 taeseongkim
                result = await CompareReturnRectsAsync(Originalbitmap, TargatBitmap, ResultRectSize, ResultImageSize);
382 24c5e56c taeseongkim
            }
383
            catch (Exception)
384
            {
385
                throw;
386
            }
387
            finally
388
            {
389
                Originalbitmap.Dispose();
390
                TargatBitmap.Dispose();
391
            }
392
393
            return result;
394
        }
395
396 0c575433 taeseongkim
        public async Task<System.Windows.Media.Imaging.BitmapSource> CompareDrawRectsAsync(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize, Size? ResultImageSize = null)
397 24c5e56c taeseongkim
        {
398
            System.Windows.Media.Imaging.BitmapSource result = null;
399
400
            Bitmap Originalbitmap = null;
401
            Bitmap TargatBitmap = null;
402
403
            try
404
            {
405
406
                Originalbitmap = LoadPicture(OriginalbitmapUri);
407
                TargatBitmap = LoadPicture(TargatBitmapUri);
408
409 0c575433 taeseongkim
                var bitmap = await CompareDrawRectsAsync(Originalbitmap, TargatBitmap, ResultRectSize, ResultImageSize);
410 24c5e56c taeseongkim
411
                result = CreateBitmapSourceFromBitmap(bitmap);
412
            }
413
            catch (Exception)
414
            {
415
                throw;
416
            }
417
            finally
418
            {
419
                Originalbitmap.Dispose();
420
                TargatBitmap.Dispose();
421
            }
422
423
            return result;
424
        }
425
426 a860bafc taeseongkim
        public async Task<List<System.Windows.Rect>> CompareReturnRectsAsync(System.Windows.Media.Imaging.BitmapSource OriginalbitmapFrame, System.Windows.Media.Imaging.BitmapSource TargatBitmapFrame, Size ResultRectSize, Size? ResultImageSize = null)
427
        {
428
            return await CompareReturnRectsAsync(Converter.ConvertBitmapFrameToBitmap(OriginalbitmapFrame), Converter.ConvertBitmapFrameToBitmap(TargatBitmapFrame), ResultRectSize, ResultImageSize);
429
        }
430
431
432
            /// <summary>
433
            /// 이미지를 비교 후 해당 영역을 Rect로 반환한다.
434
            /// </summary>
435
            /// <param name="Originalbitmap">원본 이미지</param>
436
            /// <param name="TargatBitmap">비교대상 이미지</param>
437
            /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
438
            /// <returns></returns>
439 0c575433 taeseongkim
        public async Task<List<System.Windows.Rect>> CompareReturnRectsAsync(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize,Size? ResultImageSize = null)
440 24c5e56c taeseongkim
        {
441
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
442
443
            try
444
            {
445 0c575433 taeseongkim
                Size resultImageSize = Originalbitmap.Size;
446
447
                if(ResultImageSize.HasValue)
448
                {
449
                    resultImageSize = ResultImageSize.Value;
450
                }
451
452
                var data = MathchesImageData(Originalbitmap, TargatBitmap, resultImageSize);
453 24c5e56c taeseongkim
454
                result = await GetMatchPixelsAsnc(data, ResultRectSize);
455
456
                data = null;
457
            }
458
            catch (Exception ex)
459
            {
460
                throw ex;
461
            }
462
            finally
463
            {
464
            }
465
466
            return result;
467
        }
468
469
       
470
        protected override void Dispose(bool disposing)
471
        {
472
            base.Dispose(disposing);
473
        }
474
    }
475
}
클립보드 이미지 추가 (최대 크기: 500 MB)