MFC中用CvvImage类进行图片显示的源码

网上找了下Opencv+MFC显示图片的方法,用CvvImage类还是比较方便的,但好像现在的Opencv版本中已经没有这个类了,所以如果要用到这个类可以认为的加上去。

 1 #pragma once
 2 
 3 #ifndef CVVIMAGE_CLASS_DEF
 4 #define CVVIMAGE_CLASS_DEF
 5 
 6 //#include "opencv.hpp"
 7 #include "cv.h"
 8 #include "highgui.h"
 9 /* CvvImage class definition */
10 class  CvvImage
11 {
12 public:
13     CvvImage();
14     virtual ~CvvImage();
15 
16     /* Create image (BGR or grayscale) */
17     virtual bool  Create( int width, int height, int bits_per_pixel, int image_origin = 0 );
18 
19     /* Load image from specified file */
20     virtual bool  Load( const char* filename, int desired_color = 1 );
21 
22     /* Load rectangle from the file */
23     virtual bool  LoadRect( const char* filename,
24         int desired_color, CvRect r );
25 
26 #if defined WIN32 || defined _WIN32
27     virtual bool  LoadRect( const char* filename,
28         int desired_color, RECT r )
29     {
30         return LoadRect( filename, desired_color,
31             cvRect( r.left, r.top, r.right - r.left, r.bottom - r.top ));
32     }
33 #endif
34 
35     /* Save entire image to specified file. */
36     virtual bool  Save( const char* filename );
37 
38     /* Get copy of input image ROI */
39     virtual void  CopyOf( CvvImage& image, int desired_color = -1 );
40     virtual void  CopyOf( IplImage* img, int desired_color = -1 );
41 
42     IplImage* GetImage() { return m_img; };
43     virtual void  Destroy(void);
44 
45     /* width and height of ROI */
46     int Width() { return !m_img ? 0 : !m_img->roi ? m_img->width : m_img->roi->width; };
47     int Height() { return !m_img ? 0 : !m_img->roi ? m_img->height : m_img->roi->height;};
48     int Bpp() { return m_img ? (m_img->depth & 255)*m_img->nChannels : 0; };
49 
50     virtual void  Fill( int color );
51 
52     /* draw to highgui window */
53     virtual void  Show( const char* window );
54 
55 #if defined WIN32 || defined _WIN32
56     /* draw part of image to the specified DC */
57     virtual void  Show( HDC dc, int x, int y, int width, int height,
58         int from_x = 0, int from_y = 0 );
59     /* draw the current image ROI to the specified rectangle of the destination DC */
60     virtual void  DrawToHDC( HDC hDCDst, RECT* pDstRect );
61 #endif
62 
63 protected:
64 
65     IplImage*  m_img;
66 };
67 
68 typedef CvvImage CImage;
69 
70 #endif
  1 #include "StdAfx.h"
  2 #include "CvvImage.h"
  3 
  4 //////////////////////////////////////////////////////////////////////
  5 // Construction/Destruction
  6 //////////////////////////////////////////////////////////////////////
  7 
  8 CV_INLINE RECT NormalizeRect( RECT r );
  9 CV_INLINE RECT NormalizeRect( RECT r )
 10 {
 11     int t;
 12 
 13     if( r.left > r.right )
 14     {
 15         t = r.left;
 16         r.left = r.right;
 17         r.right = t;
 18     }
 19 
 20     if( r.top > r.bottom )
 21     {
 22         t = r.top;
 23         r.top = r.bottom;
 24         r.bottom = t;
 25     }
 26 
 27     return r;
 28 }
 29 
 30 CV_INLINE CvRect RectToCvRect( RECT sr );
 31 CV_INLINE CvRect RectToCvRect( RECT sr )
 32 {
 33     sr = NormalizeRect( sr );
 34     return cvRect( sr.left, sr.top, sr.right - sr.left, sr.bottom - sr.top );
 35 }
 36 
 37 CV_INLINE RECT CvRectToRect( CvRect sr );
 38 CV_INLINE RECT CvRectToRect( CvRect sr )
 39 {
 40     RECT dr;
 41     dr.left = sr.x;
 42     dr.top = sr.y;
 43     dr.right = sr.x + sr.width;
 44     dr.bottom = sr.y + sr.height;
 45 
 46     return dr;
 47 }
 48 
 49 CV_INLINE IplROI RectToROI( RECT r );
 50 CV_INLINE IplROI RectToROI( RECT r )
 51 {
 52     IplROI roi;
 53     r = NormalizeRect( r );
 54     roi.xOffset = r.left;
 55     roi.yOffset = r.top;
 56     roi.width = r.right - r.left;
 57     roi.height = r.bottom - r.top;
 58     roi.coi = 0;
 59 
 60     return roi;
 61 }
 62 
 63 void  FillBitmapInfo( BITMAPINFO* bmi, int width, int height, int bpp, int origin )
 64 {
 65     assert( bmi && width >= 0 && height >= 0 && (bpp == 8 || bpp == 24 || bpp == 32));
 66 
 67     BITMAPINFOHEADER* bmih = &(bmi->bmiHeader);
 68 
 69     memset( bmih, 0, sizeof(*bmih));
 70     bmih->biSize = sizeof(BITMAPINFOHEADER);
 71     bmih->biWidth = width;
 72     bmih->biHeight = origin ? abs(height) : -abs(height);
 73     bmih->biPlanes = 1;
 74     bmih->biBitCount = (unsigned short)bpp;
 75     bmih->biCompression = BI_RGB;
 76 
 77     if( bpp == 8 )
 78     {
 79         RGBQUAD* palette = bmi->bmiColors;
 80         int i;
 81         for( i = 0; i < 256; i++ )
 82         {
 83             palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;
 84             palette[i].rgbReserved = 0;
 85         }
 86     }
 87 }
 88 
 89 CvvImage::CvvImage()
 90 {
 91     m_img = 0;
 92 }
 93 
 94 void CvvImage::Destroy()
 95 {
 96     cvReleaseImage( &m_img );
 97 }
 98 
 99 CvvImage::~CvvImage()
