最近有时候需要在图中输出中文,最先想到的是转换成GB2313的方法进行输出,但是不行,无奈只能想别的方法去实现。
先看看如果将utf-8转换成GB2313

std::string UTF8ToGBK(const std::string& strUTF8)
{int len = MultiByteToWideChar(CP_UTF8, 0, strUTF8.c_str(), -1, NULL, 0);WCHAR* wszGBK = new WCHAR[len + 1];memset(wszGBK, 0, len * 2 + 2);MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)(LPCTSTR)strUTF8.c_str(), -1, wszGBK, len);len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL);char *szGBK = new char[len + 1];memset(szGBK, 0, len + 1);WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL);std::string strTemp(szGBK);delete[]szGBK;delete[]wszGBK;return strTemp;
}

使用这个输出图片上中文还是乱码。

接下来看一种方法,使用Qt输出图片上的中文
方法一:借助

void PutTextChinese(cv::Mat &inMat, QString drawText, cv::Point wordCenter, int inWordSize, cv::Scalar inColor)
{QImage image;switch (inMat.type()){case CV_8UC1:image = QImage(inMat.data, inMat.cols, inMat.rows, inMat.cols, QImage::Format_Mono);break;case CV_8UC3:image = QImage(inMat.data, inMat.cols, inMat.rows, inMat.cols * 3, QImage::Format_RGB888);break;case CV_8UC4:image = QImage(inMat.data, inMat.cols, inMat.rows, inMat.cols * 4, QImage::Format_ARGB32);break;}QColor drawColor(inColor[0], inColor[1], inColor[2]);QPainter pp(&image);QPen pen = QPen(drawColor, inWordSize);QBrush brush = QBrush(drawColor);pp.setPen(pen);pp.setBrush(brush);QFont font("KaiTi", inWordSize);pp.setFont(font);pp.drawText(QPointF(wordCenter.x, wordCenter.y), drawText);
}

上述的方法如果是用Qt开发的话,还是非常好用的,直接把Mat按引用传入然后传出,就可以实现了。

方法二:

#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_#pragma once
#include "putTexts.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);
}
#include <opencv2/opencv.hpp>
#include "putTexts.h"using namespace std;
using namespace cv;int main()//自己写库解决putText无法显示中文字符问题
{Mat img = cv::imread("D:/Persional/jiazhigang/images/aifeier.jpg");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);imshow("test", img);waitKey(0);return 0;
}

效果如下图所示

putText输出中文方法相关推荐

  1. opencvShrap的PutText函数输出中文

    opencvShrap的PutText函数输出中文 PutText函数不支持中文的输出,所以需要将Mat类型转换成Image类型,然后调用Graphics的DrawString方法来写中文内容,然后再 ...

  2. Python - Sublime Text 3 控制台不能输出中文的解决方法

    Python - Sublime Text 3 控制台不能输出中文的解决方法 参考文章: (1)Python - Sublime Text 3 控制台不能输出中文的解决方法 (2)https://ww ...

  3. PHP输出中文乱码的解决方法

    PHP输出中文乱码的解决方法 参考文章: (1)PHP输出中文乱码的解决方法 (2)https://www.cnblogs.com/cyun/p/4146131.html 备忘一下.

  4. python中怎么输出中文-python中使用print输出中文的方法

    看Python简明教程,学习使用print打印字符串,试了下打印中文,不行. 编辑环境:IDLE 上网搜了下解决办法,各种说法,试了两种: print u"学习" print (u ...

  5. 成功解决cv2.imwrite(filename, img)代码输出中文文件乱码的问题(cv2.imencode方法解决)

    成功解决cv2.imwrite(filename, img)代码输出中文文件乱码的问题(cv2.imencode方法解决) 目录 解决问题 解决思路 1.从网络读取图像数据并转换成图片格式 2.将图片 ...

  6. pythonprint中文教程_python中使用print输出中文的方法

    看Python简明教程,学习使用print打印字符串,试了下打印中文,不行. 编辑环境:IDLE 上网搜了下解决办法,各种说法,试了两种: print u"学习" print (u ...

  7. VScode输出中文乱码的解决方法------测试过可以用

    VScode输出中文乱码的解决方法------测试过可以用 参考文章: (1)VScode输出中文乱码的解决方法------测试过可以用 (2)https://www.cnblogs.com/shou ...

  8. code blocks无法输出中文解决方法

    code blocks无法输出中文解决方法 参考文章: (1)code blocks无法输出中文解决方法 (2)https://www.cnblogs.com/dgwblog/p/8877507.ht ...

  9. python中print是什么意思中文-python中使用print输出中文的方法

    看Python简明教程,学习使用print打印字符串,试了下打印中文,不行. 编辑环境:IDLE 上网搜了下解决办法,各种说法,试了两种: print u"学习" print (u ...

最新文章

  1. iMeta期刊顾问James M Tiedje当选中国科学院外籍院士
  2. 基因课 15天入门生物信息(2021年) 第三天 Linux基础命令(1)
  3. 驰骋工作流携手山东金义,实施落地上海光大银行
  4. 号称用GPT-3开发的游戏,却活生生玩出了人性黑暗面
  5. 字符流写数据的5种方式
  6. 汇编语言 利用ASCII以及AND OR进行字符串大小写转换
  7. 用Java递增Map值的最有效方法–仅搜索一次键
  8. 应用框架的设计与实现学习手札系列(持续更新)
  9. Python之list对应元素求和
  10. [转载] 1.1Java使用JDBC原生方式连接MySql数据库
  11. 不支持所上传的文件格式。请确认选择的文件无误。_职场人必备!如何把PDF文件转换成word文档?...
  12. 绿盟科技亮相中国石油石化企业信息技术交流大会
  13. 【金融科技前沿】金融实人认证+基于百度AI的身份证图片批量OCR识别
  14. 朱晔的互联网架构实践心得S2E6:浅谈高并发架构设计的16招
  15. python灰色预测_python灰度预测
  16. android音频焦点Audio Focus
  17. 啊,CET6 2021年
  18. 用Python + Wxpy 为女友搭建简单微信机器人
  19. 11 02 11 无用功
  20. 车载服务器系统,车载系统平台与终端产品的介绍

热门文章

  1. Flatlist实战及爬坑
  2. 重磅来袭!java绝对值表示
  3. 解决MAC电脑下魅族手机adb无法连接问题
  4. 市场预测美联储加息的有效性几何
  5. Halcon 深度学习(三):缺陷检测
  6. Windows官方U盘系统盘制作(windows11)
  7. Snail OS 0.03 user是用户进程和系统调用的简单实现
  8. 第四周项目1建立单链表
  9. VB拼接字符串去除空格
  10. Windows更新后MySQL服务启动失败问题总结