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