搜索
bottom↓
回复: 136

[资料]GBK字库及其与unicode间的转换(用于mp3文件名的显示)

[复制链接]

出0入0汤圆

发表于 2007-1-12 18:57:47 | 显示全部楼层 |阅读模式
经过几天的摸索终于可以显示mp3的中文名了。

现在将我做的资料与大家分享,想做mp3的朋友可以试试。

点击此处下载armok01141262.rar

上面的文件是我在网上搜索的素材,我自己编了些小程序将其转换成两张表,即unicode与gbk相互转换的表。

点击此处下载armok01141263.rar

上面是我用程序产生的GBK字符,是按照顺序存放的,用这个文件配合我前几天发的“GB2312字库制作方法”中的程序用于生成GBK字库点阵。

点击此处下载armok01141264.rar

上面的文件是我最终生成的用于mp3的4个文件了。



st12.sys为gbk字库12*12的点阵文件,取模方式 “纵向取模,高位在下”(我用的液晶是128*64   ks0108兼容LCD模块)

st16.sys为gbk字库16*16的点阵



以上两个文件的起始汉字是以0x8140 开始的,为了在程序中能线形查找,其中不存在的编码 如0x**7f 0x**ff等均在编码内,只不过不会用到。也就是说从0x8140 ~0xfeff 其中高位从0x81到0xfe 地位从0x40到0xff 即126*192 = 24192个汉字数据。

因此12*12的点阵文件大小是580608Bytes (每个汉字用24字节,汉字下半截虽用4bits但是存储是按8bits)

16*16的点阵文件大小是774144Bytes(每个汉字用32字节)



uni2gbk.sys为unicode转gbk的表,从unicode的0x4e00 到0x9fa5 顺序存放着相应的gbk码,总共20902个汉字,对应的文件是41804Bytes

注:由于没有找到一些符号的unicode对照表,因此这张表中只包含了汉字部分。因此不能显示诸如“”()等符号,程序中要做相应处理。

注文件存放方式是高字节在前 比如0x4e00 存放方式为0x4e 0x00



gbk2uni.sys为gbk转unicode的表,从gbk的0x8140 到0xfeff 即126*192 = 24192按照gbk的编码顺序放,为了线形查找,其中不合法的或根据资料没有相应unicode码的都作了填零处理。文件大小为48384Bytes

注文件存放方式是高字节在前 比如0x4e00 存放方式为0x4e 0x00



用的时候要把上面的4个文件拷贝到sd卡中或u盘中,注意为了程序好处理不要让这4个文件产生碎片,要连续的存放,最好的方法是格式化后再把这几个文件拷过去。



下面说说如何在程序中处理



首先是初始化:

#include"LCD_GBK.h"



unsigned long GBK12,GBK16,GBK2UNI,UNI2GBK;//用于存放四个文件的起始扇区

extern unsigned long FirstDataSector;//第一个数据扇区

extern unsigned int SectorsPerClust;//每簇扇区数

extern unsigned int  BytesPerSector;//每扇区字节数



unsigned char GBK_Buffer[32];//单个汉字点阵数据缓冲



unsigned char GBK_Ini()//gbk初始化

{

        GBK12 = FAT_Open("\\st12.sys");//打开文件,得到簇号

        if(GBK12 == 1)return 1;

        GBK16 = FAT_Open("\\st16.sys");

        if(GBK16 == 1)return 1;

        GBK2UNI = FAT_Open("\\gbk2uni.sys");

        if(GBK2UNI == 1)return 1;

        UNI2GBK = FAT_Open("\\uni2gbk.sys");

        if(UNI2GBK == 1)return 1;



        //将簇号转成扇区号

        GBK12 = (unsigned long)FirstDataSector+(unsigned long)(GBK12 - 2)*(unsigned long)SectorsPerClust;//calculate the actual sector number

        GBK16 = (unsigned long)FirstDataSector+(unsigned long)(GBK16 - 2)*(unsigned long)SectorsPerClust;//calculate the actual sector number

        GBK2UNI = (unsigned long)FirstDataSector+(unsigned long)(GBK2UNI - 2)*(unsigned long)SectorsPerClust;//calculate the actual sector number

        UNI2GBK = (unsigned long)FirstDataSector+(unsigned long)(UNI2GBK - 2)*(unsigned long)SectorsPerClust;//calculate the actual sector number



        return 0;

}



