文章目录
一. 认识汉字编码
为什么有汉字编码?
最早的ASCII码只包括了字母、标点符号、特殊字符等127个字符。这些字符对于拉丁语系国家的人使用是足够的,但是对于非拉丁语系国家(如中国、日本等),ASCII码就远远不够了。因此就需要编码来表示大量的汉字字符。
汉字编码是为汉字设计的一种便于输入计算机的代码。由于电子计算机现有的输入键盘与英文打字机键盘完全兼容。因而如何输入非拉丁字母的文字(包括汉字)便成了多年来人们研究的课题。汉字信息处理系统一般包括编码、输入、存储、编辑、输出和传输。编码是关键。不解决这个问题,汉字就不能进入计算机。
常用汉字编码
编码格式 | 含义及用途 |
---|---|
Unicode编码 | Unicode编码通常由两个字节组成,称作USC-2,个别偏僻字由四个字节组成,称作USC-4;可以囊括多国语言,囊括了常用汉字 |
UTF-8编码 | Unicode编码的一种,Unicode用一些基本的保留字符制定了三套编码方式,它们分别为UTF-8,UTF-16,UTF-32。其中UTF-8俗称“万国码”,可以同屏显示多语种,一个汉字通常占用3字节(生僻字占6个)。为了做到国际化,网页尽可能采用UTF-8编码 |
GB2312编码 | GB2312简体中文编码,一个汉字占用2个字节,在大陆是主要的编码方式。是国家简体中文字符集,兼容ASCII |
BIG5编码 | 称为繁体中文编码,主要在台湾地区使用 |
GBK编码 | 它是GB2312的扩展,加入对繁体字的支持,兼容GB2312 |
GB18030编码 | 它解决了中文、日文、朝鲜语等的编码,兼容GBK |
(1)区位码
在国标 GD2312—80 中规定,所有的国标汉字及符号分配在一个 94 行、94 列的方阵中,方阵的每一行称为一个“区”,编号为 01区到 94 区,每一列称为一个“位”,编号为01 位到 94位,方阵中的每一个汉字和符号所在的区号和位号组合在一起形成的四个阿拉伯数字就是它们的“区位码”。区位码的前两位是它的区号,后两位是它的位号。用区位码就可以唯一地确定一个汉字或符号,反过来说,任何一个汉字或符号也都对应着一个唯一的区位码。
- 区域分布情况
区间 | 内容 |
---|---|
00-09 区 | 是符号、数字、英文字符等 |
10-15 区 | 空白, 留待扩展 |
16-55 区 | 常用汉字(也有叫一级汉字), 按拼音排序 |
56-87 区 | 非常用汉字(也有叫二级汉字), 这是按部首排序的 |
88-94 区 | 空白, 留待扩展 |
(2)机内码
汉字的机内码是指在计算机中表示一个汉字的编码。机内码与区位码稍有区别。如直接用区位码作为机内码,就会与基本 ASCII 码混淆。为了避免机内码与基本 ASCII 码的冲突,需要避开基本 ASCII 码中的控制码(00H~1FH),还需与基本 ASCII 码中的字符相区别。为了实现这两点,可以先在区码和位码分别加上 20H,在此基础上再加 80H(此处“H”表示前两位数字为十六进制数)。经过这些处理,用机内码表示一个汉字需要占两个字节,分别称为高位字节和低位字节,这两位字节的机内码按如下规则表示:
高位字节 = 区码 + 20H + 80H(或区码 + A0H)
低位字节 = 位码 + 20H + 80H(或位码 + A0H)
(3)点阵字库结构
-
在汉字的点阵字库中,每个字节的每个位都代表一个汉字的一个点,每个汉字都是由一个矩形的点阵组成,0 代表没有,1 代表有点,将 0 和 1 分别用不同颜色画出,就形成了一个汉字,常用的点阵矩阵有 12×12,14×14,16×16三种字库。
-
字库根据字节所表示点的不同有分为横向矩阵和纵向矩阵,目前多数的字库都是横向矩阵的存储方式,纵向矩阵一般是因为有某些液晶是采用纵向扫描显示法,为了提高显示速度,于是便把字库矩阵做成纵向,省得在显示时还要做矩阵转换。
我们接下去所描述的都是指横向矩阵字库。
下面举例说明点阵字库的存储
- 对于 16*16 的矩阵来说,它所需要的位数共是 16×16=256 个位,每个字节为 8 位,因此,每个汉字都需要用 256/8=32 个字节来表示。即每两个字节代表一行的 16 个点,共需要 16 行,显示汉字时,只需一次性读取 32 个字节,并将每两个字节为一行打印出来,即可形成一个汉字。
- 点阵结构如下图所示:
(4)汉字点阵获取
- 利用区位码获取汉字
汉字点阵字库是根据区位码的顺序进行存储的,因此,我们可以根据区位来
获取一个字库的点阵,它的计算公式如下:
点阵起始位置 = ((区码- 1)*94 + (位码 – 1)) * 汉字点阵字节数
获取点阵起始位置后,我们就可以从这个位置开始,读取出一个汉字的点阵。 - 利用汉字机内码获取汉字
我们可以根据机内码来获得区位码:
区码 = 机内码高位字节 - A0H
位码 = 机内码低位字节 - A0H
将这个公式与获取汉字点阵的公式进行合并计就可以得到汉字的点阵位置。
二. 实例——调用opencv在图片上显示文字
本例是在Ubuntu下用C/C++调用opencv库编程显示一张图片,并打开一个名为"logo.txt"的文本文件(其中只有一行文本文件,包括名字和学号),按照名字和学号去读取汉字24*24点阵字形字库中对应字符的字形数据,将名字和学号叠加显示在此图片右下位置
(1)准备工作
- 准备24*24的点阵.hz文件、ASCII码.zf文件、需要显示的文本文件、一张图片
注意:在logo.txt文件中输入想要显示的文字(需要用ANSI编码进行编写),不然中文会出现乱码
- 将下面四个文件放在一个文件夹中
- 打开虚拟机,将含有四个文件的文件夹拖拽到Ubuntu磁盘中
(2)撰写代码
- 在文件夹下打开终端,创建一个work.cpp文件,输入命令
gedit work.cpp
- 写入代码
第16行修改为自己的图片名字,18行可以修改汉字显示的位置,115行修改为文本文件的字节数
#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* logo_path);
int main(){