图像处理---《在图片上打印文字  windows+GDI+TrueType字体》

  刚开始使用的是putText()函数做,缺陷是只能显示非中文; 接着,看大多数推荐Freetype库来做,尝试了,可以的,适合图像输入的是IPLImage格式,其他格式需要转换一下;现在,看到可以不使用Freetype库做的,也尝试了,好用:

上接前几篇,(3)“采用windows的GDI显示系统的TrueType字体,没有封装,就两个函数,分成了h和cpp文件,可以自己编辑文件名和函数名,亦可以直接将cpp的代码复制到你需要的程序中。”

  

//====================================================================
//
// 文件: textTrueType.h
//
// 说明: OpenCV汉字输出
//
//==================================================================== #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 putTextZH(Mat &dst, const char* str, Point org, Scalar color, int fontSize,
const char *fn = "Arial", bool italic = false, bool underline = false); #endif // PUTTEXT_H_
//====================================================================
//
// 文件: textTrueType.cpp
//
// 说明: OpenCV汉字输出
//
//==================================================================== //#include "putText.h"
#include "textTrueType.h" void GetStringSize(HDC hDC, const char* str, int* w, int* h)
{
SIZE size;
GetTextExtentPoint32A(hDC, str, strlen(str), &size);
if (w != ) *w = size.cx;
if (h != ) *h = size.cy;
} void putTextZH(Mat &dst, const char* str, Point org, Scalar color, int fontSize, const char* fn, bool italic, bool underline)
{
CV_Assert(dst.data != && (dst.channels() == || dst.channels() == )); int x, y, r, b;
if (org.x > dst.cols || org.y > dst.rows) return;
x = org.x < ? -org.x : ;
y = org.y < ? -org.y : ; LOGFONTA lf;
lf.lfHeight = -fontSize;
lf.lfWidth = ;
lf.lfEscapement = ;
lf.lfOrientation = ;
lf.lfWeight = ;
lf.lfItalic = italic; //斜体
lf.lfUnderline = underline; //下划线
lf.lfStrikeOut = ;
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfOutPrecision = ;
lf.lfClipPrecision = ;
lf.lfQuality = PROOF_QUALITY;
lf.lfPitchAndFamily = ;
strcpy_s(lf.lfFaceName, fn); HFONT hf = CreateFontIndirectA(&lf);
HDC hDC = CreateCompatibleDC();
HFONT hOldFont = (HFONT)SelectObject(hDC, hf); int strBaseW = , strBaseH = ;
int singleRow = ;
char buf[ << ];
strcpy_s(buf, str);
char *bufT[ << ]; // 这个用于分隔字符串后剩余的字符,可能会超出。
//处理多行
{
int nnh = ;
int cw, ch; const char* ln = strtok_s(buf, "\n",bufT);
while (ln != )
{
GetStringSize(hDC, ln, &cw, &ch);
strBaseW = max(strBaseW, cw);
strBaseH = max(strBaseH, ch); ln = strtok_s(, "\n",bufT);
nnh++;
}
singleRow = strBaseH;
strBaseH *= nnh;
} if (org.x + strBaseW < || org.y + strBaseH < )
{
SelectObject(hDC, hOldFont);
DeleteObject(hf);
DeleteObject(hDC);
return;
} r = org.x + strBaseW > dst.cols ? dst.cols - org.x - : strBaseW - ;
b = org.y + strBaseH > dst.rows ? dst.rows - org.y - : strBaseH - ;
org.x = org.x < ? : org.x;
org.y = org.y < ? : org.y; BITMAPINFO bmp = { };
BITMAPINFOHEADER& bih = bmp.bmiHeader;
int strDrawLineStep = strBaseW * % == ? strBaseW * : (strBaseW * + - ((strBaseW * ) % )); bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = strBaseW;
bih.biHeight = strBaseH;
bih.biPlanes = ;
bih.biBitCount = ;
bih.biCompression = BI_RGB;
bih.biSizeImage = strBaseH * strDrawLineStep;
bih.biClrUsed = ;
bih.biClrImportant = ; void* pDibData = ;
HBITMAP hBmp = CreateDIBSection(hDC, &bmp, DIB_RGB_COLORS, &pDibData, , ); CV_Assert(pDibData != );
HBITMAP hOldBmp = (HBITMAP)SelectObject(hDC, hBmp); //color.val[2], color.val[1], color.val[0]
SetTextColor(hDC, RGB(, , ));
SetBkColor(hDC, );
//SetStretchBltMode(hDC, COLORONCOLOR); strcpy_s(buf, str);
const char* ln = strtok_s(buf, "\n",bufT);
int outTextY = ;
while (ln != )
{
TextOutA(hDC, , outTextY, ln, strlen(ln));
outTextY += singleRow;
ln = strtok_s(, "\n",bufT);
}
uchar* dstData = (uchar*)dst.data;
int dstStep = dst.step / sizeof(dstData[]);
unsigned char* pImg = (unsigned char*)dst.data + org.x * dst.channels() + org.y * dstStep;
unsigned char* pStr = (unsigned char*)pDibData + x * ;
for (int tty = y; tty <= b; ++tty)
{
unsigned char* subImg = pImg + (tty - y) * dstStep;
unsigned char* subStr = pStr + (strBaseH - tty - ) * strDrawLineStep;
for (int ttx = x; ttx <= r; ++ttx)
{
for (int n = ; n < dst.channels(); ++n){
double vtxt = subStr[n] / 255.0;
int cvv = vtxt * color.val[n] + ( - vtxt) * subImg[n];
subImg[n] = cvv > ? : (cvv < ? : cvv);
} subStr += ;
subImg += dst.channels();
}
} SelectObject(hDC, hOldBmp);
SelectObject(hDC, hOldFont);
DeleteObject(hf);
DeleteObject(hBmp);
DeleteDC(hDC);
}
//====================================================================
//
// 文件: test_main.cpp
//
// 说明: OpenCV汉字输出,测试主函数
//
//====================================================================
#include "opencv2/opencv.hpp" //#include "putText.h"
#include "textTrueType.h" using namespace std;
using namespace cv; /*int main()
{
Mat img = imread("D:\\005_test_4\\testImg\\road_6.png"); putTextZH(img, "Arial字体换...\n行显示!", Point(50, 50), Scalar(0, 0, 255), 30, "Arial");
putTextZH(img, "Times New Roman字体换...\n行显示!", Point(50, 50), Scalar(0, 0, 255), 30, "Times New Roman");
putTextZH(img, "微软雅黑字体换...\n行,斜体,下划线,显示!", Point(50, 100), Scalar(0, 255, 0), 30, "微软雅黑", true, true);
putTextZH(img, "楷体字体换...\n行,斜体,下划线,显示!", Point(50, 200), Scalar(128, 255, 0), 30, "楷体", true, true); imshow("test", img); waitKey(); return 0;
}*/ void main()
{
//Mat img(150,600,CV_8UC3,Scalar(255,255,255));//初始化图像
Mat img = imread("D:\\005_test_4\\testImg\\road_6.png");
putTextZH(img, "打印汉字,汉字,汉字!", Point(, ), Scalar(, , ), , "华文行楷");
imwrite("1.png", img);
imshow("", img);
waitKey();
}

