字库转位图--











h




zk16的介绍以及简单的使用方法


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汉字库的简单读写程序  


#include<stdio.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>

int main()
{
         int i,j,k;
         unsigned char incode[3]="齐";
         //incode[0]=0xb4;
         //incode[1]=0xf3;
         unsigned char qh,wh;
         unsigned long offset;
         printf("The Font Code is %#x,%#x\n",incode[0],incode[1]);
         qh=incode[0] - 0xa0; 
         wh=incode[1] - 0xa0;
         offset = (94*(qh-1)+(wh-1))*32;

         FILE    *HZK;
         char    *mat=(char *)malloc(32);
         memset(mat,0,32);
         if((HZK=fopen("HZK16","rb"))==NULL)
         {
                 printf("Can't    Open    hzk16\n");
                 exit(0);
         }
         fseek(HZK,offset,SEEK_SET);
         fread(mat,32,1,HZK);

         for(j=0;j<16;j++)
         {
for(i=0;i<2;i++) 
{
for(k=0;k<8;k++)
{
if(((mat[j*2+i]>>(7-k)) & 0x1) != 0)
{
printf("x");
}
else
{
printf(" ");
}
}
}
printf("\n");

         }
         fclose(HZK);

return 0;
}


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;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值