From 9eb5228f00ff356ac0128abfbb1c85a6abceeca7 Mon Sep 17 00:00:00 2001 From: chenke <chenke@454eff88-639b-444f-9e54-f578c98de674> Date: 星期三, 19 七月 2017 15:39:47 +0800 Subject: [PATCH] 图像缩放模块,中文字体支持模块。 --- RtspFace/PL_Paint.h | 22 ++ RtspFace/CvUtil/CvxText.h | 98 ++++++++++++++ RtspFace/CvUtil/CvxText.cpp | 202 ++++++++++++++++++++++++++++ RtspFace/PL_Paint.cpp | 56 +++++++ 4 files changed, 367 insertions(+), 11 deletions(-) diff --git a/RtspFace/CvUtil/CvxText.cpp b/RtspFace/CvUtil/CvxText.cpp new file mode 100644 index 0000000..4cd52ae --- /dev/null +++ b/RtspFace/CvUtil/CvxText.cpp @@ -0,0 +1,202 @@ +#include <freetype/freetype.h> +#include <assert.h> +#include <locale.h> +#include <ctype.h> + +#include "CvxText.h" + +//==================================================================== +//==================================================================== + +CvxText::CvxText(const char *freeType) +{ + assert(freeType != NULL); + + if (FT_Init_FreeType(&m_library)) throw; + if (FT_New_Face(m_library, freeType, 0, &m_face)) throw; + + restoreFont(); + + setlocale(LC_ALL, ""); + + m_backcolorEnable = true; +} + + +CvxText::~CvxText() +{ + FT_Done_Face(m_face); + FT_Done_FreeType(m_library); +} + + +void CvxText::getFont(int *type, CvScalar *size, bool *underline, float *diaphaneity) +{ + if (type) *type = m_fontType; + if (size) *size = m_fontSize; + if (underline) *underline = m_fontUnderline; + if (diaphaneity) *diaphaneity = m_fontDiaphaneity; +} + +void CvxText::setFont(int *type, CvScalar *size, bool *underline, float *diaphaneity) +{ + if (type) + { + if (type >= 0) m_fontType = *type; + } + if (size) + { + m_fontSize.val[0] = fabs(size->val[0]); + m_fontSize.val[1] = fabs(size->val[1]); + m_fontSize.val[2] = fabs(size->val[2]); + m_fontSize.val[3] = fabs(size->val[3]); + } + if (underline) + { + m_fontUnderline = *underline; + } + if (diaphaneity) + { + m_fontDiaphaneity = *diaphaneity; + } + FT_Set_Pixel_Sizes(m_face, size->val[0] , size->val[0]); +} + +void CvxText::restoreFont() +{ + m_fontType = 0; + + m_fontSize.val[0] = 20; + m_fontSize.val[1] = 0.5; + m_fontSize.val[2] = 0.1; + m_fontSize.val[3] = 0; + + m_fontUnderline = false; + + m_fontDiaphaneity = 1.0; + + m_scale = 1; + + FT_Set_Pixel_Sizes(m_face, (int)m_fontSize.val[0], (int)m_fontSize.val[0]); +} + +int CvxText::putText(IplImage *img, const char *text, CvPoint pos) +{ + return putText(img, text, pos, CV_RGB(255, 255, 255)); +} +int CvxText::putText(IplImage *img, const wchar_t *text, CvPoint pos) +{ + return putText(img, text, pos, CV_RGB(255, 255, 255)); +} + +// + +int CvxText::putText(IplImage *img, const char *text, CvPoint pos, CvScalar color) +{ + if (img == NULL) return -1; + if (text == NULL) return -1; + int i; + for (i = 0; text[i] != '\0'; ++i) + { + wchar_t wc = text[i]; + bool is_sascii = isascii(wc); + if (is_sascii) mbtowc(&wc, &text[i++], 2); + putWChar(img, wc, pos, color); + } + return i; +} +int CvxText::putText(IplImage *img, const wchar_t *text, CvPoint pos, CvScalar color) +{ + if (img == NULL) return -1; + if (text == NULL) return -1; + + // + + int i; + for (i = 0; text[i] != '\0'; ++i) + { + putWChar(img, text[i], pos, color); + } + return i; +} + +void CvxText::drawBackGround(IplImage *img, CvPoint pos, int w, int h) +{ + cvRectangle(img, cvPoint(pos.x, pos.y + 3), cvPoint(pos.x + w, pos.y - h), m_backcolor, -1); +} + + +void CvxText::putWChar(IplImage *img, wchar_t wc, CvPoint &pos, CvScalar color) +{ + FT_UInt glyph_index = FT_Get_Char_Index(m_face, wc); + FT_Load_Glyph(m_face, glyph_index, FT_LOAD_DEFAULT); + FT_Render_Glyph(m_face->glyph, FT_RENDER_MODE_MONO); + + // + + FT_GlyphSlot slot = m_face->glyph; + + double space = m_fontSize.val[0] * m_fontSize.val[1] * m_scale; + double sep = m_fontSize.val[0] * m_fontSize.val[2] * m_scale; + + + int rows = slot->bitmap.rows; + int cols = slot->bitmap.width; + + // + if (m_backcolorEnable) + drawBackGround(img, pos, (int)((cols ? cols : space) + sep), m_fontSize.val[0]); + for (int i = 0; i < rows; ++i) + { + for (int j = 0; j < cols; ++j) + { + int off = ((img->origin == 0) ? i : (rows - 1 - i)) + * slot->bitmap.pitch + j / 8; + + if (slot->bitmap.buffer[off] & (0xC0 >> (j % 8))) + { + int r = (img->origin == 0) ? pos.y - (rows - 1 - i) : pos.y + i; + int c = pos.x + j; + if (r >= 0 && r < img->height + && c >= 0 && c < img->width) + { + CvScalar scalar = cvGet2D(img, r, c); + + float p = m_fontDiaphaneity; + for (int k = 0; k < 4; ++k) + { + scalar.val[k] = scalar.val[k] * (1 - p) + color.val[k] * p; + } + cvSet2D(img, r, c, scalar); + } + } + } // end for + } // end for + pos.x += (int)(cols ? cols : space) + sep; +} + +int CvxText::putText(cv::Mat img, const wchar_t *text, CvPoint pos, CvScalar color) { + IplImage iplImage(img); + return putText(&iplImage, text,pos,color); +} + +int CvxText::putText(cv::Mat img, const char *text, CvPoint pos, CvScalar color) { + IplImage iplImage(img); + return putText(&iplImage, text,pos,color); +} + +int CvxText::putText(cv::Mat img, const char *text, CvPoint pos) { + return putText(img, text, pos, CV_RGB(255,255,255)); +} + +int CvxText::putText(cv::Mat img, const wchar_t *text, CvPoint pos) { + return putText(img, text, pos, CV_RGB(255,255,255)); +} +// +//void CvxText::setScale(float scale) { +// m_scale = scale; +//} +// +//void CvxText::getScale(float* scale) { +// *scale = m_scale; +//} diff --git a/RtspFace/CvUtil/CvxText.h b/RtspFace/CvUtil/CvxText.h new file mode 100644 index 0000000..cfe50c4 --- /dev/null +++ b/RtspFace/CvUtil/CvxText.h @@ -0,0 +1,98 @@ + +#ifndef OPENCV_CVX_TEXT_2007_08_31_H +#define OPENCV_CVX_TEXT_2007_08_31_H + +#include <freetype/freetype.h> +#include <opencv/cv.h> +#include <opencv/highgui.h> + +class CvxText +{ + + CvxText& operator=(const CvxText&); + + //================================================================ + //================================================================ + +public: + + + CvxText(const char *freeType); + virtual ~CvxText(); + + //================================================================ + //================================================================ + + + void getFont(int *type, + CvScalar *size = NULL, bool *underline = NULL, float *diaphaneity = NULL); + +// void setScale(float scale); +// +// void getScale(float* scale); + + void setBackColor(CvScalar color) + { + m_backcolor = color; + } + + void getBackColor(CvScalar* color) + { + *color = m_backcolor; + } + + void setBackColorEnable(bool enable) + { + m_backcolorEnable = enable; + } + + void getBackColorEnable(bool* enable) + { + *enable = m_backcolorEnable; + } + + void setFont(int *type, + CvScalar *size = NULL, bool *underline = NULL, float *diaphaneity = NULL); + + void restoreFont(); + + //================================================================ + //================================================================ + + + int putText(IplImage *img, const char *text, CvPoint pos); + + int putText(cv::Mat img, const char *text, CvPoint pos); + + int putText(IplImage *img, const wchar_t *text, CvPoint pos); + + int putText(cv::Mat img, const wchar_t *text, CvPoint pos); + + int putText(IplImage *img, const char *text, CvPoint pos, CvScalar color); + + int putText(cv::Mat img, const char *text, CvPoint pos, CvScalar color); + + int putText(IplImage *img, const wchar_t *text, CvPoint pos, CvScalar color); + + int putText(cv::Mat img, const wchar_t *text, CvPoint pos, CvScalar color); + +private: + + void putWChar(IplImage *img, wchar_t wc, CvPoint &pos, CvScalar color); + void drawBackGround(IplImage *img, CvPoint pos, int w, int h); + +private: + + FT_Library m_library; + FT_Face m_face; + CvScalar m_backcolor; + + int m_fontType; + CvScalar m_fontSize; + bool m_fontUnderline; + float m_fontDiaphaneity; + bool m_backcolorEnable; + float m_scale; +}; + +#endif // OPENCV_CVX_TEXT_2007_08_31_H \ No newline at end of file diff --git a/RtspFace/PL_Paint.cpp b/RtspFace/PL_Paint.cpp index fdf3170..daaca0d 100644 --- a/RtspFace/PL_Paint.cpp +++ b/RtspFace/PL_Paint.cpp @@ -2,7 +2,7 @@ #include "MaterialBuffer.h" #include "logger.h" #include "MediaHelper.h" - +#include "CvUtil/CvxText.h" #include <string.h> // for memcpy #include <opencv2/core/mat.hpp> #include <opencv2/imgproc.hpp> @@ -16,7 +16,7 @@ PipeMaterial pmList[2]; MB_Frame lastMbfBuffOrigin; MB_Frame lastMbfBuffCopy; - + bool payError; PL_Paint_Internal() : @@ -43,12 +43,13 @@ PipeMaterial _pm; pmList[0] = _pm; pmList[1] = _pm; - + MB_Frame _lastMbfBuff; lastMbfBuffOrigin = _lastMbfBuff; lastMbfBuffCopy = _lastMbfBuff; - + payError = true; + } }; @@ -78,6 +79,20 @@ in->config = *config; } + if(in->config.fontPath.empty()) + { + LOG_ERROR << "fontPath is null!" << LOG_ENDL; + return false; + } + if(in->config.plplCtx->cvxText != nullptr) + { + delete(in->config.plplCtx->cvxText); + } + CvxText* cvxText =new CvxText(in->config.fontPath.c_str()); + in->config.plplCtx->cvxText = cvxText; + cvxText->setBackColor(cvScalar(128, 33, 14)); + CvScalar font = cvScalar(40,1,0.2,1); + cvxText->setFont(0, &font); return true; } @@ -160,10 +175,31 @@ const uint16_t Y = plplCtx->color_front.toY(); const uint16_t UV = plplCtx->color_front.toUV(); - cv::putText(yMat, TXT, cv::Point(LTX, LTY), CV_FONT_HERSHEY_COMPLEX, 2, CV_RGB(Y, Y, Y)); - cv::putText(uvMat, TXT, cv::Point(MH_SUBSAMPLE1(LTX, 2), MH_SUBSAMPLE1(LTY, 2)), CV_FONT_HERSHEY_COMPLEX, 1, CV_RGB(UV, UV, UV)); + cv::putText(yMat, TXT, cv::Point(LTX, LTY), CV_FONT_HERSHEY_COMPLEX, 1, CV_RGB(Y, Y, Y)); + cv::putText(uvMat, TXT, cv::Point(MH_SUBSAMPLE1(LTX, 2), MH_SUBSAMPLE1(LTY, 2)), CV_FONT_HERSHEY_COMPLEX, 0.5, CV_RGB(UV, UV, UV)); } +bool plplDraw_WText_NV12(PLPLContext* plplCtx, MB_Frame* paintMb, int& paramOffset) +{ + int LTX = plplCtx->params[paramOffset + 0].val_i; + int LTY = plplCtx->params[paramOffset + 1].val_i; + const char* TXT = plplCtx->params[paramOffset + 2].val_s; + paramOffset += 3; + int src_width = paintMb->width; + int src_height = paintMb->height; + uint8_t* src_y = (uint8_t*)(paintMb->buffer); + uint8_t* src_uv = (uint8_t*)(src_y + (src_height * src_width)); + cv::Mat yMat(cv::Size(src_width, src_height), CV_8UC1, src_y); + cv::Mat uvMat(cv::Size(MH_SUBSAMPLE1(src_width, 2), MH_SUBSAMPLE1(src_height, 2)), CV_16UC1, src_uv); + + // void rectangle(Mat& img, Point pt1, Point pt2, const Scalar& color, int thickness=1, int lineType=8, int shift=0) + + const uint16_t Y = plplCtx->color_front.toY(); + const uint16_t UV = plplCtx->color_front.toUV(); + CvxText* cvText = (CvxText*)plplCtx->cvxText; + cvText->putText(yMat, L"涓枃ABCDabcd", cv::Point(LTX, LTY), CV_RGB(Y, Y, Y)); + cvText->putText(uvMat, L"涓枃ABCDabcd", cv::Point(MH_SUBSAMPLE1(LTX, 2),MH_SUBSAMPLE1(LTY, 2)), CV_RGB(UV, UV, UV)); +} bool plplExecutor_YUV(PL_Paint_Internal *in) { MB_Frame* paintMb = &(in->lastMbfBuffOrigin); @@ -250,6 +286,14 @@ else ret = false; break; + + case PLPLC_WTEXT: + //TEXT LTX,LTY,"STR" + if (paintMb->type == MB_Frame::MBFT_NV12) + ret = plplDraw_WText_NV12(plplCtx, paintMb, paramOffset); + else + ret = false; + break; } } diff --git a/RtspFace/PL_Paint.h b/RtspFace/PL_Paint.h index 9e7edab..9b1a0e1 100644 --- a/RtspFace/PL_Paint.h +++ b/RtspFace/PL_Paint.h @@ -22,7 +22,7 @@ PLPLC_PEN, PLPLC_RECT, PLPLC_TEXT, - + PLPLC_WTEXT, PLPLC__LAST }; @@ -30,12 +30,17 @@ { int val_i; float val_f; - char val_s[sizeof(int)]; + char val_s[10]; PLPLType() : val_i(0) {} PLPLType(int _val_i) : val_i(_val_i) {} PLPLType(float _val_f) : val_f(_val_f) {} PLPLType(const char* _val_s) + { + for (int i = 0; i < sizeof(val_s); i++) + val_s[i] = _val_s[i]; + } + PLPLType(const wchar_t* _val_s) { for (int i = 0; i < sizeof(val_s); i++) val_s[i] = _val_s[i]; @@ -54,19 +59,26 @@ PLGH_Color_RGBA color_back; int fill; PLGH_Pen pen; - + void* cvxText; PLPLContext() : - cmds(), params(), color_front(), color_back(), fill(0), pen(0, 0) + cmds(), params(), color_front(), color_back(), fill(0), pen(0, 0), cvxText(nullptr) {} + + ~PLPLContext() + { + delete(cvxText); + cvxText = nullptr; + } }; struct PL_Paint_Config { bool copyData; PLPLContext* plplCtx; + std::string fontPath; PL_Paint_Config() : - copyData(false), plplCtx(nullptr) + copyData(false), plplCtx(nullptr), fontPath() { } }; -- Gitblit v1.8.0