图像处理---《在图片上打印文字  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. 设计模式七大原则(C++描述)

    前言 最近在学习一些基本的设计模式,发现很多博客都是写了六个原则,但我认为有7个原则,并且我认为在编码中思想还是挺重要,所以写下一篇博客来总结下 之后有机会会写下一些设计模式的博客(咕咕咕...... ...

  2. 【OpenCV开发】使用OpenCV的OpenCL(ocl)模块

    参加OpenCV的OpenCL模块(以下称OCL)移植工作已经有2个月了.这里我说移植而不是开发,是因为大部分OCL模块的函数都是从已经很成熟的GPU模块移植过来的.于是目前阶段OCL模块所支持的函数 ...

  3. logstash数据迁移

    logstash是一个非常强大的数据迁移工具.这里主要记录今天使用到的几个简单用法. 其中比较需要注意的是 迁移到elasticsearch的时候,output 的 elasticsearch 中的 ...

  4. 【VS开发】内存映射文件3

    内存映射文件 内存映射文件,是由一个文件到一块内存的映射.Win32提供了允许应用程序把文件映射到一个进程的函数 (CreateFileMapping).内存映射文件与虚拟内存有些类似,通过内存映射文 ...

  5. 洛谷 题解 P1133 【教主的花园】

    $n<=10^5 $ O(n)算法 状态 dp[i][j][k]表示在第i个位置,种j*10的高度的树,且这棵树是否比相邻两棵树高 转移 dp[i][1][0]=max(dp[i-1][2][1 ...

  6. POJ 2195 Going Home 【最小费用最大流】

    题目链接:http://poj.org/problem?id=2195 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions:2715 ...

  7. Hadoop之HDFS客户端操作

    1. HDFS 客户端环境准备 1.1 windows 平台搭建 hadoop 2.8.5 2. 创建Maven工程 # pom.xml <dependencies> <depend ...

  8. 《鸟哥的Linux私房菜:基础学习篇》第二部分读书笔记

    一.Linux的文件权限与目录配置 1. Linux用户身份与用户组记录的文件:默认情况下,/etc/passwd记录所有的系统账号与一般身份账号及root的相关信息,/etc/shadow记录个人的 ...

  9. 编译+远程调试spark

    一 编译  以spark2.4 hadoop2.8.4为例 1,spark 项目根pom文件修改 pom文件新增 <profile> <id>hadoop-2.8</id ...

  10. Python基础 第三章 使用字符串(1)精简版

    所有标准序列操作(索引,切片,乘法,成员资格检查,长度,最小值,最大值)都适于字符串. 但,字符串是不可变得,故所有得元素赋值和切片赋值都是非法的. 1. %s 转换说明符 设置字符串格式 %左边指定 ...