100 {
101     Destroy();
102 }
103 
104 bool  CvvImage::Create( int w, int h, int bpp, int origin )
105 {
106     const unsigned max_img_size = 10000;
107 
108     if( (bpp != 8 && bpp != 24 && bpp != 32) ||
109         (unsigned)w >=  max_img_size || (unsigned)h >= max_img_size ||
110         (origin != IPL_ORIGIN_TL && origin != IPL_ORIGIN_BL))
111     {
112         assert(0); // most probably, it is a programming error
113         return false;
114     }
115 
116     if( !m_img || Bpp() != bpp || m_img->width != w || m_img->height != h )
117     {
118         if( m_img && m_img->nSize == sizeof(IplImage))
119             Destroy();
120 
121         /* prepare IPL header */
122         m_img = cvCreateImage( cvSize( w, h ), IPL_DEPTH_8U, bpp/8 );
123     }
124 
125     if( m_img )
126         m_img->origin = origin == 0 ? IPL_ORIGIN_TL : IPL_ORIGIN_BL;
127 
128     return m_img != 0;
129 }
130 
131 void  CvvImage::CopyOf( CvvImage& image, int desired_color )
132 {
133     IplImage* img = image.GetImage();
134     if( img )
135     {
136         CopyOf( img, desired_color );
137     }
138 }
139 
140 
141 #define HG_IS_IMAGE(img)                                                  \
142     ((img) != 0 && ((const IplImage*)(img))->nSize == sizeof(IplImage) && \
143     ((IplImage*)img)->imageData != 0)
144 
145 
146 void  CvvImage::CopyOf( IplImage* img, int desired_color )
147 {
148     if( HG_IS_IMAGE(img) )
149     {
150         int color = desired_color;
151         CvSize size = cvGetSize( img ); 
152 
153         if( color < 0 )
154             color = img->nChannels > 1;
155 
156         if( Create( size.width, size.height,
157             (!color ? 1 : img->nChannels > 1 ? img->nChannels : 3)*8,
158             img->origin ))
159         {
160             cvConvertImage( img, m_img, 0 );
161         }
162     }
163 }
164 
165 
166 bool  CvvImage::Load( const char* filename, int desired_color )
167 {
168     IplImage* img = cvLoadImage( filename, desired_color );
169     if( !img )
170         return false;
171 
172     CopyOf( img, desired_color );
173     cvReleaseImage( &img );
174 
175     return true;
176 }
177 
178 
179 bool  CvvImage::LoadRect( const char* filename,
180                          int desired_color, CvRect r )
181 {
182     if( r.width < 0 || r.height < 0 ) return false;
183 
184     IplImage* img = cvLoadImage( filename, desired_color );
185     if( !img )
186         return false;
187 
188     if( r.width == 0 || r.height == 0 )
189     {
190         r.width = img->width;
191         r.height = img->height;
192         r.x = r.y = 0;
193     }
194 
195     if( r.x > img->width || r.y > img->height ||
196         r.x + r.width < 0 || r.y + r.height < 0 )
197     {
198         cvReleaseImage( &img );
199         return false;
200     }
201 
202     /* truncate r to source image */
203     if( r.x < 0 )
204     {
205         r.width += r.x;
206         r.x = 0;
207     }
208     if( r.y < 0 )
209     {
210         r.height += r.y;
211         r.y = 0;
212     }
213 
214     if( r.x + r.width > img->width )
215         r.width = img->width - r.x;
216 
217     if( r.y + r.height > img->height )
218         r.height = img->height - r.y;
219 
220     cvSetImageROI( img, r );
221     CopyOf( img, desired_color );
222 
223     cvReleaseImage( &img );
224     return true;
225 }
226 
227 
228 bool  CvvImage::Save( const char* filename )
229 {
230     if( !m_img )
231         return false;
232     cvSaveImage( filename, m_img );
233     return true;
234 }
235 
236 
237 void  CvvImage::Show( const char* window )
238 {
239     if( m_img )
240         cvShowImage( window, m_img );
241 }
242 
243 
244 void  CvvImage::Show( HDC dc, int x, int y, int w, int h, int from_x, int from_y )
245 {
246     if( m_img && m_img->depth == IPL_DEPTH_8U )
247     {
248         uchar buffer[sizeof(BITMAPINFOHEADER) + 1024];
249         BITMAPINFO* bmi = (BITMAPINFO*)buffer;
250         int bmp_w = m_img->width, bmp_h = m_img->height;
251 
252         FillBitmapInfo( bmi, bmp_w, bmp_h, Bpp(), m_img->origin );
253 
254         from_x = MIN( MAX( from_x, 0 ), bmp_w - 1 );
255         from_y = MIN( MAX( from_y, 0 ), bmp_h - 1 );
256 
257         int sw = MAX( MIN( bmp_w - from_x, w ), 0 );
258         int sh = MAX( MIN( bmp_h - from_y, h ), 0 );
259 
260         SetDIBitsToDevice(
261             dc, x, y, sw, sh, from_x, from_y, from_y, sh,
262             m_img->imageData + from_y*m_img->widthStep,
263             bmi, DIB_RGB_COLORS );
264     }
265 }
266 
267 
268 void  CvvImage::DrawToHDC( HDC hDCDst, RECT* pDstRect ) 
269 {
270     if( pDstRect && m_img && m_img->depth == IPL_DEPTH_8U && m_img->imageData )
271     {
272         uchar buffer[sizeof(BITMAPINFOHEADER) + 1024];
273         BITMAPINFO* bmi = (BITMAPINFO*)buffer;
274         int bmp_w = m_img->width, bmp_h = m_img->height;
275 
276         CvRect roi = cvGetImageROI( m_img );
277         CvRect dst = RectToCvRect( *pDstRect );
278 
279         if( roi.width == dst.width && roi.height == dst.height )
280         {
281             Show( hDCDst, dst.x, dst.y, dst.width, dst.height, roi.x, roi.y );
282             return;
283         }
284 
285         if( roi.width > dst.width )
286         {
287             SetStretchBltMode(
288                 hDCDst,           // handle to device context
289                 HALFTONE );
290         }
291         else
292         {
293             SetStretchBltMode(
294                 hDCDst,           // handle to device context
295                 COLORONCOLOR );
296         }
297 
298         FillBitmapInfo( bmi, bmp_w, bmp_h, Bpp(), m_img->origin );
299 
300         ::StretchDIBits(
301             hDCDst,
302             dst.x, dst.y, dst.width, dst.height,
303             roi.x, roi.y, roi.width, roi.height,
304             m_img->imageData, bmi, DIB_RGB_COLORS, SRCCOPY );
305     }
306 }
307 
308 
309 void  CvvImage::Fill( int color )
310 {
311     cvSet( m_img, cvScalar(color&255,(color>>8)&255,(color>>16)&255,(color>>24)&255) );
312 }

 具体使用时,可以:

