使用cv::putText写中文字符时输出结果为"??????"。。。。。。这怎么能忍?

python方法中可以将opencv图片转化为PIL,写中文之后再转回opencv格式。

C++方法中通常利用freetype库来实现,freetype打包的win32静态库可以在C#通过dll引用进行调用,这需要其版本跟CvxText对应,否则会出现错误,其在x64平台也一样。

本文采用windows的GDI显示系统的TrueType字体,没有封装,就两个函数,分成h和cpp文件,可以自己编辑文件名和函数名,也可以直接将cpp的代码复制到你需要的程序中。


【putText.h】

#ifndef PUTTEXT_H_
#define PUTTEXT_H_#include <windows.h>
#include <string>
#include <opencv2/opencv.hpp>using namespace cv;void GetStringSize(HDC hDC, const char* str, int* w, int* h);
void putTextHusky(Mat &dst, const char* str, Point org, Scalar color, int fontSize,const char *fn = "Arial", bool italic = false, bool underline = false);#endif // PUTTEXT_H_

【putText.cpp】

#include "putText.h"void GetStringSize(HDC hDC, const char* str, int* w, int* h)
{SIZE size;GetTextExtentPoint32A(hDC, str, strlen(str), &size);if (w != 0) *w = size.cx;if (h != 0) *h = size.cy;
}void putTextHusky(Mat &dst, const char* str, Point org, Scalar color, int fontSize, const char* fn, bool italic, bool underline)//后俩参数:斜体,下划线
{CV_Assert(dst.data != 0 && (dst.channels() == 1 || dst.channels() == 3));int x, y, r, b;if (org.x > dst.cols || org.y > dst.rows) return;x = org.x < 0 ? -org.x : 0;y = org.y < 0 ? -org.y : 0;LOGFONTA lf;lf.lfHeight = -fontSize;lf.lfWidth = 0;lf.lfEscapement = 0;lf.lfOrientation = 0;lf.lfWeight = 5;lf.lfItalic = italic;   //斜体lf.lfUnderline = underline; //下划线lf.lfStrikeOut = 0;lf.lfCharSet = DEFAULT_CHARSET;lf.lfOutPrecision = 0;lf.lfClipPrecision = 0;lf.lfQuality = PROOF_QUALITY;lf.lfPitchAndFamily = 0;strcpy_s(lf.lfFaceName, fn);HFONT hf = CreateFontIndirectA(&lf);HDC hDC = CreateCompatibleDC(0);HFONT hOldFont = (HFONT)SelectObject(hDC, hf);int strBaseW = 0, strBaseH = 0;int singleRow = 0;char buf[1 << 12];strcpy_s(buf, str);char *bufT[1 << 12];  // 这个用于分隔字符串后剩余的字符,可能会超出。//处理多行{int nnh = 0;int cw, ch;const char* ln = strtok_s(buf, "\n", bufT);while (ln != 0){GetStringSize(hDC, ln, &cw, &ch);strBaseW = max(strBaseW, cw);strBaseH = max(strBaseH, ch);ln = strtok_s(0, "\n", bufT);nnh++;}singleRow = strBaseH;strBaseH *= nnh;}if (org.x + strBaseW < 0 || org.y + strBaseH < 0){SelectObject(hDC, hOldFont);DeleteObject(hf);DeleteObject(hDC);return;}r = org.x + strBaseW > dst.cols ? dst.cols - org.x - 1 : strBaseW - 1;b = org.y + strBaseH > dst.rows ? dst.rows - org.y - 1 : strBaseH - 1;org.x = org.x < 0 ? 0 : org.x;org.y = org.y < 0 ? 0 : org.y;BITMAPINFO bmp = { 0 };BITMAPINFOHEADER& bih = bmp.bmiHeader;int strDrawLineStep = strBaseW * 3 % 4 == 0 ? strBaseW * 3 : (strBaseW * 3 + 4 - ((strBaseW * 3) % 4));bih.biSize = sizeof(BITMAPINFOHEADER);bih.biWidth = strBaseW;bih.biHeight = strBaseH;bih.biPlanes = 1;bih.biBitCount = 24;bih.biCompression = BI_RGB;bih.biSizeImage = strBaseH * strDrawLineStep;bih.biClrUsed = 0;bih.biClrImportant = 0;void* pDibData = 0;HBITMAP hBmp = CreateDIBSection(hDC, &bmp, DIB_RGB_COLORS, &pDibData, 0, 0);CV_Assert(pDibData != 0);HBITMAP hOldBmp = (HBITMAP)SelectObject(hDC, hBmp);//color.val[2], color.val[1], color.val[0]SetTextColor(hDC, RGB(255, 255, 255));SetBkColor(hDC, 0);//SetStretchBltMode(hDC, COLORONCOLOR);strcpy_s(buf, str);const char* ln = strtok_s(buf, "\n", bufT);int outTextY = 0;while (ln != 0){TextOutA(hDC, 0, outTextY, ln, strlen(ln));outTextY += singleRow;ln = strtok_s(0, "\n", bufT);}uchar* dstData = (uchar*)dst.data;int dstStep = dst.step / sizeof(dstData[0]);unsigned char* pImg = (unsigned char*)dst.data + org.x * dst.channels() + org.y * dstStep;unsigned char* pStr = (unsigned char*)pDibData + x * 3;for (int tty = y; tty <= b; ++tty){unsigned char* subImg = pImg + (tty - y) * dstStep;unsigned char* subStr = pStr + (strBaseH - tty - 1) * strDrawLineStep;for (int ttx = x; ttx <= r; ++ttx){for (int n = 0; n < dst.channels(); ++n) {double vtxt = subStr[n] / 255.0;int cvv = vtxt * color.val[n] + (1 - vtxt) * subImg[n];subImg[n] = cvv > 255 ? 255 : (cvv < 0 ? 0 : cvv);}subStr += 3;subImg += dst.channels();}}SelectObject(hDC, hOldBmp);SelectObject(hDC, hOldFont);DeleteObject(hf);DeleteObject(hBmp);DeleteDC(hDC);
}

