#include<iostream>
#include<opencv/cv.h>
#include"opencv2/opencv.hpp"
#include<opencv/cxcore.h>
#include<opencv/highgui.h>
#include<math.h>
using namespace cv;
using namespace std;
void paint_chinese(Mat& image,int x_offset,int y_offset,unsigned long offset);
void paint_ascii(Mat& image,int x_offset,int y_offset,unsigned long offset);
void put_text_to_image(int x_offset,int y_offset,String image_path,char* **_path);
int main()
{
String image_path="1.jpg";//图片路径
char* **_path=(char*)"**.txt";//学号姓名路径
put_text_to_image(100,200,image_path,**_path);
return 0;
}
void paint_ascii(Mat& image,int x_offset,int y_offset,unsigned long offset)
{
//绘制的起点坐标
Point p;
p.x=x_offset;
p.y=y_offset;
char buff[16]; //存放ascii字模
//打开ascii字库文件
FILE *ASCII;
if((ASCII=fopen("Asci0816.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++) //十六个char
{
p.x=x_offset;
for(j=0;j<8;j++) //一个char八个bit
{
p1=p;
if(buff[i]&(0x80>>j)) //测试当前位是否为1
{
//由于原本ascii字膜是8*16的,不够大,所以原本的一个像素点用4个像素点替换,替换后就有16*32个像素点
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; //原来的一个像素点变为四个像素点,所以x和y都应该+2
}
p.y+=2;
}
}
void paint_chinese(Mat& image,int x_offset,int y_offset,unsigned long offset)
{
//实际在图片上绘制的像素点坐标
Point p;
p.x=x_offset;
p.y=y_offset;
//打开hzk24汉字库文件
FILE *HZK;
char buff[72];//存放汉字字模
if((HZK=fopen("HZKf2424.hz","rb"))==NULL)
{
printf("Can't open HZKf2424.hz,Please check the path!");
//getch();
exit(0);//退出
}
fseek(HZK,offset,SEEK_SET);//将文件指针移动到偏移量的位置
fread(buff,72,1,HZK);//从偏移量的位置读取72个字节,每个汉字占72个字节
bool mat[24][24];//定义一个新的矩阵存放转置后的文字字模
//转置汉字字模矩阵,因为汉字字模存储的是装置后的数据(反的)
int i,j,k;
for(i=0;i<24;i++) //24x24点阵汉字,一共有24行
{
for(j=0;j<3;j++) //横向有3个字节,循环判断每个字节的
for(k=0;k<8;k++) //每个字节有8位,循环判断每位是否为1
if(buff[i*3+j]&(0x80>>k)) //测试当前位是否为1
{
mat[j*8+k][i]=true; //为1的存入新的字模中
}
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 put_text_to_image(int x_offset,int y_offset,String image_path,char* **_path)
{
//通过图片路径获取图片
Mat image=imread(image_path);
int length=18;//要打印的字符长度
unsigned char qh,wh;//定义区号,位号
unsigned long offset;//偏移量
unsigned char hexcode[30];//用于存放记事本读取的十六进制
FILE* file_**;
if ((file_**=fopen(**_path,"rb"))==NULL)
{
printf("Can't open txtfile,Please check the path!");
//getch();
exit(0);
}
fseek(file_**,0,SEEK_SET);//将文件指针移动到偏移量的位置
fread(hexcode,length,1,file_**);
int x=x_offset,y=y_offset;//x,y:在图片上绘制文字的起始坐标
for(int m=0;m<length;)
{
if(hexcode[m]==0x23)
{
break;//读到#号时结束
}
//判断高阶两个十六进制数,大于或等于b0(汉字第一个是b0a1)的都应从汉字字库找
else if(hexcode[m]>0xaf)
{
qh=hexcode[m]-0xaf;//计算区码
wh=hexcode[m+1]-0xa0;//计算位码
offset=(94*(qh-1)+(wh-1))*72L;//计算该汉字在字库中偏移量
paint_chinese(image,x,y,offset);
m=m+2;//一个汉字占两个char,所以加2
x+=24;//一个汉字在图片上占24个像素点,所以水平坐标每次+24
}
else
{
wh=hexcode[m];
offset=wh*16l;//计算英文字符的偏移量
paint_ascii(image,x,y,offset);
m++;//一个char
x+=16;//原本8*16,改为16*32,原本的一个像素点现用四个像素点绘画
}
}
cv::imshow("image",image);
cv::waitKey();
}
————————————————