프로젝트

일반

사용자정보

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

markus / ImageComparer / Markus.ImageComparer / ImageCompare.cs @ master

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

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