gb2312编码表,也就是内容:http://www.knowsky.com/resource/gb2312tbl.htm
参考:
http://www.jdgcs.org/kb/HZK16
google : c语言 图片 汉字
freetype2 库的使用
HZK16字库是符合GB2312标准的16×16点阵字库,HZK16的GB2312-80支持的汉字有6763个,符号682个。其中一级汉字有3755个,按声序排列,二级汉字有3008个,按偏旁部首排列。我们在一些应用场合根本用不到这么多汉字字模,所以在应用时就可以只提取部分字体作为己用。
HZK16字库里的16×16汉字一共需要256个点来显示,也就是说需要32个字节才能达到显示一个普通汉字的目的。
我们知道一个GB2312汉字是由两个字节编码的,范围为A1A1~FEFE。A1-A9为符号区,B0到F7为汉字区。每一个区有94个字符(注意:这只是编码的许可范围,不一定都有字型对应,比如符号区就有很多编码空白区域)。下面以汉字“我”为例,介绍如何在HZK16文件中找到它对应的32个字节的字模数据。
前面说到一个汉字占两个字节,这两个中前一个字节为该汉字的区号,后一个字节为该字的位号。其中,每个区记录94个汉字,位号为该字在该区中的位置。所以要找到“我”在hzk16库中的位置就必须得到它的区码和位码。(为了区别使用了区码和区号,其实是一个东西,别被我误导了)
区码:区号(汉字的第一个字节)-0xa0 (因为汉字编码是从0xa0区开始的,所以文件最前面就是从0xa0区开始,要算出相对区码)
位码:位号(汉字的第二个字节)-0xa0
这样我们就可以得到汉字在HZK16中的绝对偏移位置:
offset=(94*(区码-1)+(位码-1))*32
注解:1、区码减1是因为数组是以0为开始而区号位号是以1为开始的
2、(94*(区号-1)+位号-1)是一个汉字字模占用的字节数
3、最后乘以32是因为汉字库文应从该位置起的32字节信息记录该字的字模信息(前面提到一个汉字要有32个字节显示)
有了偏移地址就可以从HZK16中读取汉字编码了,剩下的就是文件操作了,就不说了,要看代码可以到我的文章:“hzk16汉字库的简单读写程序 ”看一下,是一个最简单的c语言程序。
hzk16汉字库的简单读写程序
c语言实现图片插入汉字
#include <iostream>
#include <stdlib.h>
/*
part one,14 bit
*/
struct head
{
int bfType; //位图类型
long int bfsize; //位图文件大小
int freserved1; //必须为0
int freserved2; //必须为0
long int bfoffbits; //第54个开始
}bmp_head;
/*
part,two, 40 bit
*/
struct info
{
long int bisize; //本结构站用的字节数 40
long biwidth; //位图的宽度
long biheight; //位图的高度
int biplanes; //目标设备的级别
int BIBITCOUNT; //每个象素所需的位数
long int bigcompression;//位图压缩类型
long int bisizeimage; //位图的大小
long bixpelspermeter;
long biypelspermeter;
long int biclrused;
long int biclrimportant;
}bmp_info;
using namespace std;
//unsigned char meng[30]={""};
//unsigned char kai[30]={""};
unsigned char data[8][40]={""};
unsigned int cnt=0;
int arry_length = 8;
unsigned char buf[50]={""};
/*
读入文件
*/
void read(char* txt)
{
FILE *fp;
//int i_1,j_1;
//int i_2,j_2;
int x[10]={};
int y[10]={};
if(( fp = fopen(txt,"rb")) = NULL)
{
perror("Input file open error");
exit(1);
}
else
{
fp = fopen(txt,"rb");
}
for(int i=0 ;i<cnt/2 ;i++)
{
x[i] = buf[2*i] - 0xa0; //计算第一个字的区码
y[i] = buf[2*i+1] - 0xa0; //计算第一个字的位码
fseek(fp,(94*(x[i]-1)+(y[i]-1))*32,0); //把指针移到HZK中目标字的偏移位
fread(data[i],32,1,fp); //读取数据
}
//rewind(fp); //指针回到启始的位置
fclose(fp);
}
/*
从文件中读取想要转化的文字
*/
void readfile(char* txt)
{
FILE *fp;
char ch;
if(( fp = fopen(txt,"rb")) = NULL)
{
perror("Input file open error");
exit(1);
}
else
{
fp = fopen(txt,"rb");
}
while(!feof(fp))
{
ch=fgetc(fp);
cnt++;
}
cnt=(cnt-1);
fseek(fp,0,0);
fread(buf,cnt,1,fp);
fclose(fp);
}
/*
把取得的16进制的编码进行转换,并打引出来
*/
void insert(long bmp_infosize,unsigned char* buff)
{
int s;
int *x; //x数组用来存放比较的结果
s = bmp_infosize-1;
x = (int*)malloc(sizeof(int)*arry_length);
char y[40] = {""};
int offset_1 = 0;
int offset_2 = 0;
int offset_3 = 0;
for(int time=0 ;time<cnt/2 ;time++)
{
for(int k=1 ;k<32 ;k++)
{
int iMask = 1; //iMask是比较的数据
for(int i = 0; i<8; i++)
{
x[i] = data[time][(k-1)] & iMask; //进行或运算
iMask = iMask<<1; //把比较位向左移
}
for(int i=7 ;i>=0 ;i--)
{
if( x[i] == 0 )
{
printf(" ");
}
else
{
buff[s-3*320+(7-i)*3-offset_1+offset_2+offset_3] = 0x00;
buff[s-3*320+(7-i)*3+1-offset_1+offset_2+offset_3] = 0x00;
buff[s-3*320+(7-i)*3+2-offset_1+offset_2+offset_3] = 0x00;
buff[s-3*320+(7-i)*3+3-offset_1+offset_2+offset_3] = 0x00;
printf("* ");
}
}
if(k%2 == 0)
{
printf("\n");
offset_1 = offset_1+320*3;
offset_2=0;
}
else
{
offset_2 = 7*3;
}
}
//offset_3+=3*16;
}
offset_3+=3*16;
}
int main(int argc, char *argv[])
{
readfile("in.txt");
read("HZK16");
FILE *fp;
const int bitcount = 3;
int x1,y1,x2,y2;
long bmp_size,bmp_infosize,size;
unsigned char *temp,*buff;
int offset=0;
if(( fp = fopen("7.bmp","rb")) = NULL) //open a picture
{
perror("Input file open error");
exit(1);
}
else
{
fp = fopen("7.bmp","a+");
}
fread( &bmp_head ,14 ,1 ,fp );
fread( &bmp_info ,40 ,1 ,fp );
x1=0,y1=0,x2=320,y2=240;
bmp_infosize = (x2-x1+3)/4*4*(y2-y1)*bitcount;
bmp_size = bmp_infosize+54;
bmp_head.bfsize = bmp_size;
bmp_info.biwidth = (x2-x1+3)/4*4;
bmp_info.biheight = y2-y1;
bmp_info.bisizeimage = bmp_infosize;
size=bmp_size;
temp = (unsigned char*)malloc((size-54)*sizeof(char)); //read information
fread( temp ,size-54 ,1 ,fp );
buff = (unsigned char*)malloc( bmp_infosize * sizeof(int) );
fseek(fp,54,0);
fseek(fp,320*bitcount*(240-y2),1);
for(int i=0 ;i<y2-y1 ;i++)
{
fseek( fp ,x1*bitcount ,1 ); //把指针向后移动到x1
fread( &buff[i+offset] ,bmp_info.biwidth*bitcount ,1 ,fp );//读取图片宽度*4个长度
fseek( fp ,(320-x2)*bitcount ,1 ); //把指针向后移动到320
offset = offset+bmp_info.biwidth*bitcount-1; //把 offset增加 图片宽度*4个长度
}
fclose(fp);
insert(bmp_infosize,buff);
fp = fopen("8.bmp","a+"); //construct a new picture
fwrite( &bmp_head ,14 ,1 ,fp );
fwrite( &bmp_info ,40 ,1 ,fp );
fwrite( buff ,bmp_infosize ,1 ,fp );
fclose(fp);
system("PAUSE");
return 0;
}