프로젝트

일반

사용자정보

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

markus / Markus.ImageComparer / ImageCompare.cs @ c1659a98

이력 | 보기 | 이력해설 | 다운로드 (14.3 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
        /// <summary>
138
        /// 이미지를 비교 후 원본 이미지에 Rect를 그린다.
139
        /// 메모리 문제 발생
140
        /// </summary>
141
        /// <param name="Originalbitmap">원본 이미지</param>
142
        /// <param name="TargatBitmap">비교대상 이미지</param>
143
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
144
        /// <returns></returns>
145
        public async Task<Bitmap> CompareDrawRectsAsync(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize)
146
        {
147
            System.Drawing.Bitmap cloneOriginal = Originalbitmap;
148

    
149
            var rects = await CompareReturnRectsAsync(cloneOriginal, TargatBitmap, ResultRectSize);
150

    
151
            if (rects.Count != 0)
152
            {
153
                using (Graphics g = Graphics.FromImage(cloneOriginal))
154
                {
155
               
156
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
157

    
158
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
159
                    g.Save();
160

    
161
                    g.Dispose();
162
                }
163
            }
164

    
165
            return cloneOriginal;
166
        }
167

    
168
        /// <summary>
169
        /// 이미지를 비교 후 원본 이미지에 Rect를 그린다.
170
        /// 메모리 문제 발생
171
        /// </summary>
172
        /// <param name="Originalbitmap">원본 이미지</param>
173
        /// <param name="TargatBitmap">비교대상 이미지</param>
174
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
175
        /// <returns></returns>
176
        public async Task<System.Windows.Media.Imaging.BitmapSource> CompareDrawRectsAsync(System.Windows.Media.Imaging.BitmapSource Originalbitmap, System.Windows.Media.Imaging.BitmapSource TargatBitmap, Size ResultRectSize)
177
        {
178

    
179
            var _Originalbitmap = CreateBitmapFromSource(Originalbitmap);
180
            var _TargatBitmap = CreateBitmapFromSource(TargatBitmap);
181

    
182
            var rects = await CompareReturnRectsAsync(_Originalbitmap, _TargatBitmap, ResultRectSize);
183

    
184
            if (rects.Count != 0)
185
            {
186
                using (Graphics g = Graphics.FromImage(_Originalbitmap))
187
                {
188
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
189

    
190
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
191
                    g.Save();
192

    
193
                    g.Dispose();
194
                }
195
            }
196

    
197
            return CreateBitmapSourceFromBitmap(_Originalbitmap);
198
        }
199

    
200
        public Bitmap CreateBitmapFromSource(System.Windows.Media.Imaging.BitmapSource bitmapsource)
201
        {
202
            //convert image format
203
            var src = new System.Windows.Media.Imaging.FormatConvertedBitmap();
204
            src.BeginInit();
205
            src.Source = bitmapsource;
206
            src.DestinationFormat = System.Windows.Media.PixelFormats.Bgr24;
207
            src.EndInit();
208

    
209
            //copy to bitmap
210
            Bitmap bitmap = new Bitmap(src.PixelWidth, src.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
211
            var data = bitmap.LockBits(new Rectangle(Point.Empty, bitmap.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
212
            src.CopyPixels(System.Windows.Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
213
            bitmap.UnlockBits(data);
214

    
215
            return bitmap;
216
        }
217

    
218
        /// <summary>
219
        /// 메모리 문제 발생
220
        /// </summary>
221
        /// <param name="nwdBitmap"></param>
222
        /// <returns></returns>
223
        public System.Windows.Media.Imaging.WriteableBitmap CreateWriteableBitmapFromBitmap(Bitmap bitmap)
224
        {
225
            System.Windows.Media.Imaging.WriteableBitmap result = null;
226

    
227
            if (bitmap == null)
228
                throw new ArgumentNullException("bitmap");
229

    
230
            try
231
            {
232
                int bytesPerPixel = 4;
233

    
234
                Bitmap newBitmap = new Bitmap(bitmap.Width, bitmap.Height, PixelFormat.Format32bppArgb);
235
                using (Graphics g = Graphics.FromImage(newBitmap))
236
                {
237
                    g.DrawImage(bitmap, 0, 0);
238
                }
239

    
240
                result = new System.Windows.Media.Imaging.WriteableBitmap(newBitmap.Width, newBitmap.Height,
241
                                                                   newBitmap.HorizontalResolution , newBitmap.VerticalResolution,
242
                                                                   newBitmap.PixelFormat.Convert(), null);
243

    
244
                Rectangle colorBitmapRectangle = new Rectangle(0, 0, newBitmap.Width, newBitmap.Height);
245
                System.Windows.Int32Rect colorBitmapInt32Rect = new System.Windows.Int32Rect(0, 0, newBitmap.Width, newBitmap.Height);
246

    
247
                BitmapData data = newBitmap.LockBits(colorBitmapRectangle, ImageLockMode.WriteOnly, newBitmap.PixelFormat);
248

    
249
                result.WritePixels(colorBitmapInt32Rect, data.Scan0, data.Width * data.Height * bytesPerPixel, data.Stride);
250

    
251
                newBitmap.UnlockBits(data);
252
            }
253
            catch (Exception ex)
254
            {
255
                //throw ex;
256
            }
257
            finally
258
            {
259
                bitmap.Dispose();
260
                bitmap = null;
261
                //GC.Collect(2);
262
            }
263

    
264
            return result;
265
        }
266
    
267
        /// <summary>
268
        /// 메모리 문제 발생
269
        /// </summary>
270
        /// <param name="bitmap"></param>
271
        /// <returns></returns>
272
        public System.Windows.Media.Imaging.BitmapSource CreateBitmapSourceFromBitmap(Bitmap bitmap)
273
        {
274
            System.Windows.Media.Imaging.BitmapSource result = null;
275
            
276
            if (bitmap == null)
277
                throw new ArgumentNullException("bitmap");
278

    
279
            try
280
            {
281
                using (var hbitmap = new SafeHBitmapHandle(bitmap.GetHbitmap(), true))
282
                {
283

    
284
                    result = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
285
                        hbitmap.DangerousGetHandle(),
286
                        IntPtr.Zero,
287
                        System.Windows.Int32Rect.Empty,
288
                        System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
289

    
290
                   
291
                }
292
            }
293
            catch (Exception ex)
294
            {
295
                //throw ex;
296
            }
297
            finally
298
            {
299
                bitmap.Dispose();
300
                bitmap = null;
301
                //GC.Collect(2);
302
            }
303

    
304
            return result;
305
        }
306

    
307
        public async Task<List<System.Windows.Rect>> CompareReturnRectsAsync(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize)
308
        {
309
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
310

    
311
            Bitmap Originalbitmap = null;
312
            Bitmap TargatBitmap = null;
313

    
314
            try
315
            {
316

    
317
                Originalbitmap = LoadPicture(OriginalbitmapUri);
318
                TargatBitmap = LoadPicture(TargatBitmapUri);
319

    
320
                result = await CompareReturnRectsAsync(Originalbitmap, TargatBitmap, ResultRectSize);
321
            }
322
            catch (Exception)
323
            {
324
                throw;
325
            }
326
            finally
327
            {
328
                Originalbitmap.Dispose();
329
                TargatBitmap.Dispose();
330
            }
331

    
332
            return result;
333
        }
334

    
335
        public async Task<System.Windows.Media.Imaging.BitmapSource> CompareDrawRectsAsync(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize)
336
        {
337
            System.Windows.Media.Imaging.BitmapSource result = null;
338

    
339
            Bitmap Originalbitmap = null;
340
            Bitmap TargatBitmap = null;
341

    
342
            try
343
            {
344

    
345
                Originalbitmap = LoadPicture(OriginalbitmapUri);
346
                TargatBitmap = LoadPicture(TargatBitmapUri);
347

    
348
                var bitmap = await CompareDrawRectsAsync(Originalbitmap, TargatBitmap, ResultRectSize);
349

    
350
                result = CreateBitmapSourceFromBitmap(bitmap);
351
            }
352
            catch (Exception)
353
            {
354
                throw;
355
            }
356
            finally
357
            {
358
                Originalbitmap.Dispose();
359
                TargatBitmap.Dispose();
360
            }
361

    
362
            return result;
363
        }
364

    
365
        /// <summary>
366
        /// 이미지를 비교 후 해당 영역을 Rect로 반환한다.
367
        /// </summary>
368
        /// <param name="Originalbitmap">원본 이미지</param>
369
        /// <param name="TargatBitmap">비교대상 이미지</param>
370
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
371
        /// <returns></returns>
372
        public async Task<List<System.Windows.Rect>> CompareReturnRectsAsync(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize)
373
        {
374
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
375

    
376
            try
377
            {
378
                var data = MathchesImageData(Originalbitmap, TargatBitmap);
379

    
380
                result = await GetMatchPixelsAsnc(data, ResultRectSize);
381

    
382
                //result = JoinRectList(result);
383
                //if (result.Count() > 0)
384
                //{
385
                //    result = Merge(result, ResultRectSize.Height);
386
                //}
387

    
388
                data = null;
389
            }
390
            catch (Exception ex)
391
            {
392
                throw ex;
393
            }
394
            finally
395
            {
396
            }
397

    
398
            return result;
399
        }
400

    
401
       
402
        protected override void Dispose(bool disposing)
403
        {
404
            base.Dispose(disposing);
405
        }
406
    }
407
}
클립보드 이미지 추가 (최대 크기: 500 MB)