HZK16汉字16*16点阵字库的使用及实例程序 您所在的位置:网站首页 字体语言表示 HZK16汉字16*16点阵字库的使用及实例程序

HZK16汉字16*16点阵字库的使用及实例程序

2024-07-10 02:07| 来源: 网络整理| 查看: 265

前言:最近有个关于泰国文字识别并打印的项目。之前对泰文的了解只听过“萨瓦迪卡”-_-!!,所以前两天在学习泰文的排版规范及unicode编码,了解之后开始学习文字点阵打印的原理及代码编写。今天学习了汉字16*16点阵字库的使用。

这里首先感谢陪她去流浪大佬的文章(这个大佬的id一听就是有女朋友的,羡慕o.o),文章简介明了、通俗易懂,代码讲解也非常的详细。

原理:

HZK16字库是符合GB2312国家标准的16×16点阵字库,HZK16的GB2312-80支持的汉字有6763个,符号682个。其中一级汉字有 3755个,按声序排列,二级汉字有3008个,按偏旁部首排列。

HZK16字库里的16×16汉字一共需要256个点来显示,也就是说需要32个字节才能达到显示一个普通汉字的目的。我们在一些应用场合根本用不到这么多汉字字模,所以在应用时就可以只提取部分字体作为己用就可以了。

我们知道一个GB2312汉字是由两个字节编码的,范围为0xA1A1~0xFEFE。A1-A9为符号区,B0-F7为汉字区。每一个区有94个字符(注意:这只是编码的许可范围,不一定都有字型对应,比如符号区就有很多编码空白区域)

下面以汉字「我」为例,介绍如何在HZK16文件中找到它对应的32个字节的字模数据。

前面说到一个汉字占两个字节,这两个中前一个字节为该汉字的区号,后一个字节为该字的位号。其中,每个区记录94个汉字,位号为该字在该区中的位置。所以要找到「我」在hzk16库中的位置就必须得到它的区码和位码。

区码:汉字的第一个字节-0xA0,因为汉字编码是从0xA0区开始的,所以文件最前面就是从0xA0区开始,要算出相对区码位码:汉字的第二个字节-0xA0

这样我们就可以得到汉字在HZK16中的绝对偏移位置:offset = (94*(区码-1)+(位码-1))*32 。

注解:

区码减1是因为数组是以0为开始而区号位号是以1为开始的(94*(区号-1)+位号-1) 是一个汉字字模占用的字节数最后乘以32是因为汉字库文应从该位置起的32字节信息记录该字的字模信息(前面提到一个汉字要有32个字节显示) 图示:

“我”的点阵输出如下图所示: 在这里插入图片描述

所以,“我”在HZK16*16点阵字库的存放序列为(一行一行地保存,共16行,每行2个字节,共32个字节): 在这里插入图片描述 程序输出应该这样: 在这里插入图片描述

源代码实例: 版本1 #include int main(void) { FILE* fd = NULL; int i, j, k, offset; int flag; unsigned char buffer[32]; unsigned char word[3] = "我"; unsigned char key[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; fd = fopen("hzk16", "rb"); if (fd == NULL) { fprintf(stderr, "error hzk16\n"); return 1; } offset = (94 * (unsigned int)(word[0] - 0xa0 - 1) + (word[1] - 0xa0 - 1)) * 32; fseek(fd, offset, SEEK_SET); fread(buffer, 1, 32, fd); for (k = 0; k for (j = 0; j flag = buffer[k * 2 + j] & key[i]; printf("%s", flag ? "●" : "○"); } } printf("\n"); } fclose(fd); fd = NULL; return 0; } 版本2 #include #include int main(void) { FILE* fphzk = NULL; int i, j, k, offset; int flag; unsigned char buffer[32]; unsigned char word[5]; unsigned char key[8] = { 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 }; fphzk = fopen("hzk16", "rb"); if(fphzk == NULL){ fprintf(stderr, "error hzk16\n"); return 1; } while(1){ printf("输入要生成字模的汉字(多个):"); for(;;){ fgets((char*)word, 3, stdin); if(*word == '\n') break; offset = (94*(unsigned int)(word[0]-0xa0-1)+(word[1]-0xa0-1))*32; fseek(fphzk, offset, SEEK_SET); fread(buffer, 1, 32, fphzk); for(k=0; k for(i=0; i printf("0x%02X,", buffer[k]); } printf("0x%02X};\n", buffer[31]); printf("\n"); } } fclose(fphzk); fphzk = NULL; return 0; } 版本3 #include #include int main(void) { FILE* fphzk = NULL; int i, j, k, offset; int flag; unsigned char buffer[32]; unsigned char word[2] = {0xCE, 0xD2}; // 改成你的转码后的汉字编码 unsigned char key[8] = { 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 }; fphzk = fopen("hzk16", "rb"); if(fphzk == NULL){ fprintf(stderr, "error hzk16\n"); return 1; } offset = (94*(unsigned int)(word[0]-0xa0-1)+(word[1]-0xa0-1))*32; fseek(fphzk, offset, SEEK_SET); fread(buffer, 1, 32, fphzk); for(k=0; k for(i=0; i printf("0x%02X,", buffer[k]); } printf("\n"); fclose(fphzk); fphzk = NULL; return 0; }

各种字库下载地址:http://pan.baidu.com/share/link?shareid=2514580636&uk=320828865



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有