MFCTools.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. #ifndef __MFC_SELF_USE_TOOLS_H__
  2. #define __MFC_SELF_USE_TOOLS_H__
  3. #include "IntTypes.h"
  4. #include "src/detail/VsValueType.h"
  5. #include "stdafx.h"
  6. #include <string>
  7. #include <wingdi.h>
  8. // 单字节字符串转为宽字节字符串
  9. static std::wstring StringToWString(const std::string& str)
  10. {
  11. int len = 0;
  12. len = str.length();
  13. int unicodeLen = ::MultiByteToWideChar(CP_ACP,
  14. 0,
  15. str.c_str(),
  16. -1,
  17. NULL,
  18. 0);
  19. wchar_t* pUnicode = nullptr;
  20. pUnicode = new wchar_t[unicodeLen + 1];
  21. memset(pUnicode, 0, (unicodeLen + 1)*sizeof(wchar_t));
  22. ::MultiByteToWideChar(CP_ACP,
  23. 0,
  24. str.c_str(),
  25. -1,
  26. (LPWSTR)pUnicode,
  27. unicodeLen);
  28. std::wstring rt;
  29. rt = (wchar_t*)pUnicode;
  30. delete pUnicode;
  31. return rt;
  32. }
  33. // 宽字节字符串转为单字节字符串
  34. static std::string WStringToString(const std::wstring& wstr)
  35. {
  36. char* pElementText = nullptr;
  37. int nTextLen;
  38. // wide char to multi char
  39. nTextLen = WideCharToMultiByte(CP_ACP,
  40. 0,
  41. wstr.c_str(),
  42. -1,
  43. NULL,
  44. 0,
  45. NULL,
  46. NULL);
  47. pElementText = new char[nTextLen + 1];
  48. memset((void*)pElementText, 0, sizeof(char) * (nTextLen + 1));
  49. ::WideCharToMultiByte(CP_ACP,
  50. 0,
  51. wstr.c_str(),
  52. -1,
  53. pElementText,
  54. nTextLen,
  55. NULL,
  56. NULL);
  57. std::string strText;
  58. strText = pElementText;
  59. delete[] pElementText;
  60. return strText;
  61. }
  62. // CString转为std::string
  63. static std::string CStringToString(CString& cstr)
  64. {
  65. #ifdef UNICODE
  66. std::wstring wstr(cstr.GetBuffer());
  67. return WStringToString(wstr);
  68. #else
  69. std::string str(cstr.GetBuffer());
  70. return str;
  71. #endif
  72. }
  73. // std::stirng转为CString
  74. static CString StringToCString(const std::string& str)
  75. {
  76. #ifdef UNICODE
  77. return CString(StringToWString(str).c_str());
  78. #else
  79. return CString(str.c_str());
  80. #endif
  81. }
  82. class CImageHelper
  83. {
  84. public:
  85. CImageHelper(uint16_t imageBitCount = 8)
  86. : m_bitmapInfo(NULL)
  87. , m_imageBitCount(imageBitCount)
  88. , m_currentWidth(0)
  89. , m_currentHeight(0)
  90. , m_rate(0.0)
  91. , m_hPen(NULL)
  92. {
  93. switch (imageBitCount)
  94. {
  95. case 1:
  96. {
  97. m_imageBitCount = 1;
  98. break;
  99. }
  100. case 4:
  101. {
  102. m_imageBitCount = 4;
  103. break;
  104. }
  105. case 8:
  106. {
  107. m_imageBitCount = 8;
  108. break;
  109. }
  110. case 16:
  111. {
  112. m_imageBitCount = 16;
  113. break;
  114. }
  115. case 24:
  116. {
  117. m_imageBitCount = 24;
  118. break;
  119. }
  120. default:
  121. m_imageBitCount = 8;
  122. }
  123. }
  124. ~CImageHelper()
  125. {
  126. if (NULL != m_hPen)
  127. {
  128. ::DeleteObject(m_hPen);
  129. m_hPen = NULL;
  130. }
  131. if (NULL != m_bitmapInfo)
  132. {
  133. delete[] m_bitmapInfo;
  134. m_bitmapInfo = NULL;
  135. }
  136. }
  137. public:
  138. // 设置bitmap信息
  139. void initBitmapInfo(int32_t width, int32_t height)
  140. {
  141. m_bitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  142. m_bitmapInfo->bmiHeader.biWidth = width;
  143. m_bitmapInfo->bmiHeader.biHeight = -(height);
  144. m_bitmapInfo->bmiHeader.biPlanes = 1;
  145. m_bitmapInfo->bmiHeader.biBitCount = m_imageBitCount;
  146. m_bitmapInfo->bmiHeader.biCompression = 0;
  147. m_bitmapInfo->bmiHeader.biSizeImage = (width + 3) / 4 * 4 * height;
  148. m_bitmapInfo->bmiHeader.biXPelsPerMeter = 0;
  149. m_bitmapInfo->bmiHeader.biYPelsPerMeter = 0;
  150. m_bitmapInfo->bmiHeader.biClrUsed = 0;
  151. m_bitmapInfo->bmiHeader.biClrImportant = 0;
  152. for (uint32_t index = 0; index < 256; ++index)
  153. {
  154. m_bitmapInfo->bmiColors[index].rgbBlue = index;
  155. m_bitmapInfo->bmiColors[index].rgbGreen = index;
  156. m_bitmapInfo->bmiColors[index].rgbRed = index;
  157. m_bitmapInfo->bmiColors[index].rgbReserved = 0;
  158. }
  159. }
  160. // 显示灰度图
  161. void showGrayImage(
  162. HWND hWnd,
  163. uint8_t* imageData,
  164. int32_t width,
  165. int32_t height,
  166. const VisionSystem::VsOutAreaArray& outAreas)
  167. {
  168. if (NULL == m_bitmapInfo)
  169. {
  170. m_bitmapInfo = (BITMAPINFO*)new char[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
  171. }
  172. // 绘制背景
  173. if (m_currentWidth != width ||
  174. m_currentHeight != height)
  175. {
  176. setDisplayBackGround(hWnd);
  177. m_currentWidth = width;
  178. m_currentHeight = height;
  179. }
  180. initBitmapInfo(width, height);
  181. bool needDel = false;
  182. uint8_t* bitmapData = NULL;
  183. int32_t newWidth = (width + 3) / 4 * 4;
  184. if (newWidth == width)
  185. {
  186. bitmapData = imageData;
  187. }
  188. else
  189. {
  190. needDel = true;
  191. bitmapData = new uint8_t[newWidth*height];
  192. ::memset(bitmapData, 0, newWidth*height);
  193. for (int32_t index = 0; index < height; ++index)
  194. {
  195. ::memcpy_s(
  196. bitmapData + index*newWidth,
  197. newWidth,
  198. imageData + index*width,
  199. width);
  200. }
  201. }
  202. // 保持原图比例,计算缩放
  203. CRect rect;
  204. GetWindowRect(hWnd, rect);
  205. double xRate = (rect.Width() - 2) / (double)newWidth;
  206. double yRate = (rect.Height() - 2) / (double)height;
  207. double rate = xRate < yRate ? xRate : yRate;
  208. m_rate = rate;
  209. int32_t displayWidth = (int32_t)(newWidth * rate);
  210. int32_t displayHeight = (int32_t)(height * rate);
  211. int32_t displayPointX = (rect.Width() - displayWidth) / 2;
  212. int32_t displayPointY = (rect.Height() - displayHeight) / 2;
  213. m_displayPointX = displayPointX;
  214. m_displayPointY = displayPointY;
  215. // 显示图像
  216. HDC hDC = ::GetDC(hWnd);
  217. ::SetStretchBltMode(hDC, COLORONCOLOR);
  218. ::StretchDIBits(
  219. hDC,
  220. displayPointX,
  221. displayPointY,
  222. displayWidth,
  223. displayHeight,
  224. 0,
  225. 0,
  226. newWidth,
  227. height,
  228. bitmapData,
  229. m_bitmapInfo,
  230. DIB_RGB_COLORS, SRCCOPY);
  231. // 绘制区域
  232. for (uint32_t i = 0; i < outAreas.size(); ++i)
  233. {
  234. drawArea(hDC, outAreas[i]);
  235. }
  236. ::ReleaseDC(hWnd, hDC);
  237. if (needDel)
  238. {
  239. delete[] bitmapData;
  240. }
  241. }
  242. // 设置背景为黑色
  243. void setDisplayBackGround(HWND hWnd)
  244. {
  245. CRect rect;
  246. GetWindowRect(hWnd, rect);
  247. if (NULL == m_bitmapInfo)
  248. {
  249. m_bitmapInfo = (BITMAPINFO*)new char[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
  250. }
  251. initBitmapInfo(rect.Width(), rect.Height());
  252. int32_t bkWidth = (rect.Width() + 3) / 4 * 4;
  253. int32_t bkHeight = rect.Height();
  254. uint8_t* bkBitmapData = new uint8_t[bkWidth*bkHeight];
  255. ::memset(bkBitmapData, 0, bkWidth * bkHeight);
  256. HDC hDC = ::GetDC(hWnd);
  257. ::SetDIBitsToDevice(
  258. hDC,
  259. 0,
  260. 0,
  261. rect.Width(),
  262. rect.Height(),
  263. 0,
  264. 0,
  265. 0,
  266. bkHeight,
  267. bkBitmapData,
  268. m_bitmapInfo,
  269. DIB_RGB_COLORS);
  270. ::ReleaseDC(hWnd, hDC);
  271. delete[] bkBitmapData;
  272. }
  273. private:
  274. // 绘制区域
  275. void drawArea(HDC hDC, const VisionSystem::VsPoint2DArray& point2DArray)
  276. {
  277. // 若未绘制图像,则不绘制区域
  278. if (fabs(m_rate) <= DBL_EPSILON)
  279. {
  280. return;
  281. }
  282. if (NULL == m_hPen)
  283. {
  284. m_hPen = ::CreatePen(PS_SOLID, 2, RGB(0, 0, 255));
  285. }
  286. ::SelectObject(hDC, m_hPen);
  287. for (uint32_t i = 0; i < point2DArray.size(); ++i)
  288. {
  289. if (0 == i)
  290. {
  291. int32_t x = (int32_t)(point2DArray[i]->x * m_rate) + m_displayPointX;
  292. int32_t y = (int32_t)(point2DArray[i]->y * m_rate) + m_displayPointY;
  293. ::MoveToEx(hDC, x, y, NULL);
  294. continue;
  295. }
  296. int32_t x = (int32_t)(point2DArray[i]->x * m_rate) + m_displayPointX;
  297. int32_t y = (int32_t)(point2DArray[i]->y * m_rate) + m_displayPointY;
  298. ::LineTo(hDC, x, y);
  299. // 最后一个点需要补画第一个点
  300. if (i == (point2DArray.size() - 1))
  301. {
  302. x = (int32_t)(point2DArray[0]->x * m_rate) + m_displayPointX;
  303. y = (int32_t)(point2DArray[0]->y * m_rate) + m_displayPointY;
  304. ::LineTo(hDC, x, y);
  305. }
  306. }
  307. }
  308. private:
  309. BITMAPINFO* m_bitmapInfo;
  310. uint16_t m_imageBitCount;
  311. int32_t m_currentWidth;
  312. int32_t m_currentHeight;
  313. double m_rate;
  314. HPEN m_hPen;
  315. int32_t m_displayPointX;
  316. int32_t m_displayPointY;
  317. };
  318. #endif // __MFC_SELF_USE_TOOLS_H__