프로젝트

일반

사용자정보

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

markus / Markus.ImageComparer / ImageCompare.cs @ 0c575433

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

    
142
        /// <summary>
143
        /// 이미지를 비교 후 해당 영역을 Rect로 반환한다.
144
        /// </summary>
145
        /// <param name="Originalbitmap">원본 이미지</param>
146
        /// <param name="TargatBitmap">비교대상 이미지</param>
147
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
148
        /// <returns></returns>
149
        public List<System.Windows.Rect> CompareReturnRects(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize , Size? ResultImageSize = null)
150
        {
151
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
152

    
153
            try
154
            {
155
                Size resultImageSize = TargatBitmap.Size;
156

    
157
                if (ResultImageSize.HasValue)
158
                {
159
                    resultImageSize = ResultImageSize.Value;
160
                }
161

    
162
                List<System.Windows.Rect> rects = new List<System.Windows.Rect>();
163

    
164
                var data = MathchesImageData(Originalbitmap, TargatBitmap, resultImageSize);
165
                
166
                result =  GetMatchPixels(data, ResultRectSize);
167

    
168

    
169
                //var data2 = MathchesImageData(TargatBitmap,Originalbitmap, Originalbitmap.Size);
170

    
171
                //result.AddRange(GetMatchPixels(data2, ResultRectSize));
172

    
173
                //result = result.Distinct().ToList();
174
                //if (rects.Count() > 0)
175
                //{
176
                //    result = Merge(rects, ResultRectSize.Height);
177
                //}
178

    
179
                //result = JoinRectList(rects);
180
            }
181
            catch (Exception ex)
182
            {
183
                throw ex;
184
            }
185
            finally
186
            {
187

    
188
            }
189

    
190
            return result;
191
        }
192

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

    
205
            var rects = await CompareReturnRectsAsync(cloneOriginal, TargatBitmap, ResultRectSize, ResultImageSize);
206

    
207
            if (rects.Count != 0)
208
            {
209
                using (Graphics g = Graphics.FromImage(cloneOriginal))
210
                {
211
               
212
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
213

    
214
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
215
                    g.Save();
216

    
217
                    g.Dispose();
218
                }
219
            }
220

    
221
            return cloneOriginal;
222
        }
223

    
224
        /// <summary>
225
        /// 이미지를 비교 후 원본 이미지에 Rect를 그린다.
226
        /// 메모리 문제 발생
227
        /// </summary>
228
        /// <param name="Originalbitmap">원본 이미지</param>
229
        /// <param name="TargatBitmap">비교대상 이미지</param>
230
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
231
        /// <returns></returns>
232
        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)
233
        {
234

    
235
            var _Originalbitmap = CreateBitmapFromSource(Originalbitmap);
236
            var _TargatBitmap = CreateBitmapFromSource(TargatBitmap);
237

    
238
            var rects = await CompareReturnRectsAsync(_Originalbitmap, _TargatBitmap, ResultRectSize,ResultImageSize);
239

    
240
            if (rects.Count != 0)
241
            {
242
                using (Graphics g = Graphics.FromImage(_Originalbitmap))
243
                {
244
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
245

    
246
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
247
                    g.Save();
248

    
249
                    g.Dispose();
250
                }
251
            }
252

    
253
            return CreateBitmapSourceFromBitmap(_Originalbitmap);
254
        }
255

    
256
        public Bitmap CreateBitmapFromSource(System.Windows.Media.Imaging.BitmapSource bitmapsource)
