Blame view

src/test/CvxText.cpp 4.23 KB
7ba45ddc   Zou XiKun   丢包SDK
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
  #include <wchar.h>
  
  #include <locale.h>
  #include <ctype.h>
  
  #include "CvxText.h"
  
  //====================================================================
  //====================================================================
  
  // 打开字库
  
  CvxText::CvxText(const char *freeType)
  {
  	assert(freeType != NULL);
  
  	// 打开字库文件, 创建一个字体
  
  	if (FT_Init_FreeType(&m_library)) throw;
  	if (FT_New_Face(m_library, freeType, 0, &m_face)) throw;
  
  	// 设置字体输出参数
  
  	restoreFont();
  
  	// 设置C语言的字符集环境
  
  	setlocale(LC_ALL, "");
  }
  
  // 释放FreeType资源
  
  CvxText::~CvxText()
  {
  	FT_Done_Face(m_face);
  	FT_Done_FreeType(m_library);
  }
  
  // 设置字体参数:
  //
  // font         - 字体类型, 目前不支持
  // size         - 字体大小/空白比例/间隔比例/旋转角度
  // underline   - 下画线
  // diaphaneity   - 透明度
  
  void CvxText::getFont(int *type, CvScalar *size, bool *underline, float *diaphaneity)
  {
  	if (type) *type = m_fontType;
  	if (size) *size = m_fontSize;
  	if (underline) *underline = m_fontUnderline;
  	if (diaphaneity) *diaphaneity = m_fontDiaphaneity;
  }
  
  void CvxText::setFont(int *type, CvScalar *size, bool *underline, float *diaphaneity)
  {
  	// 参数合法性检查
  
  	if (type)
  	{
  		if (type >= 0) m_fontType = *type;
  	}
  	if (size)
  	{
  		m_fontSize.val[0] = fabs(size->val[0]);
  		m_fontSize.val[1] = fabs(size->val[1]);
  		m_fontSize.val[2] = fabs(size->val[2]);
  		m_fontSize.val[3] = fabs(size->val[3]);
  		FT_Set_Pixel_Sizes(m_face, (int)m_fontSize.val[0], 0);
  	}
  	if (underline)
  	{
  		m_fontUnderline = *underline;
  	}
  	if (diaphaneity)
  	{
  		m_fontDiaphaneity = *diaphaneity;
  	}
  	//FT_Set_Pixel_Sizes(m_face, (int)m_fontSize.val[0], 0);
  }
  
  // 恢复原始的字体设置
  
  void CvxText::restoreFont()
  {
  	m_fontType = 0;            // 字体类型(不支持)
  
  	m_fontSize.val[0] = 20;      // 字体大小
  	m_fontSize.val[1] = 0.5;   // 空白字符大小比例
  	m_fontSize.val[2] = 0.1;   // 间隔大小比例
  	m_fontSize.val[3] = 0;      // 旋转角度(不支持)
  
  	m_fontUnderline = false;   // 下画线(不支持)
  
  	m_fontDiaphaneity = 1.0;   // 色彩比例(可产生透明效果)
  
  							   // 设置字符大小
  
  	FT_Set_Pixel_Sizes(m_face, (int)m_fontSize.val[0], 0);
  }
  
  // 输出函数(颜色默认为黑色)
  
  int CvxText::putText(IplImage *img, const char    *text, CvPoint pos)
  {
  	return putText(img, text, pos, CV_RGB(255, 255, 255));
  }
  int CvxText::putText(IplImage *img, const wchar_t *text, CvPoint pos)
  {
  	return putText(img, text, pos, CV_RGB(255, 255, 255));
  }
  
  //
  
  int CvxText::putText(IplImage *img, const char    *text, CvPoint pos, CvScalar color)
  {
  	if (img == NULL) return -1;
  	if (text == NULL) return -1;
  
  	//
  
  	int i;
  	for (i = 0; text[i] != '\0'; ++i)
  	{
  		wchar_t wc = text[i];
  
  		// 解析双字节符号
  
  		if (!isascii(wc)) mbtowc(&wc, &text[i++], 2);
  
  		// 输出当前的字符
  
  		putWChar(img, wc, pos, color);
  	}
  	return i;
  }
  int CvxText::putText(IplImage *img, const wchar_t *text, CvPoint pos, CvScalar color)
  {
  	if (img == NULL) return -1;
  	if (text == NULL) return -1;
  
  	//
  
  	int i;
  	for (i = 0; text[i] != '\0'; ++i)
  	{
  		// 输出当前的字符
  
  		putWChar(img, text[i], pos, color);
  	}
  	return i;
  }
  
  // 输出当前字符, 更新m_pos位置
  
  void CvxText::putWChar(IplImage *img, wchar_t wc, CvPoint &pos, CvScalar color)
  {
  	// 根据unicode生成字体的二值位图
  
  	FT_UInt glyph_index = FT_Get_Char_Index(m_face, wc);
  	FT_Load_Glyph(m_face, glyph_index, FT_LOAD_DEFAULT);
  	FT_Render_Glyph(m_face->glyph, FT_RENDER_MODE_MONO);
  
  	//
  
  	FT_GlyphSlot slot = m_face->glyph;
  
  	// 行列数
  
  	int rows = slot->bitmap.rows;
  	int cols = slot->bitmap.width;
  
  	//
  
  	for (int i = 0; i < rows; ++i)
  	{
  		for (int j = 0; j < cols; ++j)
  		{
  			int off = ((img->origin == 0) ? i : (rows - 1 - i))
  				* slot->bitmap.pitch + j / 8;
  
  			if (slot->bitmap.buffer[off] & (0xC0 >> (j % 8)))
  			{
  				int r = (img->origin == 0) ? pos.y - (rows - 1 - i) : pos.y + i;;
  				int c = pos.x + j;
  
  				if (r >= 0 && r < img->height
  					&& c >= 0 && c < img->width)
  				{
  					CvScalar scalar = cvGet2D(img, r, c);
  
  					// 进行色彩融合
  
  					float p = m_fontDiaphaneity;
  					for (int k = 0; k < 4; ++k)
  					{
  						scalar.val[k] = scalar.val[k] * (1 - p) + color.val[k] * p;
  					}
  
  					cvSet2D(img, r, c, scalar);
  				}
  			}
  		} // end for
  	} // end for
  
  	  // 修改下一个字的输出位置
  
  	double space = m_fontSize.val[0] * m_fontSize.val[1];
  	double sep = m_fontSize.val[0] * m_fontSize.val[2];
  
  	pos.x += (int)((cols ? cols : space) + sep);
  }