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