프로젝트

일반

사용자정보

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

markus / Markus.ImageComparer / ImageCompare.cs @ master

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

1
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
        /// <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
        {
23
            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

    
32
            if (rects.Count != 0)
33
            {
34
                Bitmap newBitmap = new Bitmap(resultImageSize.Width, resultImageSize.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
35
           
36
                using (Graphics g = Graphics.FromImage(newBitmap))
37
                {
38
                    g.DrawImage(TargatBitmap, 0, 0);
39
                }
40

    
41
                using (Graphics g = Graphics.FromImage(newBitmap))
42
                {
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

    
51
                Originalbitmap = newBitmap;
52
            }
53

    
54
            return Originalbitmap;
55
        }
56

    
57
        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
        {
59
            var _Originalbitmap = CreateBitmapFromSource(Originalbitmap);
60
            var _TargatBitmap = CreateBitmapFromSource(TargatBitmap);
61

    
62
            var rects = CompareReturnRects(_Originalbitmap, _TargatBitmap, ResultRectSize,ResultImageSize);
63
         
64
            if (rects.Count != 0)
65
            {
66
                using (Graphics g = Graphics.FromImage(_TargatBitmap))
67
                {
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
            return CreateBitmapSourceFromBitmap(_TargatBitmap);
78
        }
79

    
80
        public List<System.Windows.Rect> CompareReturnRects(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize, Size? ResultImageSize = null)
81
        {
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
                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
            }
129
            catch (Exception)
130
            {
131
                throw;
132
            }
133
            finally
134
            {
135
                Originalbitmap.Dispose();
136
                TargatBitmap.Dispose();
137
            }
138

    
139
            return result;
140
        }
141
        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

    
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
        public List<System.Windows.Rect> CompareReturnRects(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize , Size? ResultImageSize = null)
154
        {
155
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
156

    
157
            try
158
            {
159
                Size resultImageSize = TargatBitmap.Size;
160

    
161
                if (ResultImageSize.HasValue)
162
                {
163
                    resultImageSize = ResultImageSize.Value;
164
                }
165

    
166
                List<System.Windows.Rect> rects = new List<System.Windows.Rect>();
167

    
168
                var data = MathchesImageData(Originalbitmap, TargatBitmap, resultImageSize);
169
                
170
                result =  GetMatchPixels(data, ResultRectSize);
171

    
172

    
173
                //var data2 = MathchesImageData(TargatBitmap,Originalbitmap, Originalbitmap.Size);
174

    
175
                //result.AddRange(GetMatchPixels(data2, ResultRectSize));
176

    
177
                //result = result.Distinct().ToList();
178
                //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
                Originalbitmap.Dispose();
192
                TargatBitmap.Dispose();
193

    
194
                GC.Collect(2);
195
                GC.Collect(2);
196
            }
197

    
198
            return result;
199
        }
200

    
201
        /// <summary>
202
        /// 이미지를 비교 후 원본 이미지에 Rect를 그린다.
203
        /// 메모리 문제 발생
204
        /// </summary>
205
        /// <param name="Originalbitmap">원본 이미지</param>
206
        /// <param name="TargatBitmap">비교대상 이미지</param>
207
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
208
        /// <returns></returns>
209
        public async Task<Bitmap> CompareDrawRectsAsync(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize, Size? ResultImageSize = null)
210
        {
211
            System.Drawing.Bitmap cloneOriginal = Originalbitmap;
212

    
213
            var rects = await CompareReturnRectsAsync(cloneOriginal, TargatBitmap, ResultRectSize, ResultImageSize);
214

    
215
            if (rects.Count != 0)
216
            {
217
                using (Graphics g = Graphics.FromImage(cloneOriginal))
218
                {
219
               
220
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
221

    
222
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
223
                    g.Save();
224

    
225
                    g.Dispose();
226
                }
227
            }
228

    
229
            return cloneOriginal;
230
        }
231

    
232
        /// <summary>
233
        /// 이미지를 비교 후 원본 이미지에 Rect를 그린다.
234
        /// 메모리 문제 발생
235
        /// </summary>
236
        /// <param name="Originalbitmap">원본 이미지</param>
237
        /// <param name="TargatBitmap">비교대상 이미지</param>
238
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
239
        /// <returns></returns>
240
        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)
241
        {
242

    
243
            var _Originalbitmap = CreateBitmapFromSource(Originalbitmap);
244
            var _TargatBitmap = CreateBitmapFromSource(TargatBitmap);
245

    
246
            var rects = await CompareReturnRectsAsync(_Originalbitmap, _TargatBitmap, ResultRectSize,ResultImageSize);
247

    
248
            if (rects.Count != 0)
249
            {
250
                using (Graphics g = Graphics.FromImage(_Originalbitmap))
251
                {
252
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
253

    
254
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
255
                    g.Save();
256

    
257
                    g.Dispose();
258
                }
259
            }
260

    
261
            return CreateBitmapSourceFromBitmap(_Originalbitmap);
262
        }
263

    
264
        public Bitmap CreateBitmapFromSource(System.Windows.Media.Imaging.BitmapSource bitmapsource)
265
        {
266
            //convert image format
267
            var src = new System.Windows.Media.Imaging.FormatConvertedBitmap();
268
            src.BeginInit();
269
            src.Source = bitmapsource;
270
            src.DestinationFormat = System.Windows.Media.PixelFormats.Bgr24;
271
            src.EndInit();
272

    
273
            //copy to bitmap
274
            Bitmap bitmap = new Bitmap(src.PixelWidth, src.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
275
            var data = bitmap.LockBits(new Rectangle(Point.Empty, bitmap.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
276
            src.CopyPixels(System.Windows.Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
277
            bitmap.UnlockBits(data);
278

    
279
            return bitmap;
280
        }
281

    
282
        /// <summary>
283
        /// 메모리 문제 발생
284
        /// </summary>
285
        /// <param name="nwdBitmap"></param>
286
        /// <returns></returns>
287
        public System.Windows.Media.Imaging.WriteableBitmap CreateWriteableBitmapFromBitmap(Bitmap bitmap)
288
        {
289
            System.Windows.Media.Imaging.WriteableBitmap result = null;
290

    
291
            if (bitmap == null)
292
                throw new ArgumentNullException("bitmap");
293

    
294
            try
295
            {
296
                int bytesPerPixel = 4;
297

    
298
                Bitmap newBitmap = new Bitmap(bitmap.Width, bitmap.Height, PixelFormat.Format32bppArgb);
299
                using (Graphics g = Graphics.FromImage(newBitmap))
300
                {
301
                    g.DrawImage(bitmap, 0, 0);
302
                }
303

    
304
                result = new System.Windows.Media.Imaging.WriteableBitmap(newBitmap.Width, newBitmap.Height,
305
                                                                   newBitmap.HorizontalResolution , newBitmap.VerticalResolution,
306
                                                                   newBitmap.PixelFormat.Convert(), null);
307

    
308
                Rectangle colorBitmapRectangle = new Rectangle(0, 0, newBitmap.Width, newBitmap.Height);
309
                System.Windows.Int32Rect colorBitmapInt32Rect = new System.Windows.Int32Rect(0, 0, newBitmap.Width, newBitmap.Height);
310

    
311
                BitmapData data = newBitmap.LockBits(colorBitmapRectangle, ImageLockMode.WriteOnly, newBitmap.PixelFormat);
312

    
313
                result.WritePixels(colorBitmapInt32Rect, data.Scan0, data.Width * data.Height * bytesPerPixel, data.Stride);
314

    
315
                newBitmap.UnlockBits(data);
316
            }
317
            catch (Exception ex)
318
            {
319
                //throw ex;
320
            }
321
            finally
322
            {
323
                bitmap.Dispose();
324
                bitmap = null;
325
                //GC.Collect(2);
326
            }
327

    
328
            return result;
329
        }
330
    
331
        /// <summary>
332
        /// 메모리 문제 발생
333
        /// </summary>
334
        /// <param name="bitmap"></param>
335
        /// <returns></returns>
336
        public System.Windows.Media.Imaging.BitmapSource CreateBitmapSourceFromBitmap(Bitmap bitmap)
337
        {
338
            System.Windows.Media.Imaging.BitmapSource result = null;
339
            
340
            if (bitmap == null)
341
                throw new ArgumentNullException("bitmap");
342

    
343
            try
344
            {
345
                using (var hbitmap = new SafeHBitmapHandle(bitmap.GetHbitmap(), true))
346
                {
347

    
348
                    result = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
349
                        hbitmap.DangerousGetHandle(),
350
                        IntPtr.Zero,
351
                        System.Windows.Int32Rect.Empty,
352
                        System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
353

    
354
                   
355
                }
356
            }
357
            catch (Exception ex)
358
            {
359
                //throw ex;
360
            }
361
            finally
362
            {
363
                bitmap.Dispose();
364
                bitmap = null;
365
                //GC.Collect(2);
366
            }
367

    
368
            return result;
369
        }
370

    
371
        public async Task<List<System.Windows.Rect>> CompareReturnRectsAsync(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize, Size? ResultImageSize = null)
372
        {
373
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
374

    
375
            Bitmap Originalbitmap = null;
376
            Bitmap TargatBitmap = null;
377

    
378
            try
379
            {
380

    
381
                Originalbitmap = LoadPicture(OriginalbitmapUri);
382
                TargatBitmap = LoadPicture(TargatBitmapUri);
383

    
384
                result = await CompareReturnRectsAsync(Originalbitmap, TargatBitmap, ResultRectSize, ResultImageSize);
385
            }
386
            catch (Exception)
387
            {
388
                throw;
389
            }
390
            finally
391
            {
392
                Originalbitmap.Dispose();
393
                TargatBitmap.Dispose();
394
            }
395

    
396
            return result;
397
        }
398

    
399
        public async Task<System.Windows.Media.Imaging.BitmapSource> CompareDrawRectsAsync(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize, Size? ResultImageSize = null)
400
        {
401
            System.Windows.Media.Imaging.BitmapSource result = null;
402

    
403
            Bitmap Originalbitmap = null;
404
            Bitmap TargatBitmap = null;
405

    
406
            try
407
            {
408

    
409
                Originalbitmap = LoadPicture(OriginalbitmapUri);
410
                TargatBitmap = LoadPicture(TargatBitmapUri);
411

    
412
                var bitmap = await CompareDrawRectsAsync(Originalbitmap, TargatBitmap, ResultRectSize, ResultImageSize);
413

    
414
                result = CreateBitmapSourceFromBitmap(bitmap);
415
            }
416
            catch (Exception)
417
            {
418
                throw;
419
            }
420
            finally
421
            {
422
                Originalbitmap.Dispose();
423
                TargatBitmap.Dispose();
424
            }
425

    
426
            return result;
427
        }
428

    
429
        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)
430
        {
431
            return await CompareReturnRectsAsync(Converter.ConvertBitmapFrameToBitmap(OriginalbitmapFrame), Converter.ConvertBitmapFrameToBitmap(TargatBitmapFrame), ResultRectSize, ResultImageSize);
432
        }
433

    
434

    
435
            /// <summary>
436
            /// 이미지를 비교 후 해당 영역을 Rect로 반환한다.
437
            /// </summary>
438
            /// <param name="Originalbitmap">원본 이미지</param>
439
            /// <param name="TargatBitmap">비교대상 이미지</param>
440
            /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
441
            /// <returns></returns>
442
        public async Task<List<System.Windows.Rect>> CompareReturnRectsAsync(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize,Size? ResultImageSize = null)
443
        {
444
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
445

    
446
            try
447
            {
448
                Size resultImageSize = Originalbitmap.Size;
449

    
450
                if(ResultImageSize.HasValue)
451
                {
452
                    resultImageSize = ResultImageSize.Value;
453
                }
454

    
455
                var data = MathchesImageData(Originalbitmap, TargatBitmap, resultImageSize);
456

    
457
                result = await GetMatchPixelsAsnc(data, ResultRectSize);
458

    
459
                data = null;
460
            }
461
            catch (Exception ex)
462
            {
463
                throw ex;
464
            }
465
            finally
466
            {
467
                GC.Collect(2);
468
                GC.Collect(2);
469
            }
470

    
471
            return result;
472
        }
473

    
474
        public System.Windows.Media.Imaging.BitmapSource CompareReturnDrawContours(System.Windows.Media.Imaging.BitmapSource OriginalbitmapFrame, System.Windows.Media.Imaging.BitmapSource TargatBitmapFrame, Color rectColor, Size? ResultImageSize = null)
475
        {
476
            System.Windows.Media.Imaging.BitmapSource result = null;
477

    
478
            try
479
            {
480

    
481
                using (OpenCvSharp.Mat Originalbitmap = Converter.ConvertBitmapFrameToMat(OriginalbitmapFrame))
482

    
483
                using (OpenCvSharp.Mat TargatBitmap = Converter.ConvertBitmapFrameToMat(TargatBitmapFrame))
484
                {
485
                    var bitmap = CompareReturnDrawContours(Originalbitmap, TargatBitmap, rectColor, ResultImageSize);
486
                    result = CreateBitmapSourceFromBitmap(bitmap);
487
                }
488
            }
489
            catch (Exception)
490
            {
491
                throw;
492
            }
493
            finally
494
            {
495
                GC.Collect(2);
496
                GC.Collect(2);
497
            }
498

    
499
            return result;
500
        }
501

    
502
        private System.Drawing.Bitmap CompareReturnDrawContours(OpenCvSharp.Mat OriginalData, OpenCvSharp.Mat TargatData, Color rectColor, Size? ResultImageSize = null)
503
        {
504
            System.Drawing.Bitmap result = null;
505

    
506
            try
507
            {
508
                var originalSize = OriginalData.Size();
509

    
510
                Size resultImageSize = new Size(originalSize.Width, originalSize.Height);
511

    
512
                if (ResultImageSize.HasValue)
513
                {
514
                    resultImageSize = ResultImageSize.Value;
515
                }
516

    
517
                var data = MathchesImageData(OriginalData, TargatData, resultImageSize);
518
                result = GetContoursImage(data, resultImageSize, rectColor);
519
            }
520
            catch (Exception ex)
521
            {
522
                throw ex;
523
            }
524
            finally
525
            {
526
                GC.Collect(2);
527
                GC.Collect(2);
528
            }
529

    
530
            return result;
531
        }
532
        protected override void Dispose(bool disposing)
533
        {
534
            base.Dispose(disposing);
535
        }
536
    }
537
}
클립보드 이미지 추가 (최대 크기: 500 MB)