프로젝트

일반

사용자정보

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

markus / ImageComparer / Markus.ImageCompare / ImageCompare.cs @ 24c5e56c

이력 | 보기 | 이력해설 | 다운로드 (13.7 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
                using (Graphics g = Graphics.FromImage(Originalbitmap))
27
                {
28
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height)).ToList();
29

    
30
                    g.DrawRectangles(new Pen(Brushes.Red, 5f), rect.ToArray());
31
                    g.Save();
32

    
33
                    g.Dispose();
34
                }
35
            }
36

    
37
            return Originalbitmap;
38
        }
39

    
40
        public System.Windows.Media.Imaging.BitmapSource CompareDrawRects(System.Windows.Media.Imaging.BitmapSource Originalbitmap, System.Windows.Media.Imaging.BitmapSource TargatBitmap, Size ResultRectSize)
41
        {
42
            var _Originalbitmap = CreateBitmapFromSource(Originalbitmap);
43
            var _TargatBitmap = CreateBitmapFromSource(TargatBitmap);
44

    
45
            var rects = CompareReturnRects(_Originalbitmap, _TargatBitmap, ResultRectSize);
46
         
47
            if (rects.Count != 0)
48
            {
49
                using (Graphics g = Graphics.FromImage(_Originalbitmap))
50
                {
51
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
52

    
53
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
54
                    g.Save();
55

    
56
                    g.Dispose();
57
                }
58
            }
59

    
60
            return CreateBitmapSourceFromBitmap(_Originalbitmap);
61
        }
62

    
63
        public List<System.Windows.Rect> CompareReturnRects(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize)
64
        {
65
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
66

    
67
            Bitmap Originalbitmap = null;
68
            Bitmap TargatBitmap = null;
69

    
70
            try
71
            {
72
                Originalbitmap = LoadPicture(OriginalbitmapUri);
73
                TargatBitmap = LoadPicture(TargatBitmapUri);
74

    
75
                result = CompareReturnRects(Originalbitmap, TargatBitmap, ResultRectSize);
76
            }
77
            catch (Exception)
78
            {
79
                throw;
80
            }
81
            finally
82
            {
83
                Originalbitmap.Dispose();
84
                TargatBitmap.Dispose();
85
            }
86

    
87
            return result;
88
        }
89

    
90
        /// <summary>
91
        /// 이미지를 비교 후 해당 영역을 Rect로 반환한다.
92
        /// </summary>
93
        /// <param name="Originalbitmap">원본 이미지</param>
94
        /// <param name="TargatBitmap">비교대상 이미지</param>
95
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
96
        /// <returns></returns>
97
        public List<System.Windows.Rect> CompareReturnRects(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize)
98
        {
99
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
100

    
101
            try
102
            {
103
                List<System.Windows.Rect> rects = new List<System.Windows.Rect>();
104

    
105
                var data = MathchesImageData(Originalbitmap, TargatBitmap);
106

    
107
                result =  GetMatchPixels(data, ResultRectSize);
108

    
109
                //if (rects.Count() > 0)
110
                //{
111
                //    result = Merge(rects, ResultRectSize.Height);
112
                //}
113

    
114
                //result = JoinRectList(rects);
115
            }
116
            catch (Exception ex)
117
            {
118
                throw ex;
119
            }
120
            finally
121
            {
122

    
123
            }
124

    
125
            return result;
126
        }
127

    
128
        /// <summary>
129
        /// 이미지를 비교 후 원본 이미지에 Rect를 그린다.
130
        /// 메모리 문제 발생
131
        /// </summary>
132
        /// <param name="Originalbitmap">원본 이미지</param>
133
        /// <param name="TargatBitmap">비교대상 이미지</param>
134
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
135
        /// <returns></returns>
136
        public async Task<Bitmap> CompareDrawRectsAsync(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize)
