/Demo/CvvImage.cpp

https://github.com/ArcJonSnow/Demo_for_Windows · C++ · 258 lines · 244 code · 12 blank · 2 comment · 75 complexity · 33cda42a7d4a002ecd70480e78547e08 MD5 · raw file

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