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