第二个函数putTextHusky(),默认使用Arial字体,也可以设置成操作系统中已经安装的字体,如“宋体”、“微软雅黑”、“Times New Roman”等;默认显示非斜体、非下划线。

【示例】

#include <opencv2/opencv.hpp>
#include "putText.h"using namespace std;
using namespace cv;int main()//自己写库解决putText无法显示中文字符问题
{Mat img = imread("lyf.png");putText(img, "中文无法显示...", Point(50, 50), 2, 1, Scalar(0, 0, 255), 1, 8, false);putTextHusky(img, "Arial字体...", Point(50, 100), Scalar(0, 0, 255), 30, "Arial");putTextHusky(img, "微软雅黑字体...", Point(50, 150), Scalar(0, 255, 0), 30, "微软雅黑", true, true);putTextHusky(img, "楷体字体...\n", Point(50, 200), Scalar(128, 255, 0), 30, "楷体", true, true);//imwrite("lyfWrite.png", img);imshow("test", img);waitKey(0);system("pause");return 0;
}

C++ OpenCV【解决putText不能显示中文】相关推荐

  1. CV2 puttext不能显示中文问题

    CV2 puttext不能显示中文问题,还是这个方法管用: 解决方法:将图片格式转化为PIL库的格式,用PIL的方法写入中文,然后在转化为CV的格式 但是采用如下方案会导致性能降低,毕竟多加了一次转化 ...

  2. ITEXT5.5.8转html为pdf文档解决linux不显示中文问题

    ITEXT5.5.8转html为pdf文档解决linux不显示中文问题 参考文章: (1)ITEXT5.5.8转html为pdf文档解决linux不显示中文问题 (2)https://www.cnbl ...

  3. 解决ubuntu无法显示中文拼音

    解决ubuntu无法显示中文拼音 出现的原因 解决 出现的原因 ubuntu18.04是新装的,嫌弃自带的输入法不好用,由于对迅飞输入法情有独钟,便去尝试安装linux版本的,不知道是那里的步骤安装出 ...

  4. Macbook解决TeXstudio不显示中文问题

    最近有作业需要被要求用LaTeX写作业,就下载了LaTex+TeXstudio 下载攻略:https://zhuanlan.zhihu.com/p/113193793 安装后了,运行后发现各种问题,一 ...

  5. eclipse中文乱码解决_解决git status显示中文文件名乱码问题

    使用 git status 查看本地有改动但未提交的中文文件名时,发现会显示为一串数字,没有显示中文的文件名.具体如下所示: $ git status# 位于分支 master# 尚未暂存以备提交的变 ...

  6. 怎么解决mysql中文显示_怎样解决关于MySQL显示中文的问题?

    第一种方法,很精辟的总结: 经常更换虚拟主机,而各个服务商的MYSQL版本不同,当导入数据后,总会出现乱码等无法正常显示的问题,查了好多资料,总结出自己的一点技巧: WINDOWS 下导入应该这样 使 ...

  7. 解决Linux命令行界面显示中文乱码的问题

    问题描述:查看服务器时间,结果显示乱码. 解决方法: 输入修改命令 vim ~/.bash_profile 填入以下语句 输入下面命令更新一下 source ~/.bash_profile 更改成功 ...

  8. 解决Sublime Text3 显示中文乱码问题

    1,安装包管理器 使用Ctrl+c快捷键或者通过View->Show Console菜单打开命令行,粘贴如下代码 import urllib.request,os; pf = 'Package ...

  9. linux java乱码怎么解决,linux中显示中文乱码如何解决

    #第一步-排查 #第1个里程碑-看看linux系统的字符集 echo $LANG #第2个里程碑-远程连接工具 xshell/SecureCRT/putty 字符集 #第二步-修改 修复 修改字符集 ...

