프로젝트

일반

사용자정보

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

markus / ImageComparer / Markus.ImageCompare / ImageCompare.cs @ 38d69491

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