OPenCV版本:4.4

IDE:VS2019

功能描述

OpenCV绘制文本的函数putText()不支持中文的显示,网上很多方法推荐的都是使用FreeType来支持,FreeType是什么呢?FreeType的官网上有介绍

FreeType官网

https://www.freetype.org/index.html

网站上都是英文的介绍,闲着没事,翻译了一下其介绍,水平有限,凑活着看,如下:

FreeType是一款免费的用来渲染字体的软件库。

他是用c语言编写的,体量小,效率高,可高度定制,同时能够产生大多数矢量和位图字体格式的高质量输出(字形图像)。

选择一个版本进行下载,其下载地址如下:

https://sourceforge.net/projects/freetype/files/freetype2/2.10.1/freetype-2.10.1.tar.xz/download

解压后如下图所示:

配置FreeType

​ FreeType文件夹里自带了vs的工程,在freetype-2.10.4\builds\windows\vc2010\目录下,直接用vs2019打开freetype.sln,就可以编译,选择x64编译,编译成功后在freetype-2.10.4\objs\x64\Debug文件夹下面,生成freetype.dll和freetype.lib,如下图:

新建一个工程,工程中配置相关的库路径和包含路径,如下图所示添加库的过程。

​ 点击下拉列表,如下图所示:

点击编辑,打开添加库的窗口,如下图:

把freetype.lib添加进去,点击确定后完成。

然后添加库的路径,步骤如下图:

单击下拉列表,如下图:

添加上库的路径,单击确定,完成。

添加包含头文件的目录。如下图:

单击下拉列表,打开添加包含路径的窗口,如下图:

添加路径后,单击确定,成功。

添加FreeType的封装类文件

CvxText.h

#ifndef OPENCV_CVX_TEXT_HPP_
#define OPENCV_CVX_TEXT_HPP_// 支持OpenCV中文汉字输入#include <ft2build.h>
#include FT_FREETYPE_H#include <opencv2/opencv.hpp>class CvxText {public:/*** 装载字库文件*/CvxText(const char* freeType);virtual ~CvxText();/*** 获取字体.目前有些参数尚不支持.** \param font        字体类型, 目前不支持* \param size        字体大小/空白比例/间隔比例/旋转角度* \param underline   下画线* \param diaphaneity 透明度** \sa setFont, restoreFont*/void getFont(int* type, cv::Scalar* size = nullptr, bool* underline = nullptr, float* diaphaneity = nullptr);/*** 设置字体.目前有些参数尚不支持.** \param font        字体类型, 目前不支持* \param size        字体大小/空白比例/间隔比例/旋转角度* \param underline   下画线* \param diaphaneity 透明度** \sa getFont, restoreFont*/void setFont(int* type, cv::Scalar* size = nullptr, bool* underline = nullptr, float* diaphaneity = nullptr);/*** 恢复原始的字体设置.** \sa getFont, setFont*/void restoreFont();/*** 输出汉字(颜色默认为黑色).遇到不能输出的字符将停止.** \param img  输出的影象* \param text 文本内容* \param pos  文本位置** \return 返回成功输出的字符长度,失败返回-1.*/int putText(cv::Mat& img, const char* text, cv::Point pos);/*** 输出汉字(颜色默认为黑色).遇到不能输出的字符将停止.** \param img  输出的影象* \param text 文本内容* \param pos  文本位置** \return 返回成功输出的字符长度,失败返回-1.*/int putText(cv::Mat& img, const wchar_t* text, cv::Point pos);/*** 输出汉字.遇到不能输出的字符将停止.** \param img   输出的影象* \param text  文本内容* \param pos   文本位置* \param color 文本颜色** \return 返回成功输出的字符长度,失败返回-1.*/int putText(cv::Mat& img, const char* text, cv::Point pos, cv::Scalar color);/*** 输出汉字.遇到不能输出的字符将停止.** \param img   输出的影象* \param text  文本内容* \param pos   文本位置* \param color 文本颜色** \return 返回成功输出的字符长度,失败返回-1.*/int putText(cv::Mat& img, const wchar_t* text, cv::Point pos, cv::Scalar color);private:// 禁止copyCvxText& operator=(const CvxText&);// 输出当前字符, 更新m_pos位置void putWChar(cv::Mat& img, wchar_t wc, cv::Point& pos, cv::Scalar color);FT_Library   m_library;   // 字库FT_Face      m_face;      // 字体// 默认的字体输出参数int         m_fontType;cv::Scalar   m_fontSize;bool      m_fontUnderline;float      m_fontDiaphaneity;
};#endif // OPENCV_CVX_TEXT_HPP_

CvxText.cpp

