#include "cv_put_Text.hpp" PutText::PutText(const char* font_path) { // 初始化 FreeType if (FT_Init_FreeType(&ft)) { std::cerr << "Error: Could not init FreeType !" << std::endl; return; } // 加载字体文件( 这里使用 SimHei.ttf 字体文件) if (FT_New_Face(ft, font_path, 0, &face)) { std::cerr << "Error: Load front failed!" << std::endl; exit(-1); } } PutText::~PutText() { // 释放 FreeType 资源 FT_Done_Face(face); FT_Done_FreeType(ft); } void PutText::putText(cv::Mat& img, const std::string& text, int x, int y, int fontSize, cv::Scalar color) { if(img.empty()) { std::cerr << "Empty image!"; return ; } // 设置字体大小 FT_Set_Pixel_Sizes(face, 0, fontSize); int start_point_x = x; int start_point_y = y + fontSize; // 调整基线 // 循环处理每个字符 for (size_t i = 0; i < text.size(); ) { // 解析 UTF-8 字符 unsigned long unicode = 0; if ((text[i] & 0x80) == 0) { unicode = text[i]; i += 1; } else if ((text[i] & 0xE0) == 0xC0) { unicode = ((text[i] & 0x1F) << 6) | (text[i + 1] & 0x3F); i += 2; } else if ((text[i] & 0xF0) == 0xE0) { unicode = ((text[i] & 0x0F) << 12) | ((text[i + 1] & 0x3F) << 6) | (text[i + 2] & 0x3F); i += 3; } else { i++; // 无效 UTF-8 continue; } // 加载字符字形 if (FT_Load_Char(face, unicode, FT_LOAD_RENDER)) { std::cerr << "Error: Could not load glyph" << std::endl; continue; } // 绘制到 OpenCV 图像 FT_Bitmap& bitmap = face->glyph->bitmap; for (int row = 0; row < bitmap.rows; ++row) { for (int col = 0; col < bitmap.width; ++col) { unsigned char intensity = bitmap.buffer[row * bitmap.width + col]; if (intensity > 0) { cv::Vec3b& pixel = img.at(start_point_y - face->glyph->bitmap_top + row, start_point_x + face->glyph->bitmap_left + col); pixel[0] = color[0] * (intensity / 255.0) + pixel[0] * (1 - intensity / 255.0); pixel[1] = color[1] * (intensity / 255.0) + pixel[1] * (1 - intensity / 255.0); pixel[2] = color[2] * (intensity / 255.0) + pixel[2] * (1 - intensity / 255.0); } } } start_point_x += face->glyph->advance.x >> 6; } }