CvxText.cpp 4.9 KB

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