致谢:https://blog.csdn.net/wanggao_1990/article/details/52955056;https://blog.csdn.net/weixinhum/article/details/84074594;

图像处理---《在图片上打印文字 windows+GDI+TrueType字体》的更多相关文章

  1. 图像处理---《在图片上打印文字 FreeType库》

    图像处理---<在图片上打印文字 FreeType库> 目的:想在处理之后的图像上打印输出结果.方法: (1)只在图像上打印 数字.字母的话:                1.Mat格式 ...

  2. 图像处理---《在图片上打印文字 putText()》

    图像处理---<在图片上打印文字 putText()> 目的:想在处理之后的图像上打印输出结果. 方法: (1)只在图像上打印 数字.字母的话:                 1.Mat ...

  3. C#图像处理(1):在图片上加文字和改变文字的方向

    C#在图片上加文字,代码如下: /// <summary> /// 图片上方加文字,文字将会被180度反转 /// </summary> /// <param name= ...

  4. Python3.x:如何识别图片上的文字

    Python3.x:如何识别图片上的文字 安装pytesseract库,必须先安装其依赖的PIL及tesseract-ocr,其中PIL为图像处理库,而后面的tesseract-ocr则为google ...

  5. C#实现图片叠加,图片上嵌入文字,文字生成图片的方法

    /// <summary>     /// 图片叠加     /// </summary>     /// <param name="sender"& ...

  6. python 图片上添加文字

    import PIL from PIL import ImageFont from PIL import Image from PIL import ImageDraw #设置字体,如果没有,也可以不 ...

  7. 使用Qpaint在图片上写文字

    开发过程中需要实现在图片上叠加文字,可以采用Qpaint在图片上写文字,然后将图片显示在上面.再将Qlabel加到Qwidget中.效果如下 //创建对象,加载图片 QPixmap pix; pix. ...

  8. 函数putText()在图片上写文字

    #include <iostream> #include <opencv2/opencv.hpp> using namespace std; using namespace c ...

  9. 把图片上的文字转换成word文字?

    转换后的文字不是很如意,但是免费方便. 1.打开Office办公软件自带的OneNote工具.随便新建一个笔记页面,以方便我们接下来的操作. 2.插入图片.在菜单栏里点击[插入],选择插入[图片],找 ...

