CvxText.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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(const char *freeType)
  13. {
  14. assert(freeType != NULL);
  15. // 打开字库文件, 创建一个字体
  16. if(FT_Init_FreeType(&m_library)) throw;
  17. if(FT_New_Face(m_library, freeType, 0, &m_face)) throw;
  18. // 设置字体输出参数
  19. restoreFont();
  20. // 设置C语言的字符集环境
  21. setlocale(LC_ALL, "");
  22. }
  23. // 释放FreeType资源
  24. CvxText::~CvxText()
  25. {
  26. FT_Done_Face(m_face);
  27. FT_Done_FreeType(m_library);
  28. }
  29. // 设置字体参数:
  30. //
  31. // font - 字体类型, 目前不支持
  32. // size - 字体大小/空白比例/间隔比例/旋转角度
  33. // underline - 下画线
  34. // diaphaneity - 透明度
  35. void CvxText::getFont(int *type, CvScalar *size, bool *underline, float *diaphaneity)
  36. {
  37. if(type) *type = m_fontType;
  38. if(size) *size = m_fontSize;
  39. if(underline) *underline = m_fontUnderline;
  40. if(diaphaneity) *diaphaneity = m_fontDiaphaneity;
  41. }
  42. void CvxText::setFont(int *type, CvScalar *size, bool *underline, float *diaphaneity)
  43. {
  44. // 参数合法性检查
  45. if(type)
  46. {
  47. if(type >= 0) m_fontType = *type;
  48. }
  49. if(size)
  50. {
  51. m_fontSize.val[0] = fabs(size->val[0]);
  52. m_fontSize.val[1] = fabs(size->val[1]);
  53. m_fontSize.val[2] = fabs(size->val[2]);
  54. m_fontSize.val[3] = fabs(size->val[3]);
  55. }
  56. if(underline)
  57. {
  58. m_fontUnderline = *underline;
  59. }
  60. if(diaphaneity)
  61. {
  62. m_fontDiaphaneity = *diaphaneity;
  63. }
  64. FT_Set_Pixel_Sizes(m_face, (int)m_fontSize.val[0], 0);
  65. }
  66. // 恢复原始的字体设置
  67. void CvxText::restoreFont()
  68. {
  69. m_fontType = 0; // 字体类型(不支持)
  70. m_fontSize.val[0] = 20; // 字体大小
  71. m_fontSize.val[1] = 0.5; // 空白字符大小比例
  72. m_fontSize.val[2] = 0.1; // 间隔大小比例
  73. m_fontSize.val[3] = 0; // 旋转角度(不支持)
  74. m_fontUnderline = false; // 下画线(不支持)
  75. m_fontDiaphaneity = 1.0; // 色彩比例(可产生透明效果)
  76. // 设置字符大小
  77. FT_Set_Pixel_Sizes(m_face, (int)m_fontSize.val[0], 0);
  78. }
  79. // 输出函数(颜色默认为黑色)
  80. int CvxText::putText(IplImage *img, const char *text, CvPoint pos)
  81. {
  82. return putText(img, text, pos, CV_RGB(255,255,255));
  83. }
  84. int CvxText::putText(IplImage *img, const wchar_t *text, CvPoint pos)
  85. {
  86. return putText(img, text, pos, CV_RGB(255,255,255));
  87. }
  88. //
  89. int CvxText::putText(IplImage *img, const char *text, CvPoint pos, CvScalar color)
  90. {
  91. if(img == NULL) return -1;
  92. if(text == NULL) return -1;
  93. //
  94. int i;
  95. for(i = 0; text[i] != '\0'; ++i)
  96. {
  97. wchar_t wc = text[i];
  98. // 解析双字节符号
  99. if(!isascii(wc)) mbtowc(&wc, &text[i++], 2);
  100. // 输出当前的字符
  101. putWChar(img, wc, pos, color);
  102. }
  103. return i;
  104. }
  105. int CvxText::putText(IplImage *img, const wchar_t *text, CvPoint pos, CvScalar color)
  106. {
  107. if(img == NULL) return -1;
  108. if(text == NULL) return -1;
  109. //
  110. int i;
  111. for(i = 0; text[i] != '\0'; ++i)
  112. {
  113. // 输出当前的字符
  114. putWChar(img, text[i], pos, color);
  115. }
  116. return i;
  117. }
  118. // 输出当前字符, 更新m_pos位置
  119. void CvxText::putWChar(IplImage *img, wchar_t wc, CvPoint &pos, CvScalar color)
  120. {
  121. if (wc == 0x4E00){
  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. if (wc == 0x4E00)
  164. {
  165. pos.y += (int)(m_fontSize.val[0]/2);
  166. }
  167. }