点阵汉字图片叠加显示【课程实验】
这次的博客是我们的一次课程实验,实验内容主要是验证和完成汉字的区位码、国际吗、机内码之间的转换规则,以及在图片上叠加汉字。
本次实验要完成的内容主要i有三个:
- 验证汉字的区位码和机内码转换关系。
- 如果包含汉字串(比如“张三 631604406”)的txt文本文件分别以ANSI、UTF-8、UTF-16、GBK编码格式保存、重新验证任务1。
- 编程完成一张图片上的汉字叠加显示。
一、验证汉字的区位码和机内码的转换关系
1、区位码
在国标 GD2312—80 中规定,所有的国标汉字及符号分配在一个 94 行、94 列的方阵中,方阵的每一行称为一个“区”,编号为 01 区到 94 区,每一列称为一个“位”,编号为01 位到 94 位,方阵中的每一个汉字和符号所在的区号和位号组合在一起形成的四个阿拉伯数字就是它们的“区位码”。区位码的前两位是它的区号,后两位是它的位号。用区位码就可以唯一地确定一个汉字或符号,反过来说,任何一个汉字或符号也都对应着一个唯一的区位码。汉字“母”字的区位码是 3624,表明它在方阵的 36 区 24 位,问号“?”的区位码为0331,则它在 03 区 3l 位。
2、机内码
汉字的机内码是指在计算机中表示一个汉字的编码。机内码与区位码稍有区别。如上所述,汉字区位码的区码和位码的取值均在 1~94 之间,如直接用区位码作为机内码,就会与基本 ASCII 码混淆。为了避免机内码与基本 ASCII 码的冲突,需要避开基本 ASCII 码中的控制码(00H~1FH),还需与基本 ASCII 码中的字符相区别。为了实现这两点,可以先在区码和位码分别加上 20H,在此基础上再加 80H。经过这些处理,用机内码表示一个汉字需要占两个字节,分别称为高位字节和低位字节,这两位字节的机内码按如下规则表示:
高位字节 = 区码 + 20H + 80H(或区码 + A0H)
低位字节 = 位码 + 20H + 80H(或位码 + AOH)
由于汉字的区码与位码的取值范围的十六进制数均为 01H~5EH(即十进制的 01~94),所以汉字的高位字节与低位字节的取值范围则为 A1H~FEH(即十进制的 161~254)
例如,汉字“啊”的区位码为 1601,区码和位码分别用十六进制表示即为 1001H,它的机内码的高位字节为 B0H,低位字节为 A1H,机内码就是 B0A1H
有几种方法可以实现在Windows下查看汉字机内码:
1)Debug
由于我的电脑的Windows10没有Debug,所以没法验证,推荐一篇:https://blog.csdn.net/qincode/article/details/26079213?utm_source=blogxgwz0
2)使用WinHex
下载地址:http://www.x-ways.net/winhex/
使用WinHex直接打开输入了汉字的*.txt文件(直接就是16进制的):
3)使用notepad++
下载地址:https://notepad-plus.en.softonic.com/
使用方法:在NotePad++中输入汉字,然后直接以十六进制显示就是汉字的机内码:
4)C语言查看
直接贴出代码:
#include<stdio.h>
void main(void)
{unsigned char temp[2];scanf("%s",temp);printf("机内码高字节是0x%.2x\n",temp[0]);printf("机内码低字节是0x%.2x\n",temp[1]);printf("区位码区码是%2d\n",temp[0]-0xa0);printf("区位码位码是%2d\n",temp[1]-0xa0);printf("国际码高字节是0x%.2x\n",temp[0]-0x80);printf("国际码低字节是0x%.2x\n",temp[1]-0x80);
}
测试结果如下:
第二个实验要求有重复的地方,和第一个差不多。
推荐一篇关于UTF-8编码的:https://blog.csdn.net/xiaolei1021/article/details/52093706
其中要注意的是在Windows中可以用记事本中文件->另存为:
选择编码格式,但是这里只utf-8、ANSI、Unicode等四种编码格式,在notepad++中何以更改更多的编码格式:
在设置->首选项->新建选项卡:
可以修改编码格式。
三、编程完成一张图片上的汉字叠加显示
直接上效果图
然后是代码:
#include <stdio.h>
#include <stdlib.h>
#include <cxcore.h>
#include <highgui.h>
#include <direct.h>
#include<iostream>
using namespace std;
using namespace cv;const int CC_SIZE = 16;
const int SAFE_WIDTH = 10;
const int CC_NUMBER = 15;
// 姓名
unsigned char name[7] = "xx"; //自己的名字
unsigned int name_code[2][2];// 学号
unsigned int id_code[12][2] = { { 0xa3, 0xb6 }, { 0xa3, 0xb3 }, { 0xa3, 0xb1 }, { 0xa3, 0xb6 }, { 0xa3, 0xb0 }, { 0xa3, 0xb7 }, { 0xa3, 0xb0 }, { 0xa3, 0xb4 }, { 0xa3, 0xb0 }, { 0xa3, 0xb1 }, { 0xa3, 0xb0 }, { 0xa3, 0xb3 } };// 保存字节的数组
unsigned char mat[16][2];FILE* HZK16;
IplImage* img;void get_area_position_codes();void get_mat(int a_code, int p_code);void open_file();void draw_one_cc(int num);void release();int main()
{open_file();get_area_position_codes();// 写名字int i, j;for (i = 0; i < 2; ++i){get_mat(name_code[i][0], name_code[i][1]);draw_one_cc(i);}// 写学号for (j = 0; j < 12; ++j){get_mat(id_code[j][0] - 0xa0, id_code[j][1] - 0xa0);draw_one_cc(i + j);}// 显示图片cvShowImage("IMAGE", img);cvWaitKey(0);release();return 0;
}void get_area_position_codes()
{for (int i = 0; i < 3; ++i)for (int j = 0; j < 2; ++j)name_code[i][j] = name[i * 2 + j] - 0xa0;
}void get_mat(int a_code, int p_code)
{long offset;offset = (94 * (a_code - 1) + (p_code - 1)) * 32L;// 读取数据存入数组fseek(HZK16, offset, SEEK_SET);fread(mat, 32, 1, HZK16);
}void open_file()
{char pbuf[100];_getcwd(pbuf, 100);strcat(pbuf, "\\HZKf1616.hz");// 读取图片if ((img = cvLoadImage("lena.jpg")) == NULL)exit(1);// 打开字体文件if ((HZK16 = fopen(pbuf, "rb")) == NULL)exit(1);
}void draw_one_cc(int num)
{// 图片的像素值int width, height;width = img->width;height = img->height;// 开始的x y像素点int start_x, start_y, size, current_start_x, current_start_y;size = CC_SIZE + SAFE_WIDTH;start_x = width - CC_NUMBER * size;start_y = height - CC_SIZE - SAFE_WIDTH;// 开始绘制CvScalar cs;for (int i = 0; i < 16; ++i)for (int j = 0; j < 2; ++j)for (int k = 0; k < 8; k++)if (mat[i][j] & (0x80 >> k)){cout << mat[i][j] << endl;// 绘点current_start_x = j * 8 + k + start_x + size * num;current_start_y = start_y + i;cs = cvGet2D(img, current_start_y, current_start_x);cs.val[0] = 0;cs.val[1] = 0;cs.val[2] = 0;cvSet2D(img, current_start_y, current_start_x, cs);}
}void release()
{cvReleaseImage(&img);fclose(HZK16);img = NULL;HZK16 = NULL;
}
四、实验体会
本次实验主要的内容是为了了解和理解汉字的区位码、机内码的编码规则,以及utf-8等编码格式的编码规则,了解了汉字在计算机中是如何的存储和输出的。
点阵汉字图片叠加显示【课程实验】相关推荐
- 51单片机实现c语言字母滚动,使用51单片机实现点阵汉字平滑滚动显示
使用51单片机实现点阵汉字平滑滚动显示 #说明:采用的芯片是89C51,LED点阵屏的规格是16*16,同时使用了两个74HC595芯片,字模生成软件在文末有网盘链接. 1 连接原理图 整体的电路连接 ...
- QT半透明图片叠加显示
需求描述:两张图片,一张作为背景,另一张半透明,作为前景.透过前景可以看到背景图 1.用QPixmap对象载入背景图片,或者用paint代码在QPixmap自己画图:把QPixmap放入QLabel中 ...
- 基于Ubuntu系统,调用opencv在图片上显示数字和汉字
文章目录 一.汉字编码的介绍 1.汉字编码的发展过程 (1)汉字编码产生的原因 (2)常用的汉字编码 2.区位码 (1)产生原因 (2)概念简述 (3)区域分布情况 3.机内码 (1)基本概念 (2) ...
- STM32的串口传输文件和点阵汉字的字模读取与显示
文章目录 一.串口传输文件 1.题目要求 2.实验过程 二.汉字点阵原理 1.汉字编码 2.点库字库结构 3.汉字点阵获取 三.Ubuntu下显示图片和文字 1.实验要求 2.实验准备 3.编写代码 ...
- 【嵌入式】在Ubuntu系统下通过OpenCV实现点阵汉字的字模读取与显示
介绍汉字点阵的原理,理解汉字的机内码.区位码编码规则和字形数据存储格式,通过OpenCV在Ubuntu系统下显示点阵汉字 一.汉字点阵原理 1.汉字点阵原理 1.点阵 2.汉字编码 3.点阵字库存储 ...
- c语言 字体点阵取模,[汉字取模软件怎么用]单片机点阵汉字显示需要用
[汉字取模软件怎么用]单片机点阵汉字显示需要用汉字取模软件吗 通常,用汉字取模软件生成工程所需所有汉字点阵信息.也可利用字库芯片,根据汉字内码计算字模地址,并从字库芯片中导出相关汉字的点阵信息.前者容 ...
- pc机之间的通信和点阵汉字的字模读取与显示
pc机之间的通信 连线设置 点阵汉字的读取与打印 在ubuntu下面用c调用opencv显示文字和图片 总结 连线设置 两个usb转换口 G-G,3.3-3.3,TX-RX,RX-TX 打开串口助手选 ...
- Ubuntu下点阵汉字的字模读取与显示
文章目录 一.汉字的区位码.机内码编码规则 1.GB2312标准 2.区位码 3.机内码 二.字形数据存储格式 1. Unicode 字符集和编码 2.字模 3.汉字点阵获取 三.在图片上叠加显示学号 ...
- 嵌入式系统基础:点阵汉字的字模读取与显示
点阵汉字的字模读取与显示 虚拟机:VitrualBox 6 系统:Ubuntu 18 函数库:OpenCV 3.4(涉及到图像编程) 文章目录 点阵汉字的字模读取与显示 一.汉字点阵字库原理 1. 汉 ...
最新文章
- Java项目:在线美食网站系统(java+SSM+jsp+mysql+maven)
- java1.8 indexes_java1.8源码之ArrayList源码解读
- Windows7自带桌面截图不小心删了怎么办?
- WPF路径动画(动态逆向动画)
- Java源码分析之HashMap(JDK1.8)
- vue使用better-scroll实现下拉刷新、上拉加载
- Python笔记-U2解锁手机九宫格
- 对中文语法的编程语言的质疑与回应
- 好消息 | 顶级 AI 华人学者拟加入清华大学自动化系!
- configurationproperties_Spring Boot中@ConfigurationProperties注解实现原理源码解析
- 犀牛软件rhinoceros的参数化设计插件草蜢grasshopper的安装
- 哈工大计算机科学与技术邬向前,人工智能学院组队赴哈工大交流学习
- php实现幻灯片效果,flash幻灯片切换效果代码,超简单超实用
- 创意信息联席CTO:学习财务思维,打造100位技术大咖
- 机器学习(一):定义
- 抖音企业号抖音智能营销系统源码待开发技术。。。。。
- LinuxZIP压缩和解压缩
- Deskpool云办公系列化配置
- php短信炸弹,php发送短信炸弹
- php有什么版本,php哪个版本稳定?