137
        {
138
            System.Drawing.Bitmap cloneOriginal = Originalbitmap;
139

    
140
            var rects = await CompareReturnRectsAsync(cloneOriginal, TargatBitmap, ResultRectSize);
141

    
142
            if (rects.Count != 0)
143
            {
144
                using (Graphics g = Graphics.FromImage(cloneOriginal))
145
                {
146
               
147
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
148

    
149
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
150
                    g.Save();
151

    
152
                    g.Dispose();
153
                }
154
            }
155

    
156
            return cloneOriginal;
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<System.Windows.Media.Imaging.BitmapSource> CompareDrawRectsAsync(System.Windows.Media.Imaging.BitmapSource Originalbitmap, System.Windows.Media.Imaging.BitmapSource TargatBitmap, Size ResultRectSize)
168
        {
169

    
170
            var _Originalbitmap = CreateBitmapFromSource(Originalbitmap);
171
            var _TargatBitmap = CreateBitmapFromSource(TargatBitmap);
172

    
173
            var rects = await CompareReturnRectsAsync(_Originalbitmap, _TargatBitmap, ResultRectSize);
174

    
175
            if (rects.Count != 0)
176
            {
177
                using (Graphics g = Graphics.FromImage(_Originalbitmap))
178
                {
179
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
180

    
181
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
182
                    g.Save();
183

    
184
                    g.Dispose();
185
                }
186
            }
187

    
188
            return CreateBitmapSourceFromBitmap(_Originalbitmap);
189
        }
190

    
191
        public Bitmap CreateBitmapFromSource(System.Windows.Media.Imaging.BitmapSource bitmapsource)
192
        {
193
            //convert image format
194
            var src = new System.Windows.Media.Imaging.FormatConvertedBitmap();
195
            src.BeginInit();
196
            src.Source = bitmapsource;
197
            src.DestinationFormat = System.Windows.Media.PixelFormats.Bgr24;
198
            src.EndInit();
199

    
200
            //copy to bitmap
201
            Bitmap bitmap = new Bitmap(src.PixelWidth, src.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
202
            var data = bitmap.LockBits(new Rectangle(Point.Empty, bitmap.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
203
            src.CopyPixels(System.Windows.Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
204
            bitmap.UnlockBits(data);
205

    
206
            return bitmap;
207
        }
208

    
209
        /// <summary>
210
        /// 메모리 문제 발생
211
        /// </summary>
212
        /// <param name="bitmap"></param>
213
        /// <returns></returns>
214
        public System.Windows.Media.Imaging.WriteableBitmap CreateWriteableBitmapFromBitmap(Bitmap bitmap)
215
        {
216
            System.Windows.Media.Imaging.WriteableBitmap result = null;
217

    
218
            if (bitmap == null)
219
                throw new ArgumentNullException("bitmap");
220

    
221
            try
222
            {
223
                int bytesPerPixel = 4;
224

    
225
                result = new System.Windows.Media.Imaging.WriteableBitmap(bitmap.Width, bitmap.Height,
226
                                                                   bitmap.HorizontalResolution ,bitmap.VerticalResolution,
227
                                                                   bitmap.PixelFormat.Convert(), null);
228

    
229
                Rectangle colorBitmapRectangle = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
230
                System.Windows.Int32Rect colorBitmapInt32Rect = new System.Windows.Int32Rect(0, 0, bitmap.Width, bitmap.Height);
231

    
232
                BitmapData data = bitmap.LockBits(colorBitmapRectangle, ImageLockMode.WriteOnly, bitmap.PixelFormat);
233

    
234
                result.WritePixels(colorBitmapInt32Rect, data.Scan0, data.Width * data.Height * bytesPerPixel, data.Stride);
235

    
236
                bitmap.UnlockBits(data);
237
            }
238
            catch (Exception ex)
239
            {
240
                //throw ex;
241
            }
242
            finally
243
            {
244
                bitmap.Dispose();
245
                bitmap = null;
246
                //GC.Collect(2);
247
            }
248

    
249
            return result;
250
        }
251
    
252
        /// <summary>
253
        /// 메모리 문제 발생
254
        /// </summary>
255
        /// <param name="bitmap"></param>
256
        /// <returns></returns>
257
        public System.Windows.Media.Imaging.BitmapSource CreateBitmapSourceFromBitmap(Bitmap bitmap)
258
        {
259
            System.Windows.Media.Imaging.BitmapSource result = null;
260
            
261
            if (bitmap == null)
262
                throw new ArgumentNullException("bitmap");
263

    
264
            try
265
            {
266
                using (var hbitmap = new SafeHBitmapHandle(bitmap.GetHbitmap(), true))
267
                {
268

    
269
                    result = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
270
                        hbitmap.DangerousGetHandle(),
271
                        IntPtr.Zero,
272
                        System.Windows.Int32Rect.Empty,
273
                        System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
274

    
275
                   
276
                }
277
            }
278
            catch (Exception ex)
279
            {
280
                //throw ex;
281
            }
282
            finally
283
            {
284
                bitmap.Dispose();
285
                bitmap = null;
286
                //GC.Collect(2);
287
            }
288

    
289
            return result;
290
        }
291

    
292
        public async Task<List<System.Windows.Rect>> CompareReturnRectsAsync(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize)
293
        {
294
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
295

    
296
            Bitmap Originalbitmap = null;
297
            Bitmap TargatBitmap = null;
298

    
299
            try
300
            {
301

    
302
                Originalbitmap = LoadPicture(OriginalbitmapUri);
303
                TargatBitmap = LoadPicture(TargatBitmapUri);
304

    
305
                result = await CompareReturnRectsAsync(Originalbitmap, TargatBitmap, ResultRectSize);
306
            }
307
            catch (Exception)
308
            {
309
                throw;
310
            }
311
            finally
312
            {
313
                Originalbitmap.Dispose();
314
                TargatBitmap.Dispose();
315
            }
316

    
317
            return result;
318
        }
319

    
320
        public async Task<System.Windows.Media.Imaging.BitmapSource> CompareDrawRectsAsync(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize)
321
        {
322
            System.Windows.Media.Imaging.BitmapSource result = null;
323

    
324
            Bitmap Originalbitmap = null;
325
            Bitmap TargatBitmap = null;
326

    
327
            try
328
            {
329

    
330
                Originalbitmap = LoadPicture(OriginalbitmapUri);
331
                TargatBitmap = LoadPicture(TargatBitmapUri);
332

    
333
                var bitmap = await CompareDrawRectsAsync(Originalbitmap, TargatBitmap, ResultRectSize);
334

    
335
                result = CreateBitmapSourceFromBitmap(bitmap);
336
            }
337
            catch (Exception)
338
            {
339
                throw;
340
            }
341
            finally
342
            {
343
                Originalbitmap.Dispose();
344
                TargatBitmap.Dispose();
345
            }
346

    
347
            return result;
348
        }
349

    
350
        /// <summary>
351
        /// 이미지를 비교 후 해당 영역을 Rect로 반환한다.
352
        /// </summary>
353
        /// <param name="Originalbitmap">원본 이미지</param>
354
        /// <param name="TargatBitmap">비교대상 이미지</param>
355
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
356
        /// <returns></returns>
357
        public async Task<List<System.Windows.Rect>> CompareReturnRectsAsync(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize)
358
        {
359
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
360

    
361
            try
362
            {
363
                var data = MathchesImageData(Originalbitmap, TargatBitmap);
364

    
365
                result = await GetMatchPixelsAsnc(data, ResultRectSize);
366

    
367
                //result = JoinRectList(result);
368
                //if (result.Count() > 0)
369
                //{
370
                //    result = Merge(result, ResultRectSize.Height);
371
                //}
372

    
373
                data = null;
374
            }
375
            catch (Exception ex)
376
            {
377
                throw ex;
378
            }
379
            finally
380
            {
381
            }
382

    
383
            return result;
384
        }
385

    
386
       
387
        protected override void Dispose(bool disposing)
388
        {
389
            base.Dispose(disposing);
390
        }
391
    }
392
}
클립보드 이미지 추가 (최대 크기: 500 MB)