257
        {
258
            //convert image format
259
            var src = new System.Windows.Media.Imaging.FormatConvertedBitmap();
260
            src.BeginInit();
261
            src.Source = bitmapsource;
262
            src.DestinationFormat = System.Windows.Media.PixelFormats.Bgr24;
263
            src.EndInit();
264

    
265
            //copy to bitmap
266
            Bitmap bitmap = new Bitmap(src.PixelWidth, src.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
267
            var data = bitmap.LockBits(new Rectangle(Point.Empty, bitmap.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
268
            src.CopyPixels(System.Windows.Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
269
            bitmap.UnlockBits(data);
270

    
271
            return bitmap;
272
        }
273

    
274
        /// <summary>
275
        /// 메모리 문제 발생
276
        /// </summary>
277
        /// <param name="nwdBitmap"></param>
278
        /// <returns></returns>
279
        public System.Windows.Media.Imaging.WriteableBitmap CreateWriteableBitmapFromBitmap(Bitmap bitmap)
280
        {
281
            System.Windows.Media.Imaging.WriteableBitmap result = null;
282

    
283
            if (bitmap == null)
284
                throw new ArgumentNullException("bitmap");
285

    
286
            try
287
            {
288
                int bytesPerPixel = 4;
289

    
290
                Bitmap newBitmap = new Bitmap(bitmap.Width, bitmap.Height, PixelFormat.Format32bppArgb);
291
                using (Graphics g = Graphics.FromImage(newBitmap))
292
                {
293
                    g.DrawImage(bitmap, 0, 0);
294
                }
295

    
296
                result = new System.Windows.Media.Imaging.WriteableBitmap(newBitmap.Width, newBitmap.Height,
297
                                                                   newBitmap.HorizontalResolution , newBitmap.VerticalResolution,
298
                                                                   newBitmap.PixelFormat.Convert(), null);
299

    
300
                Rectangle colorBitmapRectangle = new Rectangle(0, 0, newBitmap.Width, newBitmap.Height);
301
                System.Windows.Int32Rect colorBitmapInt32Rect = new System.Windows.Int32Rect(0, 0, newBitmap.Width, newBitmap.Height);
302

    
303
                BitmapData data = newBitmap.LockBits(colorBitmapRectangle, ImageLockMode.WriteOnly, newBitmap.PixelFormat);
304

    
305
                result.WritePixels(colorBitmapInt32Rect, data.Scan0, data.Width * data.Height * bytesPerPixel, data.Stride);
306

    
307
                newBitmap.UnlockBits(data);
308
            }
309
            catch (Exception ex)
310
            {
311
                //throw ex;
312
            }
313
            finally
314
            {
315
                bitmap.Dispose();
316
                bitmap = null;
317
                //GC.Collect(2);
318
            }
319

    
320
            return result;
321
        }
322
    
323
        /// <summary>
324
        /// 메모리 문제 발생
325
        /// </summary>
326
        /// <param name="bitmap"></param>
327
        /// <returns></returns>
328
        public System.Windows.Media.Imaging.BitmapSource CreateBitmapSourceFromBitmap(Bitmap bitmap)
329
        {
330
            System.Windows.Media.Imaging.BitmapSource result = null;
331
            
332
            if (bitmap == null)
333
                throw new ArgumentNullException("bitmap");
334

    
335
            try
336
            {
337
                using (var hbitmap = new SafeHBitmapHandle(bitmap.GetHbitmap(), true))
338
                {
339

    
340
                    result = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
341
                        hbitmap.DangerousGetHandle(),
342
                        IntPtr.Zero,
343
                        System.Windows.Int32Rect.Empty,
344
                        System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
345

    
346
                   
347
                }
348
            }
349
            catch (Exception ex)
350
            {
351
                //throw ex;
352
            }
353
            finally
354
            {
355
                bitmap.Dispose();
356
                bitmap = null;
357
                //GC.Collect(2);
358
            }
359

    
360
            return result;
361
        }
362

    
363
        public async Task<List<System.Windows.Rect>> CompareReturnRectsAsync(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize, Size? ResultImageSize = null)
364
        {
365
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
366

    
367
            Bitmap Originalbitmap = null;
368
            Bitmap TargatBitmap = null;
369

    
370
            try
371
            {
372

    
373
                Originalbitmap = LoadPicture(OriginalbitmapUri);
374
                TargatBitmap = LoadPicture(TargatBitmapUri);
375

    
376
                result = await CompareReturnRectsAsync(Originalbitmap, TargatBitmap, ResultRectSize, ResultImageSize);
377
            }
378
            catch (Exception)
379
            {
380
                throw;
381
            }
382
            finally
383
            {
384
                Originalbitmap.Dispose();
385
                TargatBitmap.Dispose();
386
            }
387

    
388
            return result;
389
        }
390

    
391
        public async Task<System.Windows.Media.Imaging.BitmapSource> CompareDrawRectsAsync(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize, Size? ResultImageSize = null)
392
        {
393
            System.Windows.Media.Imaging.BitmapSource result = null;
394

    
395
            Bitmap Originalbitmap = null;
396
            Bitmap TargatBitmap = null;
397

    
398
            try
399
            {
400

    
401
                Originalbitmap = LoadPicture(OriginalbitmapUri);
402
                TargatBitmap = LoadPicture(TargatBitmapUri);
403

    
404
                var bitmap = await CompareDrawRectsAsync(Originalbitmap, TargatBitmap, ResultRectSize, ResultImageSize);
405

    
406
                result = CreateBitmapSourceFromBitmap(bitmap);
407
            }
408
            catch (Exception)
409
            {
410
                throw;
411
            }
412
            finally
413
            {
414
                Originalbitmap.Dispose();
415
                TargatBitmap.Dispose();
416
            }
417

    
418
            return result;
419
        }
420

    
421
        /// <summary>
422
        /// 이미지를 비교 후 해당 영역을 Rect로 반환한다.
423
        /// </summary>
424
        /// <param name="Originalbitmap">원본 이미지</param>
425
        /// <param name="TargatBitmap">비교대상 이미지</param>
426
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
427
        /// <returns></returns>
428
        public async Task<List<System.Windows.Rect>> CompareReturnRectsAsync(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize,Size? ResultImageSize = null)
429
        {
430
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
431

    
432
            try
433
            {
434
                Size resultImageSize = Originalbitmap.Size;
435

    
436
                if(ResultImageSize.HasValue)
437
                {
438
                    resultImageSize = ResultImageSize.Value;
439
                }
440

    
441
                var data = MathchesImageData(Originalbitmap, TargatBitmap, resultImageSize);
442

    
443
                result = await GetMatchPixelsAsnc(data, ResultRectSize);
444

    
445
                //var data2 = MathchesImageData(TargatBitmap, Originalbitmap, Originalbitmap.Size);
446

    
447
                //var result2 = await GetMatchPixelsAsnc(data2, ResultRectSize);
448
                
449
                //result.AddRange(result2);
450

    
451
                //result = result.Distinct().ToList();
452
                //result = JoinRectList(result);
453
                //if (result.Count() > 0)
454
                //{
455
                //    result = Merge(result, ResultRectSize.Height);
456
                //}
457

    
458
                data = null;
459
            }
460
            catch (Exception ex)
461
            {
462
                throw ex;
463
            }
464
            finally
465
            {
466
            }
467

    
468
            return result;
469
        }
470

    
471
       
472
        protected override void Dispose(bool disposing)
473
        {
474
            base.Dispose(disposing);
475
        }
476
    }
477
}
클립보드 이미지 추가 (최대 크기: 500 MB)