这样可以得到四个文件的起始扇区,接下来的操作在此基础上加上偏移量就可以了,无须再次寻找文件。

其中FAT_Open("\\st12.sys");//打开文件,得到簇号

该函数实现寻找根目录下st12.sys的起始簇,这个FAT函数可以搜索一下我以前发的帖子,那里有完整的程序。



根据汉字内码找其点阵数据:

unsigned char Read_One_GBK16(unsigned char *ch)

{

        unsigned int  temp1;

        unsigned char temp2;

        unsigned int  sector_offset;//扇区偏移

        unsigned int  byte_offset;//字节偏移

        unsigned char buffer[512];

        temp1=*ch;

        temp2=*(ch+1);

        if(temp1<0x81||temp2<0x40)return 1;//不合法的汉字

        temp1-=0x81;//的到类似于2312的区号

        temp2-=0x40;//位号

        temp1*=192;//xx7f and xxff are included

        temp1+=temp2;//得到偏移

        //temp1*=24;

        sector_offset = temp1/(BytesPerSector/32);//算出要读哪个扇区

        byte_offset = (temp1%(BytesPerSector/32))*32;//算出要读扇区的哪个字节

        if(FAT_ReadSector(GBK16 + sector_offset,buffer))return 1;//读要读的扇区

        for(temp2 = 0,temp1 = byte_offset;temp2<32;temp2++,temp1++)GBK_Buffer[temp2] = buffer[temp1];//复制要复制的数据

        return 0

}

注意由于在设计时非法的编码如0x**7f与0x**ff都计在内所以每个区有192个汉字,而不是190个

这是16*16的程序

12*12的程序稍复杂一点,因为512/24 不能除尽,因此还要判断是不是有数据在下一个扇区。其代码如下(没加注释)

unsigned char Read_One_GBK12(unsigned char *ch)

{

        unsigned long temp1;

        unsigned char temp2;

        unsigned int  sector_offset;

        unsigned int  byte_offset;

        unsigned char buffer[512];

        temp1=*ch;

        temp2=*(ch+1);

        if(temp1<0x81||temp2<0x40)return 1;

        temp1-=0x81;

        temp2-=0x40;

        temp1*=192;//xx7f and xxff are included

        temp1+=temp2;

        temp1*=24;

        sector_offset = temp1/BytesPerSector;

        byte_offset = temp1%BytesPerSector;

        if(FAT_ReadSector(GBK12 + sector_offset,buffer))return 1;

        if(byte_offset>488)

        {

                for(temp2 = 0,temp1 = byte_offset;temp2<(BytesPerSector - byte_offset);temp2++,temp1++)GBK_Buffer[temp2] = buffer[temp1];

                if(FAT_ReadSector(GBK12 + sector_offset + 1,buffer))return 1;

                for(temp1 = 0;temp2<24;temp2++,temp1++)GBK_Buffer[temp2] = buffer[temp1];

        }

        else for(temp2 = 0,temp1 = byte_offset;temp2<24;temp2++,temp1++)GBK_Buffer[temp2] = buffer[temp1];

        return 0;

}



至于显示我就不说了,不同的液晶操作不同,只要把读出的数据按照你的LCD的操作方法写进去即可。



unicode到gbk的转换。

unsigned char Unicode_to_GBK(unsigned char *ch)