最新文章

  1. html 整个页面变灰
  2. RPC调用框架比较分析--转载
  3. STM32开发 -- CRC校验码
  4. Generator函数自执行
  5. Spring Boot系列教程一:Eclipse安装spring-tool-suite插件
  6. Wait Event SQL*Net more data to client
  7. [vue] 你了解axios的原理吗?有看过它的源码吗?
  8. break continue区别和用法_因为不知道break和contiue的核心区别,他在初试就被刷了下来...
  9. 学习EXT第八天:EXT的布局(Layout)Part 1
  10. Navicat Premium 12破解方法
  11. u盘芯片 测试软件,U盘芯片检测工具(Chip Genius)
  12. python爬取阳光问政
  13. 三星BESPOKE家电系列海外发布会看点一览,定制化设计成未来家居首选
  14. 开灯问题~有n盏灯,编号为1~n。1号将灯全部打开,2将按下所有为2的倍数的开关,(这些灯将被关掉)第3个人按下所有编号为3的倍数的开关(该灯如为打开的, 则将它关闭;如关闭的,则将它打开)。
  15. 黑盒测试技术之等价类划分法
  16. 分析1300万起案件:洛杉矶警局如何用大数据预测犯罪?
  17. 跨交换机VLAN的配置实验
  18. mysql root password_MYSQL安装时解决要输入current root password的方案
  19. java心得hello_java学习的第一阶段总结
  20. 国产操作系统(2)中标麒麟和银河麒麟体验QT

热门文章

  1. 父亲节用计算机给惊喜,送给父亲的的惊喜句子
  2. react native scrollView FlatList 多级联动
  3. 去除chrome网站https的安全检测
  4. python自动化运维快速入门pdf下载_我爱电子书-《Python自动化运维快速入门》| pdf + epub + mobi + awz3, 高清版, 带目录,Kindle版, 多看精排版下载...
  5. 查看远程端口开放状态
  6. except:异常的使用
  7. 微信小程序订阅模板消息
  8. Data Structures and Algorithms7-25——Harry Potter's Exam
  9. 断网小游戏“滑板冲浪”
  10. Cannot find existing PyQt5 plugin directories |找不到PyQt5路径