一、串口传输文件
1.连接
2.串口发送
二、点阵汉字的字模读取与显示
1.代码
#include <stdio.h>//标准输入输出库
#include <stdlib.h>//
#include <cxcore.h>
#include <highgui.h>
//#include <direct.h>
#include <unistd.h>
using namespace cv;
const int CC_SIZE = 16;
const int SAFE_WIDTH = 10;
const int CC_NUMBER = 15;
// 姓名
unsigned char name[12] = "姚羽";
unsigned int name_code[6][6];
// 学号
unsigned int id_code[12][2] = { { 0xa3, 0xb6 }, { 0xa3, 0xb3 }, { 0xa3, 0xb1 }, { 0xa3, 0xb9 }, { 0xa3, 0xb0 }, { 0xa3, 0xb7 }, { 0xa3, 0xb0 }, { 0xa3, 0xb6 }, { 0xa3, 0xb0 }, { 0xa3, 0xb5 }, { 0xa3, 0xb3 }, { 0xa3, 0xb0 } };
// 保存字节的数组
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);
}
// 显示图片
//cvSaveImage("IMAGE", img);
cvShowImage("IMAGE", img);//显示图片
cvWaitKey(0);//刷新图像,参数单位是毫秒,表示刷新频率
release();//释放捕捉
return 0;
}
void get_area_position_codes()
{
for (int i = 0; i < 2; ++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);//设置流HZK16的文件起始位置为给定偏移offset,参数offset意味着从给定的SEEK_SET位置查找的字节数
fread(mat, 32, 1, HZK16);//从指定流读取数据到mat数组
}
void open_file()
{
char pbuf[100];
getcwd(pbuf, 100);//将当前的工作目录绝对路径复制到参数pbuf所指的内存空间,参数100为pbuf 的空间大小。
strcat(pbuf,"HZKf1616.hz");//把HZKf1616.hz所指向的字符串追加到pbuf所指向的字符串的结尾
// 读取图片
if ((img = cvLoadImage("image.jpg")) == NULL)exit(1);
// 打开字体文件
if ((HZK16 = fopen("HZKf1616.hz", "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))
{
// 绘点
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] = 255;
cs.val[2] = 0;
cvSet2D(img, current_start_y, current_start_x, cs);//获取像素点的值
}
}
void release()
{
cvReleaseImage(&img);
fclose(HZK16);
img = NULL;
HZK16 = NULL;
}
2.效果
三、总结
汉字编码:
区位码
在区位码中,01-09区为特殊字符,10-55区为一级汉字(3755个最常用的汉字,按拼音字母的次序排列),56-87区为二级汉字(3008个汉字,按部首次序排列), 在区位码汉字输入方法中,汉字编码无重码,在熟练掌握汉字的区位码后,录入汉字的速度是很快的,但若想记忆住全部区位码是相当困难的
机内码
汉字机内码、国标码和区位码三者之间的关系为:区位码(十进制)的两个字节分别转换为十六进制后加2020H得到对应的国标码;机内码是汉字交换码(国标码)两个字节的最高位分别加1,即汉字交换码(国标码)的两个字节分别加80H得到对应的机内码;区位码(十进制)的两个字节分别转换为十六进制后加A0H得到对应的机内码