cv_put_Text.cpp 2.5 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#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<cv::Vec3b>(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;
    }
}