优化osd绘制代码

serial
BlueMatthew 1 year ago
parent 4de8b2ec79
commit 22fd597163

@ -620,7 +620,7 @@ namespace cv {
// Update current position ( in FreeType coordinates )
float advance = mFace->glyph->advance.x >> 6;
currentPos.x += mFace->glyph->advance.x + mFace->glyph->bitmap_left;
currentPos.x += mFace->glyph->advance.x + mFace->glyph->metrics.horiBearingX;
currentPos.y += mFace->glyph->advance.y;
// currentPos.x += mFace->glyph->metrics.horiBearingX >> 6;
// currentPos.y += mFace->glyph->metrics.horiBearingY >> 6;
@ -628,7 +628,7 @@ namespace cv {
// currentPos.x += mFace->glyph->metrics.horiBearingX;
// currentPos.y += mFace->glyph->metrics.horiBearingY;
// break;
_org.x += (mFace->glyph->advance.x + mFace->glyph->bitmap_left) >> 6;
_org.x += (mFace->glyph->advance.x + mFace->glyph->metrics.horiBearingX) >> 6;
_org.y += mFace->glyph->advance.y >> 6;
}
@ -638,29 +638,36 @@ namespace cv {
#endif 0
}
Size FreeType2Impl::getTextSize(
const String& _text,
int _fontHeight,
int _thickness,
CV_OUT int* _baseLine)
{
if (_text.empty())
{
return Size(0, 0);
}
CV_Assert(_fontHeight >= 0);
if (_fontHeight == 0)
{
return Size(0, 0);
}
CV_Assert(!FT_Set_Pixel_Sizes(mFace, _fontHeight, _fontHeight));
FT_Vector currentPos = { 0,0 };
FT_Set_Transform(mFace, 0, &currentPos);
Size FreeType2Impl::getTextSize(
const String& _text,
int _fontHeight,
int _thickness,
CV_OUT int* _baseLine)
{
if (_text.empty())
{
return Size(0, 0);
}
CV_Assert(_fontHeight >= 0);
if (_fontHeight == 0)
{
return Size(0, 0);
}
CV_Assert(!FT_Set_Pixel_Sizes(mFace, _fontHeight, _fontHeight));
FT_UInt glyph_index;
FT_Bool use_kerning;
FT_UInt previous;
use_kerning = FT_HAS_KERNING(mFace);
previous = 0;
FT_Vector currentPos = { 0,0 };
FT_Set_Transform(mFace, 0, &currentPos);
#if defined(USING_HB)
hb_buffer_t *hb_buffer = hb_buffer_create();
hb_buffer_t *hb_buffer = hb_buffer_create();
CV_Assert(hb_buffer != NULL);
hb_buffer_add_utf8(hb_buffer, _text.c_str(), -1, 0, -1);
@ -672,89 +679,102 @@ namespace cv {
hb_buffer_get_glyph_infos(hb_buffer, &textLen);
CV_Assert(info != NULL);
#else
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
wstring wstr = converter.from_bytes(_text);
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
wstring wstr = converter.from_bytes(_text);
#endif
// Initilize BoundaryBox ( in OpenCV coordinates )
int xMin = INT_MAX, yMin = INT_MAX;
int xMax = INT_MIN, yMax = INT_MIN;
// Initilize BoundaryBox ( in OpenCV coordinates )
int xMin = INT_MAX, yMin = INT_MAX;
int xMax = INT_MIN, yMax = INT_MIN;
#if defined(USING_HB)
for (unsigned int i = 0; i < textLen; i++) {
CV_Assert(!FT_Load_Glyph(mFace, info[i].codepoint, 0));
for (unsigned int i = 0; i < textLen; i++) {
glyph_index = info[i].codepoint;
CV_Assert(!FT_Load_Glyph(mFace, glyph_index, 0));
#else
for (unsigned int i = 0; i < wstr.size(); i++) {
if (wstr[i] == '\r' || wstr[i] == '\n')
{
// xMin = cv::min(xMin, ftd(bbox.xMin));
// xMax = cv::max(xMax, ftd(bbox.xMax));
// yMin = cv::min(yMin, ftd(bbox.yMin));
// yMax = cv::max(yMax, currentPos.y + (mFace->glyph->advance.y));
continue;
}
CV_Assert(!FT_Load_Glyph(mFace, FT_Get_Char_Index(mFace, wstr[i]), 0));
for (unsigned int i = 0; i < wstr.size(); i++) {
if (wstr[i] == '\r' || wstr[i] == '\n')
{
// xMin = cv::min(xMin, ftd(bbox.xMin));
// xMax = cv::max(xMax, ftd(bbox.xMax));
// yMin = cv::min(yMin, ftd(bbox.yMin));
// yMax = cv::max(yMax, currentPos.y + (mFace->glyph->advance.y));
continue;
}
glyph_index = FT_Get_Char_Index(mFace, wstr[i]);
CV_Assert(!FT_Load_Glyph(mFace, glyph_index, 0));
#endif
FT_GlyphSlot slot = mFace->glyph;
FT_Outline outline = slot->outline;
FT_BBox bbox;
// Flip ( in FreeType coordinates )
FT_Matrix mtx = { 1 << 16 , 0 , 0 , -(1 << 16) };
FT_Outline_Transform(&outline, &mtx);
// Move to current position ( in FreeType coordinates )
FT_Outline_Translate(&outline, currentPos.x, currentPos.y);
// Get BoundaryBox ( in FreeType coordinatrs )
CV_Assert(!FT_Outline_Get_BBox(&outline, &bbox));
// If codepoint is space(0x20), it has no glyph.
// A dummy boundary box is needed when last code is space.
if (
(bbox.xMin == 0) && (bbox.xMax == 0) &&
(bbox.yMin == 0) && (bbox.yMax == 0)
)
{
bbox.xMin = currentPos.x;
bbox.xMax = currentPos.x + (mFace->glyph->advance.x);
bbox.yMin = yMin;
bbox.yMax = yMax;
}
/* retrieve kerning distance and move pen position */
if (use_kerning && previous)
{
FT_Vector delta;
FT_Get_Kerning(mFace, previous, glyph_index, FT_KERNING_DEFAULT, &delta);
currentPos.x += delta.x >> 6;
}
FT_GlyphSlot slot = mFace->glyph;
FT_Outline outline = slot->outline;
FT_BBox bbox;
// Flip ( in FreeType coordinates )
FT_Matrix mtx = { 1 << 16 , 0 , 0 , -(1 << 16) };
FT_Outline_Transform(&outline, &mtx);
// Update current position ( in FreeType coordinates )
currentPos.x += mFace->glyph->advance.x + mFace->glyph->bitmap_left;
currentPos.y += mFace->glyph->advance.y;
// Move to current position ( in FreeType coordinates )
FT_Outline_Translate(&outline, currentPos.x, currentPos.y);
// Update BoundaryBox ( in OpenCV coordinates )
xMin = cv::min(xMin, ftd(bbox.xMin));
xMax = cv::max(xMax, ftd(bbox.xMax));
yMin = cv::min(yMin, ftd(bbox.yMin));
yMax = cv::max(yMax, ftd(bbox.yMax));
}
// Get BoundaryBox ( in FreeType coordinatrs )
CV_Assert(!FT_Outline_Get_BBox(&outline, &bbox));
// If codepoint is space(0x20), it has no glyph.
// A dummy boundary box is needed when last code is space.
if (
(bbox.xMin == 0) && (bbox.xMax == 0) &&
(bbox.yMin == 0) && (bbox.yMax == 0)
)
{
bbox.xMin = currentPos.x;
bbox.xMax = currentPos.x + (mFace->glyph->advance.x + mFace->glyph->bitmap_left);
bbox.yMin = yMin;
bbox.yMax = yMax;
}
// Update current position ( in FreeType coordinates )
currentPos.x += mFace->glyph->advance.x + mFace->glyph->bitmap_left;
currentPos.y += mFace->glyph->advance.y;
// Update BoundaryBox ( in OpenCV coordinates )
xMin = cv::min(xMin, ftd(bbox.xMin));
xMax = cv::max(xMax, ftd(bbox.xMax));
yMin = cv::min(yMin, ftd(bbox.yMin));
yMax = cv::max(yMax, ftd(bbox.yMax));
previous = glyph_index;
}
#if defined(USING_HB)
hb_buffer_destroy(hb_buffer);
hb_buffer_destroy(hb_buffer);
#endif
// Calcurate width/height/baseline ( in OpenCV coordinates )
int width = xMax - xMin;
int height = -yMin;
// Calcurate width/height/baseline ( in OpenCV coordinates )
int width = xMax - xMin;
int height = -yMin;
if (_thickness > 0) {
width = cvRound(width + _thickness * 2);
height = cvRound(height + _thickness * 1);
}
else {
width = cvRound(width + 1);
height = cvRound(height + 1);
}
if (_thickness > 0) {
width = cvRound(width + _thickness * 2);
height = cvRound(height + _thickness * 1);
}
else {
width = cvRound(width + 1);
height = cvRound(height + 1);
}
if (_baseLine) {
*_baseLine = yMax;
}
if (_baseLine) {
*_baseLine = yMax;
}
return Size(width, height);
}
return Size(width, height);
}
void FreeType2Impl::putPixel_8UC1_mono(Mat& _dst, const int _py, const int _px, const uint8_t *_col)
{
@ -1038,6 +1058,7 @@ namespace cv {
#endif
}
int FreeType2Impl::mvFn(const FT_Vector *to, void * user)
{
if (user == NULL) { return 1; }

@ -942,16 +942,6 @@ void DrawOutlineText(cv::Ptr<cv::ft::FreeType2> ft2, cv::Mat& mat, const std::st
lineHeight = std::max(fontSize, textSize.height);
ft2->putText(mat, *it, pt, fontSize, clr, thickness, cv::LINE_AA, false, true);
#ifdef _DEBUG
if (pt.y > (mat.rows / 2))
{
ft2->putText(mat, *it, cv::Point(pt.x, pt.y - fontSize * 3), fontSize, clr, thickness, cv::LINE_AA, false);
}
else
{
ft2->putText(mat, *it, cv::Point(pt.x, pt.y + fontSize * 3), fontSize, clr, thickness, cv::LINE_AA, false);
}
#endif
pt.x = startPoint.x;
pt.y += lineHeight + (lineHeight >> 2); // 125%
@ -1123,8 +1113,8 @@ bool CPhoneDevice::OnImageReady(cv::Mat& mat)
pt.y = height - it->y * ratio - textSize.height;
}
cv::Rect rc(pt.x, pt.y, textSize.width, textSize.height);
cv::rectangle(mat, rc, cv::Scalar(0,255,255), 2);
// cv::Rect rc(pt.x, pt.y, textSize.width, textSize.height);
// cv::rectangle(mat, rc, cv::Scalar(0,255,255), 2);
DrawOutlineText(ft2, mat, it->text, pt, fontSize, scalar, thickness);
}

Loading…
Cancel
Save