全网首发:OSD字幕时,字体数据、间距的正确处理 比如说如果是巍宇这字好处理如果是一丨字体数据只有一行数据如何刷新处理间距又如何处理别担心。我这里有现成的代码。先看处理结果https://blog.csdn.net/quantum7/article/details/153679213FreeType字体加载这个各位想必很熟悉了。FT_Library m_pFTLib NULL; FT_Face m_pFTFace NULL; int m_iFontSize 16; FT_Init_FreeType(m_pFTLib); if (FT_New_Face(m_pFTLib, mFontFile, 0, m_pFTFace)) { WY_LOG_TEXT(FT_New_Face error!); return; } //FT_ENCODING_GB2312, FT_ENCODING_UNICODE FT_Select_Charmap(m_pFTFace, FT_ENCODING_UNICODE); FT_Set_Char_Size (m_pFTFace, 0, m_iFontSize6, 200, 200);加载字符插槽使用的是Slot而不是Glyph。因为代码是用于字幕字幕字符是固定的所以使用了一个std::map保存起来。static FT_GlyphSlot osd_load_char_glyph(const wchar_t wch, const FT_Face pFTFace) { FT_GlyphSlot wslot new FT_GlyphSlotRec(); int result FT_Load_Char( pFTFace, wch, FT_LOAD_RENDER ); FT_GlyphSlot slot pFTFace-glyph; memcpy(wslot, slot, sizeof(FT_GlyphSlotRec)); FT_Bitmap* bmp (slot-bitmap); int size bmp-rows*bmp-width; wslot-bitmap.buffer (unsigned char*)malloc(size); memcpy(wslot-bitmap.buffer, bmp-buffer, size); return wglyph; }正确处理数据及间距#define COLOR_TO_PIXEL(pixel, color, v, index) {int temp color.val[index]*v/0xFF; \ if (temp 0 color.val[index] ! 0) temp 1; \ pixel[index] temp; } #define COLOR_R_INDEX 2 #define COLOR_G_INDEX 1 #define COLOR_B_INDEX 0 void refresh(cv::Mat rgb, cv::Scalar color, int startX, int startY) { bool isBlack (color.val[0] 0 color.val[1] 0 color.val[2] 0); for (int i0; ithis-mTextCount; i) { wchar_t wch this-mText[i]; std::mapwchar_t, FT_GlyphSlot::iterator it mTextGlyphMap.find(wch); FT_GlyphSlot pSlot it-second; FT_Bitmap* pBmp (pSlot-bitmap); int osdWpBmp-width; int osdHpBmp-rows; int osdX startXpSlot-bitmap_left; //高度是pSlot-metrics.vertAdvance/64因为要绘制所以要减去 int osdY startY(pSlot-metrics.vertAdvance/64-pSlot-bitmap_top); for (int j0; josdH; j){ for (int i0; iosdW; i){ unsigned char v pBmp-buffer[osdW*ji]; if (v MIN_FONT_VALUE) { continue; } cv::Vec3b pixel rgb.atcv::Vec3b(osdYj, osdXi); if (isBlack) { v 0xFF-v; pixel[COLOR_B_INDEX] v; pixel[COLOR_G_INDEX] v; pixel[COLOR_R_INDEX] v; } else { COLOR_TO_PIXEL(pixel, color, v, COLOR_B_INDEX); COLOR_TO_PIXEL(pixel, color, v, COLOR_G_INDEX); COLOR_TO_PIXEL(pixel, color, v, COLOR_R_INDEX); } } } // 这个是正确宽度 startX pSlot-metrics.horiAdvance/64; } }