프로젝트

일반

사용자정보

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

markus / ImageComparer / Markus.ImageComparer / ImageCompare.cs @ 16231f58

이력 | 보기 | 이력해설 | 다운로드 (15.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
        /// <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
                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
                {
35
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height)).ToList();
36

    
37
                    g.DrawRectangles(new Pen(Brushes.Red, 5f), rect.ToArray());
38
                    g.Save();
39

    
40
                    g.Dispose();
41
                }
42

    
43
                Originalbitmap = newBitmap;
44
            }
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
                List<System.Windows.Rect> rects = new List<System.Windows.Rect>();
113

    
114
                var data = MathchesImageData(Originalbitmap, TargatBitmap);
115

    
116
                result =  GetMatchPixels(data, ResultRectSize);
117

    
118
                //if (rects.Count() > 0)
119
                //{
120
                //    result = Merge(rects, ResultRectSize.Height);
121
                //}
122

    
123
                //result = JoinRectList(rects);
124
            }
125
            catch (Exception ex)
126
            {
127
                throw ex;
128
            }
129
            finally
130
            {
131

    
132
            }
133

    
134
            return result;
135
        }
136

    
137
        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
        /// <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
               
178
                    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
        /// <param name="nwdBitmap"></param>
244
        /// <returns></returns>
245
        public System.Windows.Media.Imaging.WriteableBitmap CreateWriteableBitmapFromBitmap(IList<Bitmap> bitmaps,Size size)
246
        {
247
            System.Windows.Media.Imaging.WriteableBitmap result = null;
248

    
249
            try
250
            {
251
                int bytesPerPixel = 4;
252

    
253
                Bitmap newBitmap = new Bitmap(size.Width, size.Height, PixelFormat.Format32bppArgb);
254
                using (Graphics g = Graphics.FromImage(newBitmap))
255
                {
256
                    foreach (var bitmap in bitmaps)
257
                    {
258
                        g.DrawImage(bitmap, 0, 0);
259
                    }
260
                }
261

    
262
                result = new System.Windows.Media.Imaging.WriteableBitmap(newBitmap.Width, newBitmap.Height,
263
                                                                   newBitmap.HorizontalResolution , newBitmap.VerticalResolution,
264
                                                                   newBitmap.PixelFormat.Convert(), null);
265

    
266
                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

    
269
                BitmapData data = newBitmap.LockBits(colorBitmapRectangle, ImageLockMode.WriteOnly, newBitmap.PixelFormat);
270

    
271
                result.WritePixels(colorBitmapInt32Rect, data.Scan0, data.Width * data.Height * bytesPerPixel, data.Stride);
272

    
273
                newBitmap.UnlockBits(data);
274
            }
275
            catch (Exception ex)
276
            {
277
                //throw ex;
278
            }
279
            finally
280
            {
281
                for (int i = 0; i < bitmaps.Count;i++)
282
                {
283
                    bitmaps[i].Dispose();
284
                    bitmaps[i] = null;
285
                }
286
                //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
        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
        /// <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
                var data = MathchesImageData(Originalbitmap, TargatBitmap);
404

    
405
                result = await GetMatchPixelsAsnc(data, ResultRectSize);
406

    
407
                //result = JoinRectList(result);
408
                //if (result.Count() > 0)
409
                //{
410
                //    result = Merge(result, ResultRectSize.Height);
411
                //}
412

    
413
                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)