#include <wchar.h>
#include <assert.h>
#include <locale.h>
#include <ctype.h>
#include <cmath>
#include "CvxText.h"// 打开字库
CvxText::CvxText(const char* freeType)
{//INFO("font lib path:%s", freeType);assert(freeType != NULL);// 打开字库文件, 创建一个字体FT_Error error;error = FT_Init_FreeType(&m_library);if (error){//INFOE("an error occurred during library initialization");//fprintf(stderr, "an error occurred during library initialization\n");}//if(FT_Init_FreeType(&m_library)) throw;if (FT_New_Face(m_library, freeType, 0, &m_face)) throw;// 设置字体输出参数restoreFont();// 设置C语言的字符集环境setlocale(LC_ALL, "");
}// 释放FreeType资源
CvxText::~CvxText()
{FT_Done_Face(m_face);FT_Done_FreeType(m_library);
}// 设置字体参数:
//
// font         - 字体类型, 目前不支持
// size         - 字体大小/空白比例/间隔比例/旋转角度
// underline   - 下画线
// diaphaneity   - 透明度
void CvxText::getFont(int* type, cv::Scalar* 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, cv::Scalar* size, bool* underline, float* diaphaneity)
{// 参数合法性检查if (type) {if (type >= 0) m_fontType = *type;}if (size) {m_fontSize.val[0] = std::fabs(size->val[0]);m_fontSize.val[1] = std::fabs(size->val[1]);m_fontSize.val[2] = std::fabs(size->val[2]);m_fontSize.val[3] = std::fabs(size->val[3]);}if (underline) {m_fontUnderline = *underline;}if (diaphaneity) {m_fontDiaphaneity = *diaphaneity;}FT_Set_Pixel_Sizes(m_face, (int)m_fontSize.val[0], 0);
}// 恢复原始的字体设置
void CvxText::restoreFont()
{m_fontType = 0;            // 字体类型(不支持)m_fontSize.val[0] = 80;      // 字体大小m_fontSize.val[1] = 0.5;   // 空白字符大小比例m_fontSize.val[2] = 0.1;   // 间隔大小比例m_fontSize.val[3] = 0;      // 旋转角度(不支持)m_fontUnderline = false;   // 下画线(不支持)m_fontDiaphaneity = 1.0;   // 色彩比例(可产生透明效果)// 设置字符大小FT_Set_Pixel_Sizes(m_face, (int)m_fontSize.val[0], 0);
}// 输出函数(颜色默认为白色)
int CvxText::putText(cv::Mat& img, const char* text, cv::Point pos)
{return putText(img, text, pos, CV_RGB(255, 255, 255));
}int CvxText::putText(cv::Mat& img, const wchar_t* text, cv::Point pos)
{return putText(img, text, pos, CV_RGB(255, 255, 255));
}int CvxText::putText(cv::Mat& img, const char* text, cv::Point pos, cv::Scalar color)
{if (img.data == nullptr) return -1;if (text == nullptr) return -1;int i;for (i = 0; text[i] != '\0'; ++i) {wchar_t wc = text[i];// 解析双字节符号if (!isascii(wc)) mbtowc(&wc, &text[i++], 2);// 输出当前的字符putWChar(img, wc, pos, color);}return i;
}int CvxText::putText(cv::Mat& img, const wchar_t* text, cv::Point pos, cv::Scalar color)
{if (img.data == nullptr) return -1;if (text == nullptr) return -1;int i;for (i = 0; text[i] != '\0'; ++i) {// 输出当前的字符putWChar(img, text[i], pos, color);}return i;
}// 输出当前字符, 更新m_pos位置
void CvxText::putWChar(cv::Mat& img, wchar_t wc, cv::Point& pos, cv::Scalar color)
{// 根据unicode生成字体的二值位图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;// 行列数int rows = slot->bitmap.rows;int cols = slot->bitmap.width;for (int i = 0; i < rows; ++i) {for (int j = 0; j < cols; ++j) {int off = i * slot->bitmap.pitch + j / 8;if (slot->bitmap.buffer[off] & (0xC0 >> (j % 8))) {int r = pos.y - (rows - 1 - i);int c = pos.x + j;if (r >= 0 && r < img.rows && c >= 0 && c < img.cols) {cv::Vec3b pixel = img.at<cv::Vec3b>(cv::Point(c, r));cv::Scalar scalar = cv::Scalar(pixel.val[0], pixel.val[1], pixel.val[2]);// 进行色彩融合float p = m_fontDiaphaneity;for (int k = 0; k < 4; ++k) {scalar.val[k] = scalar.val[k] * (1 - p) + color.val[k] * p;}img.at<cv::Vec3b>(cv::Point(c, r))[0] = (unsigned char)(scalar.val[0]);img.at<cv::Vec3b>(cv::Point(c, r))[1] = (unsigned char)(scalar.val[1]);img.at<cv::Vec3b>(cv::Point(c, r))[2] = (unsigned char)(scalar.val[2]);}}}}// 修改下一个字的输出位置double space = m_fontSize.val[0] * m_fontSize.val[1];double sep = m_fontSize.val[0] * m_fontSize.val[2];pos.x += (int)((cols ? cols : space) + sep);
}

源码

#include <iostream>
#include <opencv2/opencv.hpp>
#include "CvxText.h"int main()
{cv::Mat image = cv::imread("D:\\OpenCVtest\\images\\juice.png");std::string text = "我是果汁";int font_face = cv::FONT_HERSHEY_COMPLEX;double font_scale = 3;int thickness = 8;int baseline;//获取文本框的长宽cv::Size text_size = cv::getTextSize(text, font_face, font_scale, thickness, &baseline);//将文本框居中绘制cv::Point origin;origin.x = image.cols / 2 - text_size.width / 2;origin.y = image.rows / 2 + text_size.height / 2;CvxText chinese("D:\\OpenCVtest\\PutTextChinese\\SimHei.ttf");chinese.putText(image, text.c_str(), origin, cv::Scalar(255, 0, 0));imshow("文本绘制", image);cv::waitKey(0);return 0;
}

运行结果

OpenCV文字绘制支持中文显示相关推荐

  1. 让英文版的LINUX 支持中文显示

    (以REDHAT为例) 1.首先查看系统中有没有安装中文支持软件包   rpm -qa |grep fonts-chinese 如果命令执行后能够查询到相应的包,那么说明已经安装过包:反之则没有安装 ...

  2. [django]Django站点admin支持中文显示和输入设置

    正文: Django站点admin支持中文输入设置,操作如下: 1 需要确定的你的数据库的client客户端和服务端的编码设置为utf-8,如果不是,请将其设置成utf-8编码,我采用mysql,详情 ...

  3. 让黑莓模拟器支持中文显示

    黑莓模拟器不支持中文显示和输入,调试中文程序的时候出现方块,解决方法如下: [首先找到模拟器安装目录] 情况一:如果使用的是bb jde for eclipse plugins的话,找到eclipse ...

  4. 一百零二、Hive——hive设置元数据支持中文显示

    在hive中建外部表时遇见到这样一个问题,就是表字段的中文注释在desc 表结构时看不了,发现原来是Hive的元数据库没有设置支持中文显示 第一步,在元数据库metastore完成初始化后,再次登录M ...

  5. svn自动邮件提醒(win7下支持中文显示,使用commit-emial.pl)

    1 前提:已安装svn,假设已有版本库名称为 :share 2 安装perl并重新启动.     下载并安装  ActivePerl-5.14.2.1402-MSWin32-x86-295342.ms ...

  6. QT嵌入式QT支持中文显示(zynq)

    @QT嵌入式QT支持中文显示 开发板可以使用文泉驿字体.在如下链接下载wqy-zenhei-0.8.38-1.tar.gz https://sourceforge.net/projects/wqy/f ...

  7. Xna支持中文显示方法归纳

    Xna不同于DirectX,因其内部并未提供类似于D3DFont的机制(据说之所以会这样做,也是考虑到与Xbox360兼容的缘故),使得显示中文变得极为不便. 虽然如此,要实现Xna下的中文显示依然存 ...

  8. [转] OpenCV 文字绘制cv::putText详解

    ref:[OpenCV3]文字绘制--cv::putText详解_cv.puttext_PHILOS_THU的博客-CSDN博客 opencv学习(十三)之文本文字插入_opencv视频添加文本并保存 ...

  9. linux系统可以显示中文输入法,2 Linux支持中文显示和中文拼音输入法(番外篇)...

    今天打开虚拟机 linux  本来要整理笔记 发现Linux不支持中文.修改了/etc/sysconfig/i18n也不好使. 后来我猜想是没有装中文语言包,上网一查果然是这样. 装语言包: 1找到r ...

最新文章

  1. 关闭eslint检查2020_2020 vscode配置eslint保存后自动fix
  2. 在子线程中弹土司的一段代码
  3. python3下载文件-python 3.3 下载固定链接文件并保存的方法
  4. docker (centOS 7) 使用笔记4 - etcd服务
  5. SQL Server 存储过程的应用
  6. python二维数组去重复_php二维数组去重,array_unique出除重复数据
  7. Processor Tracing | 处理器追踪
  8. 遇见格灵深瞳那一刻,我一见倾心
  9. cmd判断redis是否启动成功_软启动是否故障如何判断及不同故障检测维修办法
  10. Could not create ServerSocket on address 0.0.0.0/0.0.0.0:9083
  11. 基于vue3 实现页面自动配色、颜色选择器组件
  12. LINUX操作命令汇总(zt)
  13. 手把手教你开一间咖啡馆
  14. 计算机家庭组改工作组,win7系统如何更改工作组
  15. <数据结构>停车场管理系统,利用栈和队列实现,包含纯c语言版和C++版的全注释源码
  16. Spring Security内部工作原理
  17. WQ7033开发指南(基础篇)之1.1 初识SDK
  18. 机器学习——逻辑回归
  19. Block背后的数据结构及变量截取
  20. 关于eth-trunk链路聚合的建立

热门文章

  1. boost::log::keywords::format用法的测试程序
  2. ITK:使用Deformation Field扭曲图像
  3. ITK:将图像翻转到指定的轴上
  4. VTK:Filtering之GaussianSplat
  5. OpenCV基本mat重建的实例(附完整代码)
  6. OpenCV放大图像:多输出
  7. Qt Creator预览版
  8. OpenGL multiple lights多光源的实例
  9. C语言以递归实现归并排序Merge Sort算法(附完整源码)
  10. C语言实现自组织映射kohone/trace算法(附完整源码)