Files
eUi/include/opencvPaintAlgo.hpp
T
2025-06-13 01:55:47 +08:00

96 lines
3.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#include <opencv.hpp>
#pragma region 画叉
static void Cross(cv::Mat& image, const cv::Point& center, int length, int thickness, const cv::Scalar& color = cv::Scalar(255, 255, 255)) {
// 检查输入图像是否有效
if (image.empty()) {
throw std::invalid_argument("Input image is empty");
}
// 计算水平和垂直线段的起点和终点
cv::Point horizontalStart(center.x - length / 2, center.y);
cv::Point horizontalEnd(center.x + length / 2, center.y);
cv::Point verticalStart(center.x, center.y - length / 2);
cv::Point verticalEnd(center.x, center.y + length / 2);
// 绘制水平和垂直线段
cv::line(image, horizontalStart, horizontalEnd, color, thickness);
cv::line(image, verticalStart, verticalEnd, color, thickness);
}
#pragma endregion
#pragma region 写中文
static std::wstring utf8ToWstring(const std::string& utf8Str) {
int len = MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, nullptr, 0);
if (len == 0) return L"";
std::wstring wstr(len, L'\0');
MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, &wstr[0], len);
wstr.pop_back(); // remove null terminator
return wstr;
}
// 在图像上绘制中文(仅 Windows,使用 GDI)
static void putTextZH(cv::Mat& image, const std::string& text, cv::Point org, int fontSize = 20, cv::Scalar color = cv::Scalar(255, 0, 0)) {
// 创建兼容的位图
cv::Mat img;
if (image.channels() == 1)
cv::cvtColor(image, img, cv::COLOR_GRAY2BGRA);
else if (image.channels() == 3)
cv::cvtColor(image, img, cv::COLOR_BGR2BGRA);
else if (image.channels() == 4)
img = image.clone();
else
throw std::runtime_error("Unsupported number of channels");
// 创建 Windows 位图信息
HDC hdc = GetDC(nullptr);
HDC memDC = CreateCompatibleDC(hdc);
BITMAPINFO bmi;
memset(&bmi, 0, sizeof(BITMAPINFO));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = img.cols;
bmi.bmiHeader.biHeight = -img.rows; // top-down
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
void* pBits = nullptr;
HBITMAP hBitmap = CreateDIBSection(memDC, &bmi, DIB_RGB_COLORS, &pBits, nullptr, 0);
SelectObject(memDC, hBitmap);
memcpy(pBits, img.data, img.total() * img.elemSize());
// 设置字体
HFONT hFont = CreateFontW(
fontSize, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE,
GB2312_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
ANTIALIASED_QUALITY, DEFAULT_PITCH | FF_SWISS, L"微软雅黑");
SelectObject(memDC, hFont);
// 设置颜色和背景
SetBkMode(memDC, TRANSPARENT);
SetTextColor(memDC, RGB(color[2], color[1], color[0]));
// 输出文字
std::wstring wtext = utf8ToWstring(text);
TextOutW(memDC, org.x, org.y, wtext.c_str(), static_cast<int>(wtext.length()));
// 拷贝回来
GetDIBits(memDC, hBitmap, 0, img.rows, img.data, &bmi, DIB_RGB_COLORS);
// 转换回原始图像格式
if (image.channels() == 1)
cv::cvtColor(img, image, cv::COLOR_BGRA2GRAY);
else if (image.channels() == 3)
cv::cvtColor(img, image, cv::COLOR_BGRA2BGR);
else if (image.channels() == 4)
image = img.clone();
// 清理
DeleteObject(hFont);
DeleteObject(hBitmap);
DeleteDC(memDC);
ReleaseDC(nullptr, hdc);
}
#pragma endregion