随机推荐

  1. java中类加载的全过程及内存图分析

    类加载机制: jvm把class文件加载到内存,并对数据进行校验.解析和初始化,最终形成jvm可以直接使用的java类型的过程. (1)加载 将class文件字节码内容加载到内存中,并将这些静态数据转 ...

  2. lnmp 命令 及其 TP5 部署遇到的一些问题

    1.添加站点域名命令: lnmp vhost add; 2.重置mysql密码: 第一种方法:用军哥的一键修改LNMP环境下MYSQL数据库密码脚本 一键脚本肯定是非常方便.具体执行以下命令: wge ...

  3. list集合的一些小见解

    关于LIst集合 前言: 第一次写博客,有些东西可能总结的到位,发表一下自己的一些观点,欢迎大佬们点评和指教 正文: list集合可以分为ArrayLlst和LinkedList. ArrayList ...

  4. Docker pull php:7.1-fpm的php.ini配置修改

    今天,换了 Deepin 操作系统,开发环境是通过 Docker 搭建的,具体结构如下: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e ...

  5. JavaSE基础(四)--Java基本数据类型

    Java 基本数据类型 变量就是申请内存来存储值.也就是说,当创建变量的时候,需要在内存中申请空间. 内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据. 因此,通过定义不 ...

  6. 小程序部分机型上一个诡异的偶现bug

    如上图所示:开始的时候进到下单页面,价格是0,当选中了商品产生价格的时候,生成的价格如 ¥150,这个时候会只露出¥1以及一小半的5,后面的都被遮挡住了. wxml里是这样的写的 <view w ...

  7. hdoj1561 The more, The Better (树形dp,分组背包)

    题目链接:https://vjudge.net/problem/HDU-1561 题意:给一个森林,每个结点有个权值,求选m个结点的最大权值和,并且选子结点前必须先选父结点. 思路: 把每颗树的树根连 ...

  8. Upgrading CentOS 6 to CentOS 7

    Upgrading CentOS 6 to CentOS 7 November 15th, 2018 — whplus PRE TASKS There are some tasks you can d ...

  9. Win10默认输入法怎么打顿号

    这个问题发现于一个月之前,解决于今天,方式百度. 一.主要是想纪念一下我这一个月的蠢操作(贴图证蠢): 这一个月我的顿号都是这样打出来的,(′д` )…彡…彡 二.闲话少叙,说一下解决方式: 之前用的 ...

  10. DP_Milking Time

    Bessie is such a hard-working cow. In fact, she is so focused on maximizing her productivity that sh ...