{

        unsigned int temp;

        unsigned int sector_offset;//扇区偏移

        unsigned int byte_offset;//字节偏移

        unsigned char buffer[512];

        temp = *((unsigned int*)ch);//由于FAT中文件民unicode码是 地字节在前,所以要按uint型读

        temp -= 0x4e00;//减去基础数据

        temp *= 2;//每个汉字两个字节

        sector_offset = temp/BytesPerSector;//计算出扇区偏移,确定存在哪个扇区

        byte_offset = temp%BytesPerSector;//存在哪个字节

        if(FAT_ReadSector(UNI2GBK + sector_offset,buffer))return 1;//读那个扇区

        *ch = buffer[byte_offset];//将数据读出

        *(ch+1) = buffer[byte_offset+1];

        return 0;

}





要注意的是FAT中文件名的存放方式是低字节在前,而gbk的存放是高字节在前,操作时不要搞混了。



gbk到unicode的转换mp3种用不着所以我也就没试过,程序也没写,因此那四个文件,gbk2uni.sys可以不拷。



由于资料有限unicode的编码只有汉字部分 即所谓的“中日韩统一汉字编码”,(2w多汉字)显示汉字肯定是没问题了,有些符号没有。希望大家去完善一下。



谢谢ouravr的各位朋友!

来几张图片

试验用的板子(已经在这出现好多次了)



显示中文名



阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2007-1-12 19:10:20 | 显示全部楼层
顶下楼主.



PS:  图片效果跟阿莫的有一拼了.

出0入0汤圆

 楼主| 发表于 2007-1-12 19:12:29 | 显示全部楼层
没办法啊,只有手机哪个30万像素的分辨率。如果有完全的30万那也不错。

关键是没有。

出0入0汤圆

发表于 2007-1-12 22:56:51 | 显示全部楼层
这种资料很有价值,谢谢楼主。

出0入4汤圆

发表于 2007-1-13 09:54:51 | 显示全部楼层
Well done!

很喜欢那首 Five Hundred miles 仿佛耳边响起歌声:

If you miss the train I am on

you will know that I am gone

you can hear the whistle blow

A hundred mile

...

出0入0汤圆

发表于 2007-1-13 13:06:55 | 显示全部楼层
谢了

出0入0汤圆

发表于 2007-8-31 10:12:45 | 显示全部楼层
那请问一下楼主,你的12864是用5V驱动的啊,可是VS1003与SD卡分别是要3.3V,2.5V使用的,你是如何解决AVR的供电问题,谢!

出0入0汤圆

发表于 2007-9-2 12:49:47 | 显示全部楼层
谢谢楼主的哦,已经利用楼主的字库用3310,SD卡,M16显示出汉字了,谢谢的哦,感谢!

出0入0汤圆

发表于 2007-9-2 18:30:45 | 显示全部楼层
太好的,多谢楼主

出0入0汤圆

发表于 2007-9-3 16:43:00 | 显示全部楼层
这么好的资料,收藏着。谢谢楼主!

出0入0汤圆

发表于 2007-12-12 20:53:43 | 显示全部楼层
轻轻的把你顶起来。

出0入0汤圆

发表于 2007-12-13 14:10:31 | 显示全部楼层
这就是我想要的,,楼主做出来了,顶!!!

出0入0汤圆

发表于 2008-1-20 00:20:09 | 显示全部楼层
用什么软件转换和,又用生成卡里字库的呢?

出0入0汤圆

发表于 2008-1-20 12:26:58 | 显示全部楼层
留个记号。。

出0入0汤圆

发表于 2008-4-30 23:56:25 | 显示全部楼层
留个脚印

出0入0汤圆

发表于 2008-5-6 22:44:33 | 显示全部楼层
超cool

出0入0汤圆

发表于 2008-5-8 15:19:51 | 显示全部楼层
Cool

出0入0汤圆

发表于 2008-5-9 09:47:24 | 显示全部楼层
MARK

出0入0汤圆

