프로젝트

일반

사용자정보

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

markus / ImageComparer / Markus.ImageComparer / ImageComparer.cs @ 6b6e937c

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

1
using Emgu.CV;
2
using Emgu.CV.Structure;
3
using System;
4
using System.Collections.Generic;
5
using System.Drawing;
6
using System.Drawing.Imaging;
7
using System.Linq;
8
using System.Text;
9
using System.Threading.Tasks;
10

    
11
namespace Markus.Image
12
{
13
    public class ImageComparer : ImageComparerBase
14
    {
15
        /// <summary>
16
        /// 이미지를 비교 후 원본 이미지에 Rect를 그린다.
17
        /// </summary>
18
        /// <param name="Originalbitmap">원본 이미지</param>
19
        /// <param name="TargatBitmap">비교대상 이미지</param>
20
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
21
        /// <returns></returns>
22
        public Bitmap CompareDrawRects(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize)
23
        {
24
            var rects =  CompareReturnRects(Originalbitmap, TargatBitmap, ResultRectSize);
25

    
26
            if (rects.Count != 0)
27
            {
28
                using (Graphics g = Graphics.FromImage(Originalbitmap))
29
                {
30
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
31

    
32
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
33
                    g.Save();
34

    
35
                    g.Dispose();
36
                }
37
            }
38

    
39
            return Originalbitmap;
40
        }
41

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

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

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

    
58
                    g.Dispose();
59
                }
60
            }
61

    
62
            return CreateBitmapSourceFromBitmap(_Originalbitmap);
63
        }
64

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

    
69
            Bitmap Originalbitmap = null;
70
            Bitmap TargatBitmap = null;
71

    
72
            try
73
            {
74

    
75
                Originalbitmap = LoadPicture(OriginalbitmapUri);
76
                TargatBitmap = LoadPicture(TargatBitmapUri);
77

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

    
90
            return result;
91
        }
92

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

    
104
            try
105
            {
106
                byte[,,] data = MathchesImageData(Originalbitmap, TargatBitmap);
107

    
108
                result =  GetMatchPixels(data, ResultRectSize);
109
            }
110
            catch (Exception ex)
111
            {
112
                throw ex;
113
            }
114
            finally
115
            {
116

    
117
            }
118

    
119
            return result;
120
        }
121

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

    
134
            var rects = await CompareReturnRectsAsync(cloneOriginal, TargatBitmap, ResultRectSize);
135

    
136
            if (rects.Count != 0)
137
            {
138
                using (Graphics g = Graphics.FromImage(cloneOriginal))
139
                {
140
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
141

    
142
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
143
                    g.Save();
144

    
145
                    g.Dispose();
146
                }
147
            }
148

    
149
            return cloneOriginal;
150
        }
151

    
152
        /// <summary>
153
        /// 이미지를 비교 후 원본 이미지에 Rect를 그린다.
154
        /// 메모리 문제 발생
155
        /// </summary>
156
        /// <param name="Originalbitmap">원본 이미지</param>
157
        /// <param name="TargatBitmap">비교대상 이미지</param>
158
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
159
        /// <returns></returns>
160
        public async Task<System.Windows.Media.Imaging.BitmapSource> CompareDrawRectsAsync(System.Windows.Media.Imaging.BitmapSource Originalbitmap, System.Windows.Media.Imaging.BitmapSource TargatBitmap, Size ResultRectSize)
161
        {
162

    
163
            var _Originalbitmap = CreateBitmapFromSource(Originalbitmap);
164
            var _TargatBitmap = CreateBitmapFromSource(TargatBitmap);
165

    
166
            var rects = await CompareReturnRectsAsync(_Originalbitmap, _TargatBitmap, ResultRectSize);
167

    
168
            if (rects.Count != 0)
169
            {
170
                using (Graphics g = Graphics.FromImage(_Originalbitmap))
171
                {
172
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
173

    
174
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
175
                    g.Save();
176

    
177
                    g.Dispose();
178
                }
179
            }
180

    
181
            return CreateBitmapSourceFromBitmap(_Originalbitmap);
182
        }
183

    
184
        public Bitmap CreateBitmapFromSource(System.Windows.Media.Imaging.BitmapSource bitmapsource)
