/MFCShowVideoTest/CvvImage.cpp

https://github.com/cqswzqcj/MFCShowVideoTest · C++ · 312 lines · 244 code · 63 blank · 5 comment · 75 complexity · cc15ee77cb7c425592d497f8263a3d34 MD5 · raw file

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