void CobjTrack_DlgMFCDlg::ShowImage(IplImage* img, UINT ID,bool background)
{    
    CDC* pDC = GetDlgItem( ID ) ->GetDC();
    // 获取 HDC(设备句柄) 来进行绘图操作        
    HDC hDC = pDC ->GetSafeHdc();                
    CRect rect;
    GetDlgItem(ID) ->GetClientRect( &rect );
    // 求出图片控件的宽和高
    int lp=rect.left;
    int rp=rect.right;
    int tp=rect.top;
    int bp=rect.bottom;
    int rw =rp-lp;            
    int rh =bp-tp;
    CvvImage cimg;
    // 清空picture control

    if (background)//这个可以忽略,因为每次载入图片不同的话,不用背景刷新下,上次的图片会残留
    {
        IplImage * bg=cvCreateImage(cvSize(rw,rh),IPL_DEPTH_8U,1);    
        cvZero(bg);
        cimg.CopyOf(bg);
        SetRect(rect,lp,tp,rw+lp,rh+tp);
        cimg.DrawToHDC(hDC,&rect);
        cvReleaseImage(&bg);
    }
    //设置图片区域
    if (img)
    {
        // 读取图片的宽和高,为了能够将图片不变形的显示到整个图片区域,也就是上下或者左右中一种形式撑满
        int imagw=img->width;
        int imagh=img->height;
        int iw=0,ih=0,x=0,y=0;
        if(imagw*rh>imagh*rw)
        {
            iw=rw;
            ih=imagh*rw/imagw;
            x=lp;
            y=tp+(rh-ih)/2;
        }
        else
        {
            ih=rh;
            iw=imagw*rh/imagh;
            x=lp+(rw-iw)/2;
            y=tp;
        }
        SetRect(rect,x,y,x+iw,y+ih);
        frame=cvCreateImage(cvSize(iw,ih),img->depth,img->nChannels);    
        cvResize(img,frame);//上面是自己的东西,主要是下面几行的显示代码,用到cimg就行了
        cimg.CopyOf( frame );
            // 将图片绘制到显示控件的指定区域内    
        cimg.DrawToHDC( hDC, &rect );
    }

    ReleaseDC( pDC );
}

 

posted @ 2013-05-16 21:54  ChudyShao  阅读(705)  评论(0编辑  收藏  举报