#ifndef __MFC_SELF_USE_TOOLS_H__ #define __MFC_SELF_USE_TOOLS_H__ #include "IntTypes.h" #include "src/detail/VsValueType.h" #include "stdafx.h" #include #include // 单字节字符串转为宽字节字符串 static std::wstring StringToWString(const std::string& str) { int len = 0; len = str.length(); int unicodeLen = ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0); wchar_t* pUnicode = nullptr; pUnicode = new wchar_t[unicodeLen + 1]; memset(pUnicode, 0, (unicodeLen + 1)*sizeof(wchar_t)); ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, (LPWSTR)pUnicode, unicodeLen); std::wstring rt; rt = (wchar_t*)pUnicode; delete pUnicode; return rt; } // 宽字节字符串转为单字节字符串 static std::string WStringToString(const std::wstring& wstr) { char* pElementText = nullptr; int nTextLen; // wide char to multi char nTextLen = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, NULL, 0, NULL, NULL); pElementText = new char[nTextLen + 1]; memset((void*)pElementText, 0, sizeof(char) * (nTextLen + 1)); ::WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, pElementText, nTextLen, NULL, NULL); std::string strText; strText = pElementText; delete[] pElementText; return strText; } // CString转为std::string static std::string CStringToString(CString& cstr) { #ifdef UNICODE std::wstring wstr(cstr.GetBuffer()); return WStringToString(wstr); #else std::string str(cstr.GetBuffer()); return str; #endif } // std::stirng转为CString static CString StringToCString(const std::string& str) { #ifdef UNICODE return CString(StringToWString(str).c_str()); #else return CString(str.c_str()); #endif } class CImageHelper { public: CImageHelper(uint16_t imageBitCount = 8) : m_bitmapInfo(NULL) , m_imageBitCount(imageBitCount) , m_currentWidth(0) , m_currentHeight(0) , m_rate(0.0) , m_hPen(NULL) { switch (imageBitCount) { case 1: { m_imageBitCount = 1; break; } case 4: { m_imageBitCount = 4; break; } case 8: { m_imageBitCount = 8; break; } case 16: { m_imageBitCount = 16; break; } case 24: { m_imageBitCount = 24; break; } default: m_imageBitCount = 8; } } ~CImageHelper() { if (NULL != m_hPen) { ::DeleteObject(m_hPen); m_hPen = NULL; } if (NULL != m_bitmapInfo) { delete[] m_bitmapInfo; m_bitmapInfo = NULL; } } public: // 设置bitmap信息 void initBitmapInfo(int32_t width, int32_t height) { m_bitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); m_bitmapInfo->bmiHeader.biWidth = width; m_bitmapInfo->bmiHeader.biHeight = -(height); m_bitmapInfo->bmiHeader.biPlanes = 1; m_bitmapInfo->bmiHeader.biBitCount = m_imageBitCount; m_bitmapInfo->bmiHeader.biCompression = 0; m_bitmapInfo->bmiHeader.biSizeImage = (width + 3) / 4 * 4 * height; m_bitmapInfo->bmiHeader.biXPelsPerMeter = 0; m_bitmapInfo->bmiHeader.biYPelsPerMeter = 0; m_bitmapInfo->bmiHeader.biClrUsed = 0; m_bitmapInfo->bmiHeader.biClrImportant = 0; for (uint32_t index = 0; index < 256; ++index) { m_bitmapInfo->bmiColors[index].rgbBlue = index; m_bitmapInfo->bmiColors[index].rgbGreen = index; m_bitmapInfo->bmiColors[index].rgbRed = index; m_bitmapInfo->bmiColors[index].rgbReserved = 0; } } // 显示灰度图 void showGrayImage( HWND hWnd, uint8_t* imageData, int32_t width, int32_t height, const VisionSystem::VsOutAreaArray& outAreas) { if (NULL == m_bitmapInfo) { m_bitmapInfo = (BITMAPINFO*)new char[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)]; } // 绘制背景 if (m_currentWidth != width || m_currentHeight != height) { setDisplayBackGround(hWnd); m_currentWidth = width; m_currentHeight = height; } initBitmapInfo(width, height); bool needDel = false; uint8_t* bitmapData = NULL; int32_t newWidth = (width + 3) / 4 * 4; if (newWidth == width) { bitmapData = imageData; } else { needDel = true; bitmapData = new uint8_t[newWidth*height]; ::memset(bitmapData, 0, newWidth*height); for (int32_t index = 0; index < height; ++index) { ::memcpy_s( bitmapData + index*newWidth, newWidth, imageData + index*width, width); } } // 保持原图比例,计算缩放 CRect rect; GetWindowRect(hWnd, rect); double xRate = (rect.Width() - 2) / (double)newWidth; double yRate = (rect.Height() - 2) / (double)height; double rate = xRate < yRate ? xRate : yRate; m_rate = rate; int32_t displayWidth = (int32_t)(newWidth * rate); int32_t displayHeight = (int32_t)(height * rate); int32_t displayPointX = (rect.Width() - displayWidth) / 2; int32_t displayPointY = (rect.Height() - displayHeight) / 2; m_displayPointX = displayPointX; m_displayPointY = displayPointY; // 显示图像 HDC hDC = ::GetDC(hWnd); ::SetStretchBltMode(hDC, COLORONCOLOR); ::StretchDIBits( hDC, displayPointX, displayPointY, displayWidth, displayHeight, 0, 0, newWidth, height, bitmapData, m_bitmapInfo, DIB_RGB_COLORS, SRCCOPY); // 绘制区域 for (uint32_t i = 0; i < outAreas.size(); ++i) { drawArea(hDC, outAreas[i]); } ::ReleaseDC(hWnd, hDC); if (needDel) { delete[] bitmapData; } } // 设置背景为黑色 void setDisplayBackGround(HWND hWnd) { CRect rect; GetWindowRect(hWnd, rect); if (NULL == m_bitmapInfo) { m_bitmapInfo = (BITMAPINFO*)new char[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)]; } initBitmapInfo(rect.Width(), rect.Height()); int32_t bkWidth = (rect.Width() + 3) / 4 * 4; int32_t bkHeight = rect.Height(); uint8_t* bkBitmapData = new uint8_t[bkWidth*bkHeight]; ::memset(bkBitmapData, 0, bkWidth * bkHeight); HDC hDC = ::GetDC(hWnd); ::SetDIBitsToDevice( hDC, 0, 0, rect.Width(), rect.Height(), 0, 0, 0, bkHeight, bkBitmapData, m_bitmapInfo, DIB_RGB_COLORS); ::ReleaseDC(hWnd, hDC); delete[] bkBitmapData; } private: // 绘制区域 void drawArea(HDC hDC, const VisionSystem::VsPoint2DArray& point2DArray) { // 若未绘制图像,则不绘制区域 if (fabs(m_rate) <= DBL_EPSILON) { return; } if (NULL == m_hPen) { m_hPen = ::CreatePen(PS_SOLID, 2, RGB(0, 0, 255)); } ::SelectObject(hDC, m_hPen); for (uint32_t i = 0; i < point2DArray.size(); ++i) { if (0 == i) { int32_t x = (int32_t)(point2DArray[i]->x * m_rate) + m_displayPointX; int32_t y = (int32_t)(point2DArray[i]->y * m_rate) + m_displayPointY; ::MoveToEx(hDC, x, y, NULL); continue; } int32_t x = (int32_t)(point2DArray[i]->x * m_rate) + m_displayPointX; int32_t y = (int32_t)(point2DArray[i]->y * m_rate) + m_displayPointY; ::LineTo(hDC, x, y); // 最后一个点需要补画第一个点 if (i == (point2DArray.size() - 1)) { x = (int32_t)(point2DArray[0]->x * m_rate) + m_displayPointX; y = (int32_t)(point2DArray[0]->y * m_rate) + m_displayPointY; ::LineTo(hDC, x, y); } } } private: BITMAPINFO* m_bitmapInfo; uint16_t m_imageBitCount; int32_t m_currentWidth; int32_t m_currentHeight; double m_rate; HPEN m_hPen; int32_t m_displayPointX; int32_t m_displayPointY; }; #endif // __MFC_SELF_USE_TOOLS_H__