如何把一个汉字点阵码掏出来.docx
《如何把一个汉字点阵码掏出来.docx》由会员分享,可在线阅读,更多相关《如何把一个汉字点阵码掏出来.docx(11页珍藏版)》请在冰点文库上搜索。
如何把一个汉字点阵码掏出来
如何把一个汉字的点阵码掏出来?
我要把汉字显示在LED上
我以前回过的一个类似贴
汉字库我用的是UCDOS的HZK16,直接导入了ROM
他说的仅仅是取点阵码罢了。
用软件就不必说了,那太多了。
用程序来:
在一块MemDC上写上汉字,
弄到合适大小。
然后GetPixel
CDC memDC;
CBitmap memBmp;
CBitmap *pOldBmp;
(...);.);
pOldBmp = (&memBmp);.
(...);94L32L
扩展名是fon。
我这里也有,如果需要可以和我联系。
注意库文件和输入点阵数的匹配!
#include<>
#definereglen94//每区(行)有94位(列)
#definesubcode0xa0//内码与区位码的差值
/*
#definefont_size16//点阵的数目//////根据字体库进行更改
#definedotsizefont_size*font_size/8//一个汉字点阵所占的字节数
charfont_file_name[]="";//点阵字库文件名,必须与字体大小匹配
charbindot[dotsize];//存储点阵信息的数组
*/
charstr[2],ch;
intfont_size,dotsize;
voidprintcharbindot(char*bindot,intdotlen);
intmain()
{
charfont_file_name[30];
printf("输入字体点阵数:
(12或16):
\n");
scanf("%d",&font_size);
printf("输入文字库文件的路径(如果在同目录可只输入文件名):
scanf("%s",font_file_name);
dotsize=(font_size*font_size/8);
#if(font_size==12)
charbindot[12*12/8];
#else
charbindot[16*16/8];
#endif
FILE*fp=fopen(font_file_name,"r");
ch=getchar();
printf("输入任意中文文本:
while(ch=getchar(),ch!
='\n')
str[0]=ch;
str[1]=ch;
intstring_size=font_size*font_size;
inti=0,j=0;
unsignedcharregcode;//区码
unsignedcharbitcode;//位码
//计算区位码
regcode=(unsignedchar)str[i]-subcode;
bitcode=(unsignedchar)str[i+1]-subcode;
//计算汉字在字库中的位置
intoffset=((regcode-1)*reglen+bitcode-1)*dotsize;
//在字库文件中读取点阵数据
fseek(fp,offset,SEEK_SET);
fread(bindot,sizeof(bindot),1,fp);
//输出
printcharbindot(bindot,dotsize);
for(i=1;i<=font_size;i++)
printf("--");
printf("\n");
}
fclose(fp);
system("pause");
return0;
//按顺序输出点阵的每一位信息
voidprintcharbindot(char*bindot,intdotlen)
intcharnum=0;//当前字节号
intbitnum=0;//已读取的位数
intbitindex=0;//当前位号
intbitvalue;//当前位的值
for(charnum=0;charnum{ //从高到低顺次输出一个字节的每位信息 for(bitindex=7;bitindex>=0;bitindex--) { //输出当前字节第bitindix位的值 bitvalue=((bindot[charnum]>>bitindex)&0x1); if(bitvalue==1) printf("**"); else printf(" "); //printf("%c",bitvalue+'0'); //一行输出完了换行 if((++bitnum%font_size)==0) printf("\n"); }}return;}欢迎大家提出你们宝贵的意见或建议。标签: 1、汉字的点阵码我此刻明白的是:(1)汉字能够以点阵的形式存储。(2)液晶能够在屏上画点。这二者结合起来就能够够在液晶屏上显示汉字。最简单的方式,能够在程序中事前存储号点阵码的字符,然后要用的时候显示出来。举个例子,小那个汉字,它的点阵码是如此的:它对应的点阵字符码是:0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x05,0x40,0x05,0x20,0x09,0x10,0x09,0x08,0x11,0x04,0x21,0x04,0x41,0x00,0x01,0x00,0x01,0x00,0x05,0x00,0x02,0x00共32个字节,其扫描的顺序是从左到右,从上到下。在显示的时候,再把字符点阵按相同的顺序显示在液晶屏上,就看到了小字。2、中文文档的存储方式那么咱们看到的中文文档,它们全数都是存储的这种点阵码吗?不是的。汉字在运算机内容实际是存储的一种特定编码。比如“小”那个字,在文档内咱们在对应位置看到的可能是“D0A1”,也可能是“5C0F”,也确实是能够有不同的编码表示“小”那个汉字,这确实是汉字的编码方式。我此刻听过的概念有:区位码、国标码、内码、unicode、UTF-8,还有GBK、GB2312(这两个仿佛与国标码是相关的,具体怎么对应,我的明白得还不是很清楚)。除UTF-8适合在网络上传输,那个地址不管它。其它几种编码方式都是16位的,其大致关系如下:内码=国标码+0x80;国标码=区位码+0x20;国标码=GB2312;GBK仿佛是国标码的最新扩展。汉字在运算机内部文档里面一样是之内码的形式存储。而文件系统里中文文件名一样以unicode编码的形式存储。以上这些明白得不知对不对?再去XX一下加深对这些概念的明白得。GB2312、GBK都是中文的内码,GB18030仿佛是最新的扩展(还包括了少数名族的字符),Big5是繁体汉字的内码。嵌入式系统上一样用GB2312就好了。“D0A1”确实是:“小”的内码,是一种GB2312码,固然由于GBK、GB18030的继承性,一样的汉字其编码是一样的。3、中文字库的作用当运算机程序读取一个中文文档时,它读到的是内码,什么缘故能够在屏幕上显示其字形呢?方式是在运算机内部存储了一个汉字字库,存储了大部份汉字的字形点阵。而且关于每一个汉字来讲,它在字库里点阵的位置与其内码存在着一一对应关系。也确实是说只要明白了内码,就能够够在字库文件里找到其点阵码,然后进行显示。GB2312型的内码是通过以下的换算找到其在字库中的位置的,以“小”字为例:它的内码是“D0A1”,别减去“A0A0”取得其区位码,“3001”。字库的组织方式确实是依照区位码排列的,在0x30区,序号29,每一个区94个汉字,一次其序号为:(0x30-1)*94+(01-1)。固然从字节的存储位置来讲,还要乘以32,(每一个汉字16*16点阵,占据32个字节),综合起来,公式能够写成:CharPos=((NH-0xA1)*94+(NL-0xA1))*32。我此刻也不能完全确认这确实是对的,我在网上下了UCDOS的HZK16文件,专门快就要编写一个测试程序来查验。4、咱们在键盘上是怎么样输入汉字的事实上咱们在键盘上的“键入组合”,在“中文输入法”的干与下,将被转换为内码。仿佛有的时候,这种键入组合也能够称之为外码。比如,咱们怎么样在键盘上输入汉字“小”呢?以最经常使用的拼音输入法为例,咱们要一次键入“xiao”四个字符,那个应该就叫做“外码”,那时起主导作用的输入法通过“查表”或“其它算法”,将那个组合方式转变成了“小”字的内码“D0A1”存储在文件内,或在运算机上传输。比如串口,你输入“小”的时候,串话柄际发出的是“A1”,“D0”。(小端字节应该是如此发的吧)。 5、第一个测试程序的计划添加一个命令mctest,STM32开发同意到那个命令后,等待串口终端的输入。假设输入一个汉字,那么命令处置程序打开汉字库文件,找到点阵码,在液晶上显示汉字。假设输入英文字符,也要能显示英文。当按下“ESC”键的时候,命令处置程序退出。 标签: 1、程序框架的修改我编写程序都是积存式的,以前曾经编写过五个按键输入、液晶作为显示终端的命令输入界面。那个界面一直是有效的,此刻汉字显示要利用液晶屏,因此要通过一些修改。修改的地址如下:(1)主程序占用了液晶的一行,写液晶的那句话注释掉。//Shell_PutStrPC(0,0,Str,Yellow,Black);//不要占据屏幕了(2)键盘、液晶命令界面的主任务删除掉。实际确实是不创建那个任务了。//OSTaskCreate(Task_CmdShell,(void*)0,&Task_CmdShellStk[TaskStk_Size-1],Task_CmdShell_Prio);//该任务临时不需要了。(3)在键盘扫描任务中,使读键子程序老是返回0(不管有无按键)KeyCurrent=GetKeyState();//老是返回0(4)在无按键输入处置流程中,将关闭液晶显示的指令去掉因为在以前的程序中,当一分钟左右没有按键输入的时候,系统会自动关闭液晶显示(模拟电话的模式),此刻要注释掉。//DisplayOn=0;//不要关闭屏幕//LCD_DisplayOff();再次编译下载,成功。液晶此刻能够自由利用了。2、mctest命令处置程序框架的编写修改支持命令个数的常数、添加命令字符串、初始化命令表的新命令、在输入命令文件中添加新命令、在Help命令处置程序中添加新命令显示、写新命令函数概念(临时空着),编译下载,一个新的命令就添加成功了。这次又要支持很多的命令,故工程中新增加一个文件,用于处置多媒体相关的命令。3、mctest命令处置程序内容的设计处置程序进入一个循环,不断的接收从串口过来的字符。若是是“ESC”键按下(0x1B),那么跳出循环。概念一个标志字符,当接收到ESC时,设置标志为1。采纳dowhile循环结构。概念两个字符变量,接收一个字符后进行判定。若是小于0x80,说明是一般的ascii码,进行相应处置。若是大于0x80,判定是不是DBCS的第一个字节。接收第二个字节,同时判定是不是DBCS第二字节,若是知足条件,计算出对应汉字在字库文件中对应的存储位置。打开字库文件,定位到存储位置,读取32个字节存入缓冲区。然后挪用液晶显示程序显示汉字。do{Char1=Uart_GetChar();//那个字符是从串口字符队列中取得的。if(Char1<0x80){if(Char1==0x1B)break;//退出输入模式elseif(Char1='\b'){//处置退格命令}elseif(Char1='\r')continue;//\r跳过不处置,只处置\nelseif(Char1='\n'){//处置换行}elseif(ISPRTCHAR(Char1))//是可打印字符Shell_PutChar(Char1);else{//其它操纵字符不处置,显示一个空格Shell_PutChar('\x20');}}else{if(!ISDBCS1(Char1))break;//是不是DBCS的低字节else{Char2=Uart_GetChar();if(!ISDBCS1(Char1))break;//是不是DBCS的高字节DBCSFlag=TRUE;//该标志标明上一个输入是汉字仍是英文,方便删除。CharPos=(DWORD)(((Char2-0xA1)*94+(Char1-0xA1))*32);//计算的字库中的存储位置res=f_open(&HZKFile,(constchar*)FileStr,FA_READ);if(res!=FR_OK)break;res=f_lseek(&HZKFile,CharPos);//移动到点阵存储位置if(res!=FR_OK)break;res=f_read(&HZKFile,(void*)HZArray,32,&ByteRead);if(res!=FR_OK)break;Shell_PutHanzi(HZArray);}}}while(1);通过调试发觉,从串口先送出来的是内码的高字节,然后才是低字节,与我先前的推测相反。我在txt文件中写入了一个“小”字(它的内码是0xD0A1),再用UltraEdit打开,发觉的确是高位在前,也确实是D0在低位。悔改以后,能够在液晶上为所欲为的输出汉字了。缺点:所编写的那个汉字输入函数Shell_PutHanzi是以汉字点阵数组为输入参数,不具有利用的通用性。因此接下来要实现像电话电子书类似的功能,需要改变参数,使它能够以汉字内码作为输入参数,实现汉字显示的通用性。
//从高到低顺次输出一个字节的每位信息
for(bitindex=7;bitindex>=0;bitindex--)
//输出当前字节第bitindix位的值
bitvalue=((bindot[charnum]>>bitindex)&0x1);
if(bitvalue==1)
printf("**");
else
printf(" ");
//printf("%c",bitvalue+'0');
//一行输出完了换行
if((++bitnum%font_size)==0)
return;
欢迎大家提出你们宝贵的意见或建议。
标签:
1、汉字的点阵码
我此刻明白的是:
(1)汉字能够以点阵的形式存储。
(2)液晶能够在屏上画点。
这二者结合起来就能够够在液晶屏上显示汉字。
最简单的方式,能够在程序中事前存储号点阵码的字符,然后要用的时候显示出来。
举个例子,小那个汉字,它的点阵码是如此的:
它对应的点阵字符码是:
0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,
0x01,0x00,0x05,0x40,0x05,0x20,0x09,0x10,
0x09,0x08,0x11,0x04,0x21,0x04,0x41,0x00,
0x01,0x00,0x01,0x00,0x05,0x00,0x02,0x00
共32个字节,其扫描的顺序是从左到右,从上到下。
在显示的时候,再把字符点阵按相同的顺序显示在液晶屏上,就看到了小字。
2、中文文档的存储方式
那么咱们看到的中文文档,它们全数都是存储的这种点阵码吗?
不是的。
汉字在运算机内容实际是存储的一种特定编码。
比如“小”那个字,在文档内咱们在对应位置看到的可能是“D0A1”,也可能是“5C0F”,也确实是能够有不同的编码表示“小”那个汉字,这确实是汉字的编码方式。
我此刻听过的概念有:
区位码、国标码、内码、unicode、UTF-8,还有GBK、GB2312(这两个仿佛与国标码是相关的,具体怎么对应,我的明白得还不是很清楚)。
除UTF-8适合在网络上传输,那个地址不管它。
其它几种编码方式都是16位的,其大致关系如下:
内码=国标码+0x80;国标码=区位码+0x20;
国标码=GB2312;GBK仿佛是国标码的最新扩展。
汉字在运算机内部文档里面一样是之内码的形式存储。
而文件系统里中文文件名一样以unicode编码的形式存储。
以上这些明白得不知对不对?
再去XX一下加深对这些概念的明白得。
GB2312、GBK都是中文的内码,GB18030仿佛是最新的扩展(还包括了少数名族的字符),Big5是繁体汉字的内码。
嵌入式系统上一样用GB2312就好了。
“D0A1”确实是:
“小”的内码,是一种GB2312码,固然由于GBK、GB18030的继承性,一样的汉字其编码是一样的。
3、中文字库的作用
当运算机程序读取一个中文文档时,它读到的是内码,什么缘故能够在屏幕上显示其字形呢?
方式是在运算机内部存储了一个汉字字库,存储了大部份汉字的字形点阵。
而且关于每一个汉字来讲,它在字库里点阵的位置与其内码存在着一一对应关系。
也确实是说只要明白了内码,就能够够在字库文件里找到其点阵码,然后进行显示。
GB2312型的内码是通过以下的换算找到其在字库中的位置的,以“小”字为例:
它的内码是“D0A1”,别减去“A0A0”取得其区位码,“3001”。
字库的组织方式确实是依照区位码排列的,在0x30区,序号29,每一个区94个汉字,一次其序号为:
(0x30-1)*94+(01-1)。
固然从字节的存储位置来讲,还要乘以32,(每一个汉字16*16点阵,占据32个字节),综合起来,公式能够写成:
CharPos=((NH-0xA1)*94+(NL-0xA1))*32。
我此刻也不能完全确认这确实是对的,我在网上下了UCDOS的HZK16文件,专门快就要编写一个测试程序来查验。
4、咱们在键盘上是怎么样输入汉字的
事实上咱们在键盘上的“键入组合”,在“中文输入法”的干与下,将被转换为内码。
仿佛有的时候,这种键入组合也能够称之为外码。
比如,咱们怎么样在键盘上输入汉字“小”呢?
以最经常使用的拼音输入法为例,咱们要一次键入“xiao”四个字符,那个应该就叫做“外码”,那时起主导作用的输入法通过“查表”或“其它算法”,将那个组合方式转变成了“小”字的内码“D0A1”存储在文件内,或在运算机上传输。
比如串口,你输入“小”的时候,串话柄际发出的是“A1”,“D0”。
(小端字节应该是如此发的吧)。
5、第一个测试程序的计划
添加一个命令mctest,STM32开发同意到那个命令后,等待串口终端的输入。
假设输入一个汉字,那么命令处置程序打开汉字库文件,找到点阵码,在液晶上显示汉字。
假设输入英文字符,也要能显示英文。
当按下“ESC”键的时候,命令处置程序退出。
1、程序框架的修改
我编写程序都是积存式的,以前曾经编写过五个按键输入、液晶作为显示终端的命令输入界面。
那个界面一直是有效的,此刻汉字显示要利用液晶屏,因此要通过一些修改。
修改的地址如下:
(1)主程序占用了液晶的一行,写液晶的那句话注释掉。
//Shell_PutStrPC(0,0,Str,Yellow,Black);//不要占据屏幕了
(2)键盘、液晶命令界面的主任务删除掉。
实际确实是不创建那个任务了。
//OSTaskCreate(Task_CmdShell,(void*)0,&Task_CmdShellStk[TaskStk_Size-1],Task_CmdShell_Prio);
//该任务临时不需要了。
(3)在键盘扫描任务中,使读键子程序老是返回0(不管有无按键)
KeyCurrent=GetKeyState();//老是返回0
(4)在无按键输入处置流程中,将关闭液晶显示的指令去掉
因为在以前的程序中,当一分钟左右没有按键输入的时候,系统会自动关闭液晶显示(模拟电话的模式),此刻要注释掉。
//DisplayOn=0;//不要关闭屏幕
//LCD_DisplayOff();
再次编译下载,成功。
液晶此刻能够自由利用了。
2、mctest命令处置程序框架的编写
修改支持命令个数的常数、添加命令字符串、初始化命令表的新命令、在输入命令文件中添加新命令、在Help命令处置程序中添加新命令显示、写新命令函数概念(临时空着),编译下载,一个新的命令就添加成功了。
这次又要支持很多的命令,故工程中新增加一个文件,用于处置多媒体相关的命令。
3、mctest命令处置程序内容的设计
处置程序进入一个循环,不断的接收从串口过来的字符。
若是是“ESC”键按下(0x1B),那么跳出循环。
概念一个标志字符,当接收到ESC时,设置标志为1。
采纳dowhile循环结构。
概念两个字符变量,接收一个字符后进行判定。
若是小于0x80,说明是一般的ascii码,进行相应处置。
若是大于0x80,判定是不是DBCS的第一个字节。
接收第二个字节,同时判定是不是DBCS第二字节,若是知足条件,计算出对应汉字在字库文件中对应的存储位置。
打开字库文件,定位到存储位置,读取32个字节存入缓冲区。
然后挪用液晶显示程序显示汉字。
do{
Char1=Uart_GetChar();//那个字符是从串口字符队列中取得的。
if(Char1<0x80){
if(Char1==0x1B)break;//退出输入模式
elseif(Char1='\b'){//处置退格命令
elseif(Char1='\r')continue;//\r跳过不处置,只处置\n
elseif(Char1='\n'){//处置换行
elseif(ISPRTCHAR(Char1))//是可打印字符
Shell_PutChar(Char1);
else{//其它操纵字符不处置,显示一个空格
Shell_PutChar('\x20');
else{
if(!
ISDBCS1(Char1))break;//是不是DBCS的低字节
Char2=Uart_GetChar();
ISDBCS1(Char1))break;//是不是DBCS的高字节
DBCSFlag=TRUE;//该标志标明上一个输入是汉字仍是英文,方便删除。
CharPos=(DWORD)(((Char2-0xA1)*94+(Char1-0xA1))*32);//计算的字库中的存储位置
res=f_open(&HZKFile,(constchar*)FileStr,FA_READ);
if(res!
=FR_OK)break;
res=f_lseek(&HZKFile,CharPos);//移动到点阵存储位置
res=f_read(&HZKFile,(void*)HZArray,32,&ByteRead);
Shell_PutHanzi(HZArray);
}while
(1);
通过调试发觉,从串口先送出来的是内码的高字节,然后才是低字节,与我先前的推测相反。
我在txt文件中写入了一个“小”字(它的内码是0xD0A1),再用UltraEdit打开,发觉的确是高位在前,也确实是D0在低位。
悔改以后,能够在液晶上为所欲为的输出汉字了。
缺点:
所编写的那个汉字输入函数Shell_PutHanzi是以汉字点阵数组为输入参数,不具有利用的通用性。
因此接下来要实现像电话电子书类似的功能,需要改变参数,使它能够以汉字内码作为输入参数,实现汉字显示的通用性。
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2