CvxText.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. #ifdef _WIN32
  2. #include "stdafx.h"
  3. #endif
  4. #include <wchar.h>
  5. #include <assert.h>
  6. #include <locale.h>
  7. #include <ctype.h>
  8. #include "CvxText.h"
  9. //====================================================================
  10. //====================================================================
  11. // 打开字库
  12. CvxText::CvxText(CHostApi* pHostApi, const char *freeType)
  13. {
  14. assert(freeType != NULL);
  15. // 打开字库文件, 创建一个字体
  16. FT_Error error = FT_Init_FreeType(&m_library);
  17. if (error)
  18. {
  19. pHostApi->Debug(RECORD_LOG_DEBUG, "library FT_Init_FreeType error");
  20. return;
  21. }
  22. error = FT_New_Face(m_library, freeType, 0, &m_face);
  23. if (error == FT_Err_Unknown_File_Format)
  24. {
  25. pHostApi->Debug(RECORD_LOG_DEBUG, "FT_New_Face unsupported font format!");
  26. return;
  27. }
  28. else if (error)
  29. {
  30. pHostApi->Debug(RECORD_LOG_DEBUG, "FT_New_Face can not open font files, error: %d", error);
  31. return;
  32. }
  33. /*
  34. if(FT_Init_FreeType(&m_library)) throw;
  35. if(FT_New_Face(m_library, freeType, 0, &m_face)) throw;
  36. */
  37. // 设置字体输出参数
  38. restoreFont();
  39. // 设置C语言的字符集环境
  40. setlocale(LC_ALL, "");
  41. }
  42. // 释放FreeType资源
  43. CvxText::~CvxText()
  44. {
  45. FT_Done_Face (m_face);
  46. FT_Done_FreeType(m_library);
  47. }
  48. // 设置字体参数:
  49. //
  50. // font - 字体类型, 目前不支持
  51. // size - 字体大小/空白比例/间隔比例/旋转角度
  52. // underline - 下画线
  53. // diaphaneity - 透明度
  54. void CvxText::getFont(int *type, CvScalar *size, bool *underline, float *diaphaneity)
  55. {
  56. if(type) *type = m_fontType;
  57. if(size) *size = m_fontSize;
  58. if(underline) *underline = m_fontUnderline;
  59. if(diaphaneity) *diaphaneity = m_fontDiaphaneity;
  60. }
  61. void CvxText::setFont(int *type, CvScalar *size, bool *underline, float *diaphaneity)
  62. {
  63. // 参数合法性检查
  64. if(type)
  65. {
  66. if(type >= 0) m_fontType = *type;
  67. }
  68. if(size)
  69. {
  70. m_fontSize.val[0] = fabs(size->val[0]);
  71. m_fontSize.val[1] = fabs(size->val[1]);
  72. m_fontSize.val[2] = fabs(size->val[2]);
  73. m_fontSize.val[3] = fabs(size->val[3]);
  74. }
  75. if(underline)
  76. {
  77. m_fontUnderline = *underline;
  78. }
  79. if(diaphaneity)
  80. {
  81. m_fontDiaphaneity = *diaphaneity;
  82. }
  83. FT_Set_Pixel_Sizes(m_face, (int)m_fontSize.val[0], 0);
  84. }
  85. // 恢复原始的字体设置
  86. void CvxText::restoreFont()
  87. {
  88. m_fontType = 0; // 字体类型(不支持)
  89. m_fontSize.val[0] = 20; // 字体大小
  90. m_fontSize.val[1] = 0.5; // 空白字符大小比例
  91. m_fontSize.val[2] = 0.1; // 间隔大小比例
  92. m_fontSize.val[3] = 0; // 旋转角度(不支持)
  93. m_fontUnderline = false; // 下画线(不支持)
  94. m_fontDiaphaneity = 1.0; // 色彩比例(可产生透明效果)
  95. // 设置字符大小
  96. FT_Set_Pixel_Sizes(m_face, (int)m_fontSize.val[0], 0);
  97. }
  98. // 输出函数(颜色默认为黑色)
  99. int CvxText::putText(IplImage *img, const char *text, CvPoint pos)
  100. {
  101. return putText(img, text, pos, CV_RGB(255,255,255));
  102. }
  103. int CvxText::putText(IplImage *img, const wchar_t *text, CvPoint pos)
  104. {
  105. return putText(img, text, pos, CV_RGB(255,255,255));
  106. }
  107. //
  108. int CvxText::putText(IplImage *img, const char *text, CvPoint pos, CvScalar color)
  109. {
  110. if(img == NULL) return -1;
  111. if(text == NULL) return -1;
  112. //
  113. int i;
  114. for(i = 0; text[i] != '\0'; ++i)
  115. {
  116. wchar_t wc = text[i];
  117. // 解析双字节符号
  118. if(!isascii(wc)) mbtowc(&wc, &text[i++], 2);
  119. // 输出当前的字符
  120. putWChar(img, wc, pos, color);
  121. }
  122. return i;
  123. }
  124. int CvxText::putText(IplImage *img, const wchar_t *text, CvPoint pos, CvScalar color)
  125. {
  126. if(img == NULL) return -1;
  127. if(text == NULL) return -1;
  128. //
  129. int i;
  130. for(i = 0; text[i] != '\0'; ++i)
  131. {
  132. // 输出当前的字符
  133. putWChar(img, text[i], pos, color);
  134. }
  135. return i;
  136. }
  137. // 输出当前字符, 更新m_pos位置
  138. void CvxText::putWChar(IplImage *img, wchar_t wc, CvPoint &pos, CvScalar color)
  139. {
  140. // add by ly at 2016/12/28
  141. if (wc == 0x4E00)
  142. {
  143. pos.y -= (int)(m_fontSize.val[0]/2);
  144. }
  145. // 根据unicode生成字体的二值位图
  146. FT_UInt glyph_index = FT_Get_Char_Index(m_face, wc);
  147. FT_Load_Glyph(m_face, glyph_index, FT_LOAD_DEFAULT);
  148. FT_Render_Glyph(m_face->glyph, FT_RENDER_MODE_MONO);
  149. //
  150. FT_GlyphSlot slot = m_face->glyph;
  151. // 行列数
  152. int rows = slot->bitmap.rows;
  153. int cols = slot->bitmap.width;
  154. //
  155. for(int i = 0; i < rows; ++i)
  156. {
  157. for(int j = 0; j < cols; ++j)
  158. {
  159. int off = ((img->origin==0)? i: (rows-1-i))
  160. * slot->bitmap.pitch + j/8;
  161. if(slot->bitmap.buffer[off] & (0xC0 >> (j%8)))
  162. {
  163. int r = (img->origin==0)? pos.y - (rows-1-i): pos.y + i;;
  164. int c = pos.x + j;
  165. if(r >= 0 && r < img->height
  166. && c >= 0 && c < img->width)
  167. {
  168. CvScalar scalar = cvGet2D(img, r, c);
  169. // 进行色彩融合
  170. float p = m_fontDiaphaneity;
  171. for(int k = 0; k < 4; ++k)
  172. {
  173. scalar.val[k] = scalar.val[k]*(1-p) + color.val[k]*p;
  174. }
  175. cvSet2D(img, r, c, scalar);
  176. }
  177. }
  178. } // end for
  179. } // end for
  180. // 修改下一个字的输出位置
  181. double space = m_fontSize.val[0]*m_fontSize.val[1];
  182. double sep = m_fontSize.val[0]*m_fontSize.val[2];
  183. pos.x += (int)((cols? cols: space) + sep);
  184. if (wc == 0x4E00)
  185. {
  186. pos.y += (int)(m_fontSize.val[0]/2);
  187. }
  188. }