185
        {
186
            //convert image format
187
            var src = new System.Windows.Media.Imaging.FormatConvertedBitmap();
188
            src.BeginInit();
189
            src.Source = bitmapsource;
190
            src.DestinationFormat = System.Windows.Media.PixelFormats.Bgr24;
191
            src.EndInit();
192

    
193
            //copy to bitmap
194
            Bitmap bitmap = new Bitmap(src.PixelWidth, src.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
195
            var data = bitmap.LockBits(new Rectangle(Point.Empty, bitmap.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
196
            src.CopyPixels(System.Windows.Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
197
            bitmap.UnlockBits(data);
198

    
199
            return bitmap;
200
        }
201

    
202
        /// <summary>
203
        /// 메모리 문제 발생
204
        /// </summary>
205
        /// <param name="bitmap"></param>
206
        /// <returns></returns>
207
        public System.Windows.Media.Imaging.WriteableBitmap CreateWriteableBitmapFromBitmap(Bitmap bitmap)
208
        {
209
            System.Windows.Media.Imaging.WriteableBitmap result = null;
210

    
211
            if (bitmap == null)
212
                throw new ArgumentNullException("bitmap");
213

    
214
            try
215
            {
216
                int bytesPerPixel = 4;
217

    
218
                result = new System.Windows.Media.Imaging.WriteableBitmap(bitmap.Width, bitmap.Height,
219
                                                                   bitmap.HorizontalResolution ,bitmap.VerticalResolution,
220
                                                                   bitmap.PixelFormat.Convert(), null);
221

    
222
                Rectangle colorBitmapRectangle = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
223
                System.Windows.Int32Rect colorBitmapInt32Rect = new System.Windows.Int32Rect(0, 0, bitmap.Width, bitmap.Height);
224

    
225
                BitmapData data = bitmap.LockBits(colorBitmapRectangle, ImageLockMode.WriteOnly, bitmap.PixelFormat);
226

    
227
                result.WritePixels(colorBitmapInt32Rect, data.Scan0, data.Width * data.Height * bytesPerPixel, data.Stride);
228

    
229
                bitmap.UnlockBits(data);
230
            }
231
            catch (Exception ex)
232
            {
233
                //throw ex;
234
            }
235
            finally
236
            {
237
                bitmap.Dispose();
238
                bitmap = null;
239
                //GC.Collect(2);
240
            }
241

    
242
            return result;
243
        }
244
    
245
        /// <summary>
246
        /// 메모리 문제 발생
247
        /// </summary>
248
        /// <param name="bitmap"></param>
249
        /// <returns></returns>
250
        public System.Windows.Media.Imaging.BitmapSource CreateBitmapSourceFromBitmap(Bitmap bitmap)
251
        {
252
            System.Windows.Media.Imaging.BitmapSource result = null;
253
            
254
            if (bitmap == null)
255
                throw new ArgumentNullException("bitmap");
256

    
257
            try
258
            {
259
                using (var hbitmap = new SafeHBitmapHandle(bitmap.GetHbitmap(), true))
260
                {
261

    
262
                    result = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
263
                        hbitmap.DangerousGetHandle(),
264
                        IntPtr.Zero,
265
                        System.Windows.Int32Rect.Empty,
266
                        System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
267

    
268
                   
269
                }
270
            }
271
            catch (Exception ex)
272
            {
273
                //throw ex;
274
            }
275
            finally
276
            {
277
                bitmap.Dispose();
278
                bitmap = null;
279
                //GC.Collect(2);
280
            }
281

    
282
            return result;
283
        }
284

    
285
        public async Task<List<System.Windows.Rect>> CompareReturnRectsAsync(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize)
286
        {
287
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
288

    
289
            Bitmap Originalbitmap = null;
290
            Bitmap TargatBitmap = null;
291

    
292
            try
293
            {
294

    
295
                Originalbitmap = LoadPicture(OriginalbitmapUri);
296
                TargatBitmap = LoadPicture(TargatBitmapUri);
297

    
298
                result = await CompareReturnRectsAsync(Originalbitmap, TargatBitmap, ResultRectSize);
299
            }
300
            catch (Exception)
301
            {
302
                throw;
303
            }
304
            finally
305
            {
306
                Originalbitmap.Dispose();
307
                TargatBitmap.Dispose();
308
            }
309

    
310
            return result;
311
        }
312

    
313
        /// <summary>
314
        /// 이미지를 비교 후 해당 영역을 Rect로 반환한다.
315
        /// </summary>
316
        /// <param name="Originalbitmap">원본 이미지</param>
317
        /// <param name="TargatBitmap">비교대상 이미지</param>
318
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
319
        /// <returns></returns>
320
        public async Task<List<System.Windows.Rect>> CompareReturnRectsAsync(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize)
321
        {
322
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
323

    
324
            try
325
            {
326
                byte[,,] data = MathchesImageData(Originalbitmap, TargatBitmap);
327

    
328
                result = await GetMatchPixelsAsnc(data, ResultRectSize);
329

    
330
                data = null;
331
            }
332
            catch (Exception ex)
333
            {
334
                throw ex;
335
            }
336
            finally
337
            {
338
            }
339

    
340
            return result;
341
        }
342

    
343
       
344
        protected override void Dispose(bool disposing)
345
        {
346
            base.Dispose(disposing);
347
        }
348
    }
349
}
클립보드 이미지 추가 (최대 크기: 500 MB)