发表于 2008-5-21 14:39:50 | 显示全部楼层
注:由于没有找到一些符号的unicode对照表,因此这张表中只包含了汉字部分。因此不能显示诸如“”()等符号,程序中要做相应处理。


word 中可以看出对应关系!

出0入0汤圆

发表于 2008-7-3 23:26:20 | 显示全部楼层
佩服啊!向你学习。

出0入0汤圆

发表于 2008-8-13 14:16:31 | 显示全部楼层
留个痕,谢谢!

出0入0汤圆

发表于 2008-8-14 08:43:21 | 显示全部楼层
学习!
佩服!

出0入0汤圆

发表于 2008-8-14 08:45:37 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-8-14 11:08:06 | 显示全部楼层
谢谢楼主!收藏!

出0入0汤圆

发表于 2008-8-15 20:23:20 | 显示全部楼层
收藏了

出0入0汤圆

发表于 2008-8-15 21:01:40 | 显示全部楼层
3QU!

出0入0汤圆

发表于 2008-8-15 21:19:35 | 显示全部楼层
好东西一定要顶

出0入0汤圆

发表于 2008-8-21 10:21:01 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-1-1 15:38:56 | 显示全部楼层
刚好用到。。谢谢楼主

出0入0汤圆

发表于 2009-1-4 09:53:56 | 显示全部楼层
支持波仔~~

出0入0汤圆

发表于 2009-1-5 23:30:19 | 显示全部楼层
mark&nbsp;

出0入0汤圆

发表于 2009-1-6 11:09:25 | 显示全部楼层
很好很强大,lz牛。

做个记号。

出0入0汤圆

发表于 2009-1-6 11:17:58 | 显示全部楼层
谢谢楼主!致敬!

出0入0汤圆

发表于 2009-1-6 11:19:03 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-1-6 12:06:34 | 显示全部楼层
好东西,可惜我现在还不会,先做个标记把

出0入0汤圆

发表于 2009-4-11 17:15:26 | 显示全部楼层
GBK字库及其与unicode间的转换(用于mp3文件名的显示)

出0入0汤圆

发表于 2009-4-11 20:50:50 | 显示全部楼层
收藏,谢谢!

出0入0汤圆

发表于 2009-4-14 22:30:54 | 显示全部楼层
mark!

出0入0汤圆

发表于 2009-4-19 20:48:33 | 显示全部楼层
摁个记号.

出0入0汤圆

发表于 2009-4-19 20:57:36 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-5-26 11:39:36 | 显示全部楼层
学习中!

出0入0汤圆

发表于 2009-5-26 12:15:12 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-5-26 12:40:16 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-6-1 20:43:21 | 显示全部楼层
前段时间刚做了字库,可惜没早看到LZ的好帖子,哎,写的那么详细,资料又那么全~~O(∩_∩)O~

出0入0汤圆

发表于 2009-6-17 22:35:29 | 显示全部楼层
太牛了!

出0入0汤圆

发表于 2009-7-10 15:51:28 | 显示全部楼层
牛人

出0入0汤圆

发表于 2009-8-8 19:59:51 | 显示全部楼层
牛人!不得不顶~

出0入0汤圆

发表于 2009-8-19 08:50:55 | 显示全部楼层
强啊

出0入0汤圆

发表于 2009-9-25 12:01:00 | 显示全部楼层
不顶不行哦  哈哈 !!

出0入0汤圆

发表于 2009-9-25 12:43:46 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-9-27 19:47:39 | 显示全部楼层
记号

出0入0汤圆

发表于 2009-10-22 20:32:49 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2009-11-22 20:36:28 | 显示全部楼层
谢谢分享 ,mark

出0入0汤圆

发表于 2009-11-25 20:08:18 | 显示全部楼层
mark~~留着以后好好看看

出0入0汤圆

发表于 2009-12-4 21:35:15 | 显示全部楼层
虽然现在看不明白,但是有这么么多人顶,我想一定是重量级资料,所以mark~~留着以后好好看看!

