프로젝트

일반

사용자정보

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

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

이력 | 보기 | 이력해설 | 다운로드 (17.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

    
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
        public async Task<Bitmap> CompareDrawRectsAsync(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize, Size? ResultImageSize = null)
207
        {
208
            System.Drawing.Bitmap cloneOriginal = Originalbitmap;
209

    
210
            var rects = await CompareReturnRectsAsync(cloneOriginal, TargatBitmap, ResultRectSize, ResultImageSize);
211

    
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
        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
        {
239

    
240
            var _Originalbitmap = CreateBitmapFromSource(Originalbitmap);
241
            var _TargatBitmap = CreateBitmapFromSource(TargatBitmap);
242

    
243
            var rects = await CompareReturnRectsAsync(_Originalbitmap, _TargatBitmap, ResultRectSize,ResultImageSize);
244

    
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
        /// <param name="nwdBitmap"></param>
283
        /// <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
                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

    
305
                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

    
308
                BitmapData data = newBitmap.LockBits(colorBitmapRectangle, ImageLockMode.WriteOnly, newBitmap.PixelFormat);
309

    
310
                result.WritePixels(colorBitmapInt32Rect, data.Scan0, data.Width * data.Height * bytesPerPixel, data.Stride);
311

    
312
                newBitmap.UnlockBits(data);
313
            }
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
        public async Task<List<System.Windows.Rect>> CompareReturnRectsAsync(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize, Size? ResultImageSize = null)
369
        {
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
                result = await CompareReturnRectsAsync(Originalbitmap, TargatBitmap, ResultRectSize, ResultImageSize);
382
            }
383
            catch (Exception)
384
            {
385
                throw;
386
            }
387
            finally
388
            {
389
                Originalbitmap.Dispose();
390
                TargatBitmap.Dispose();
391
            }
392

    
393
            return result;
394
        }
395

    
396
        public async Task<System.Windows.Media.Imaging.BitmapSource> CompareDrawRectsAsync(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize, Size? ResultImageSize = null)
397
        {
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
                var bitmap = await CompareDrawRectsAsync(Originalbitmap, TargatBitmap, ResultRectSize, ResultImageSize);
410

    
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
        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
        public async Task<List<System.Windows.Rect>> CompareReturnRectsAsync(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize,Size? ResultImageSize = null)
440
        {
441
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
442

    
443
            try
444
            {
445
                Size resultImageSize = Originalbitmap.Size;
446

    
447
                if(ResultImageSize.HasValue)
448
                {
449
                    resultImageSize = ResultImageSize.Value;
450
                }
451

    
452
                var data = MathchesImageData(Originalbitmap, TargatBitmap, resultImageSize);
453

    
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)