提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
opencv点阵字库显示学习记录
一、汉字在机器内表示
汉字的编码格式主要有区位码和机内码两种,显示时需要依据这几种编码格式找到所需汉字的点阵字库后才能在显示出来。我们可以依据一定的公式,在机器内找到并将其显示出来。
二、汉字叠加图片展示
代码如下
#include <iostream>
#include<string.h>
#include <math.h>
#include "include/opencv2/opencv.hpp"
#include "include/opencv2/core.hpp"
#include "include/opencv2/highgui.hpp"
#include "include/opencv2/highgui/highgui_c.h"
#include "include/opencv2/core/core_c.h"
using namespace std;
using namespace cv;
void PaintSChinese(Mat& image, int x_offset, int y_offset, unsigned long offset);
void PaintSAscii(Mat& image,int x_offset, int y_offset, unsigned long offset);
void putTextToImage(int x_offset,int y_offset,string imagePath ,char* txtPath)
{
Mat img = imread(imagePath);
unsigned char qh, wh;
unsigned long offset;
char hexcode[30];
FILE* filetxt;
if ((filetxt = fopen(txtPath, "rb")) == NULL){
printf("Can't open txtfile,Please check the path!");
//getch();
exit(0);
}
fseek(filetxt, 0, SEEK_SET);
fread(hexcode, 30, 1, filetxt);
int x = x_offset, y = y_offset;
for (int m = 0; m < 30; )
if (hexcode[m] == 0x23)
break;
else if (hexcode[m] > 0xffffffaf)
{
qh = hexcode[m] - 0xaf;
wh = hexcode[m+1] - 0xa0;
offset = (94 * (qh - 1) + (wh - 1)) * 72L;
PaintSChinese(img, x , y , offset);
m = m + 2;
x += 24;
}
else
{
wh = hexcode[m];
offset = wh * 16L;
PaintSAscii(img, x, y, offset);
m++;
x += 16;
}
IplImage *imge;
imge = &cvIplImage(img);
cvSaveImage("image_text.png", imge);
cvNamedWindow("TEXT", 1);
cvShowImage("TEXT", imge);
cvWaitKey();
}
void PaintSChinese(Mat& image, int x_offset, int y_offset, unsigned long offset){
Point p;
p.x = x_offset;
p.y = y_offset;
FILE *HZK;
char buff[72];
if ((HZK = fopen("D:\\Download\\中文点阵字库及显示工具程序\\中文点阵字库\\HZK24F\\HZKf2424.hz", "rb")) == NULL){
printf("Can't open hzk24.hz,Please check the path!");
//getch();
exit(0);
}
fseek(HZK, offset, SEEK_SET);
fread(buff, 72, 1, HZK);
bool mat[24][24];
int i, j, k;
for (i = 0; i<24; i++)
{
for (j = 0; j<3; j++)
for (k = 0; k<8; k++)
if (buff[i * 3 + j] & (0x80 >> k))
{
mat[j * 8 + k][i] = true;
}
else {
mat[j * 8 + k][i] = false;
}
}
for (i = 0; i < 24; i++)
{
p.x = x_offset;
for (j = 0; j < 24; j++)
{
if (mat[i][j])
circle(image, p, 1, Scalar(255, 0, 0), -1);
p.x++;
}
p.y++;
}
}
void PaintSAscii(Mat& image, int x_offset, int y_offset, unsigned long offset){
Point p;
p.x = x_offset;
p.y = y_offset;
char buff[16];
FILE *ASCII;
if ((ASCII = fopen("D:\\Download\\中文点阵字库及显示工具程序\\中文点阵字库\\Asci1516.zf", "rb")) == NULL){
printf("Can't open ascii.zf,Please check the path!");
//getch();
exit(0);
}
fseek(ASCII, offset, SEEK_SET);
fread(buff, 16, 1, ASCII);
int i, j;
Point p1 = p;
for (i = 0; i<16; i++)
{
p.x = x_offset;
for (j = 0; j < 8; j++)
{
p1 = p;
if (buff[i] & (0x80 >> j))
{
circle(image, p1, 0, Scalar(0, 0, 255), -1);
p1.x++;
circle(image, p1, 0, Scalar(0, 0, 255), -1);
p1.y++;
circle(image, p1, 0, Scalar(0, 0, 255), -1);
p1.x--;
circle(image, p1, 0, Scalar(0, 0, 255), -1);
}
p.x+=2;
}
p.y+=2;
}
}
int main(){
putTextToImage(150,450,"te.jpg","name.txt");
return 0;
}
原始图片如下:
处理后图片如下
总结
汉字以及各种字体在屏幕上展示时,需要通过机内码或区位码在点阵字库中找到相对应的汉字点阵。这样才能在屏幕上显示。