出0入0汤圆

发表于 2009-12-4 22:45:00 | 显示全部楼层
mark 高手啊

出0入0汤圆

发表于 2010-1-1 18:04:37 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-1-9 18:39:41 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-1-27 15:40:00 | 显示全部楼层
在unsigned char Read_One_GBK12(unsigned char *ch)
函数中temp1*=192;                           //xx7f and xxff are included
      temp1+=temp2;                         //得到偏移

这偏移是根据什么公式计算的呢?

出0入0汤圆

发表于 2010-1-27 16:30:48 | 显示全部楼层
中文短信发送也用到Unicode吧

出0入0汤圆

发表于 2010-1-27 22:07:23 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-2-12 12:59:14 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-3-11 20:59:09 | 显示全部楼层
mark……

出235入235汤圆

发表于 2010-3-17 15:38:14 | 显示全部楼层
mark!

出0入0汤圆

发表于 2010-3-19 09:24:44 | 显示全部楼层
谢谢波仔前辈!

出0入0汤圆

发表于 2010-3-30 10:13:44 | 显示全部楼层
MARK  UP!

出0入0汤圆

发表于 2010-4-22 14:51:47 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-4-22 16:11:52 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-6-1 16:39:17 | 显示全部楼层
很好很强大

出0入0汤圆

发表于 2010-8-16 21:05:54 | 显示全部楼层
MARK 谢谢

出235入235汤圆

发表于 2010-8-18 13:30:11 | 显示全部楼层
make!

出235入235汤圆

发表于 2010-8-19 11:42:06 | 显示全部楼层
make!

出0入0汤圆

发表于 2010-8-30 11:46:51 | 显示全部楼层
好东西 mark下

出0入0汤圆

发表于 2010-8-30 12:10:00 | 显示全部楼层
暂未用到,好东东,mark

出0入0汤圆

发表于 2010-8-30 12:13:03 | 显示全部楼层
正需要

出0入0汤圆

发表于 2010-8-30 12:40:17 | 显示全部楼层
马克

出0入0汤圆

发表于 2010-8-30 13:31:02 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-9-4 20:20:03 | 显示全部楼层
关注,关注

出0入0汤圆

发表于 2010-9-8 14:24:40 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-9-18 22:06:51 | 显示全部楼层
Bozai你好,想问一下你的MP3的最大码率可以达到多少?可以播放WAV文件么

出0入0汤圆

发表于 2010-9-19 23:42:21 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-22 21:59:56 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-22 23:01:38 | 显示全部楼层
mark@!~

出0入0汤圆

发表于 2010-12-13 22:18:07 | 显示全部楼层
波仔V5

出0入0汤圆

发表于 2010-12-27 22:39:36 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-1-11 16:52:36 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-3-4 17:40:38 | 显示全部楼层
学习

出0入0汤圆

发表于 2011-4-2 11:15:23 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-2 12:19:27 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-4-2 13:04:38 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-3 12:38:00 | 显示全部楼层
好资料必须要顶!

出0入0汤圆

发表于 2011-4-6 16:31:17 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-6 17:23:58 | 显示全部楼层
看看,正在做这方面的东西

出0入0汤圆

发表于 2011-4-7 10:25:24 | 显示全部楼层
MARK

出0入112汤圆

发表于 2011-4-7 11:58:22 | 显示全部楼层
高手!

出0入0汤圆

发表于 2011-4-7 16:16:57 | 显示全部楼层
强悍!!1

出0入0汤圆

发表于 2011-4-8 09:17:24 | 显示全部楼层
慢慢看

出0入0汤圆

发表于 2011-4-9 01:01:18 | 显示全部楼层
先收藏了,呵呵

出0入0汤圆

发表于 2011-4-9 05:57:43 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-22 17:42:08 | 显示全部楼层
值得研究
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 07:24

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表