logo资料库

JAVA汉字字库及字模提取程序实现.doc

第1页 / 共6页
第2页 / 共6页
第3页 / 共6页
第4页 / 共6页
第5页 / 共6页
第6页 / 共6页
资料共6页,全文预览结束
JAVA汉字字库及字模提取程序实现
JAVA 汉字字库及字模提取程序实现 研究使用 LED 显示屏显示汉字时,编写了这个使用 Java 语言从汉字字库里提取所需要 的字模数据。实现这个程序主要玩成以下的步骤就行: 在这里先说说这个程序的核心部分就是汉字字库。汉字字库文件有很多,如:HZK16S 为宋体,HZK16F 为仿宋,HZK16H 为黑体,HZK16K 为楷体,HZK16Y 为幼圆,HZK16L 为隶书 等,本文采取的字库文件是 HZK16。 HZK16 字库是符合 GB2312 标准的 16×16 点阵字库,GB2312-80 支持的汉字有 6763 个, 符号 682 个。其中一级汉字有 3755 个,按声序排列,二级汉字有 3008 个,按偏旁部首排 列。同时 HZK16 是一个二进制文件,一般程序是难以打开的,不过 Java 有可以打开二进制 文 件 的 方 法 , 那 就 是 “FileInputStream ”。 当 然 Java 里 除 了 “FileInputStream ” 外 还 有 “FileReader”,但两者是有区别的,“FileInputStream”是用于读取二进制数据(以字节流方 式),“FileReader”是用于读取文本数据(以字符流形式,即 Unicode 字符)。所以本文采用 FileInputStream。 FileInputStream fileIn = new FileInputStream(HZK16);//打开 HZK16 文件 到这里已经 HZK16 文件,但如果要显示文件内容,内容是一连串整型数据(十进制), 这是因为 Java 系统自动把一个字节的二进制数据转为十进制,如果想要得到十六进制数据 还需要一些操作。 首先要定义一个一维数组 ZiMo16: byte[] ZiMo16 = new byte[(int)file.length()]; ZiMo16,file.length()是获取 HZK16 文件的长度(大小) file = new File(HZK16); fileIn.read(ZiMo16); //把读取出来的数据存进 ZiMo16 数组里 //新建文件,这句是要放在前面 // 创 建 临 时 数 组 此时 ZiMo16 数组里已经有 HZK16 所有数据,这样就可以对其进行数据的截取,例如根 据输入汉字的区位码进行截取 32 个数据。 说到要得到输入文本的内容,就需要新建一个“Scanner”流: Scanner scan = new Scanner(System.in); //新建文本输入流 System.out.println("请输入:");
String str; str = scan.nextLine(); 然后就是获取汉字的区位码: add = getAddress(strarray[i]); 因为这里我为了节省代码长度,已经把获取区位码和获取首地址写成一个函数。 //输入汉字字符 //逐个汉字调用地址偏移量函数 public static int getAddress(String str0) throws IOException{ 获取地址(偏移量)函数 // int quCode = 0; int weiCode = 0; int Address = 0; String quweiCode = "";//定义字符型区位码 byte[] chineseByte = str0.getBytes("GBK");//将输入的中文字 //定义区码 //定义位码 //定义偏移量地址 符转为 GBK 码(byte 类型) for(int i = 0;i < chineseByte.length;i++){ int a =Integer.parseInt(bytes2HexString(chineseByte[i]),16); //把获得的 GBK 码转十六进制再转为十进制(因为 GBK 码是带符号, 需要转为不带符号整型才可以进行十六进制运算) quweiCode = (a - 0xA0)+""; switch(i){ case 0: quCode = Integer.parseInt(quweiCode);//获得 case 1: weiCode = Integer.parseInt(quweiCode);//获 整型区码 得整型位码 } } System.out.print("区位码是:"); System.out.print(quCode+"\t"); System.out.println(weiCode); Address = 32 * ((quCode - 1) * 94 + (weiCode - 1)); System.out.print("地址是:"); System.out.println(Address); return Address; } 有了首地址就可以在 HZK16 提取输入汉字字符相应的字模数据。 //逐个汉字调用地址偏移量函数 add = getAddress(str); System.out.println(str); //显示输入汉字的首地址 for(int i = 0;i < 32;i++){ ZiMo[i] = ZiMo16[add+i]; ZiMoStr[i] = hexByte(ZiMo[i]); 十六进制 System.out.print(ZiMoStr[i]+" "); //输出 //按要求截取 ZiMo16 里 32 个数据 //将 byte 型十进制转为 String
if((j+1)%10==0) System.out.println();//每十个数据就换行 } ZiMo[i]是前面定义的一个数组。 byte ZiMo[] = new byte[32];//定义汉字存储字模二维数组 到这里已经完成边这个程序目的。 完整的程序实例(只限提取单个字符): import java.util.Scanner; import java.util.Timer; import java.util.TimerTask; import java.io.FileInputStream; import java.io.IOException; import java.io.File; public class transform { public static String bytes2HexString(byte abyte) { //将 byte 类型数据转为字符串 return bytes2HexString(new byte[] {abyte}); } public static String bytes2HexString(byte[] bytes) { //将整 型数据转为十六进制字符型数据,String 是字符串类 String ret = ""; for(int i = 0;i < bytes.length;i++) { String hex = Integer.toHexString(bytes[i]&0XFF);//将输 进的十进制数据转为十六进制字符型数据 if(hex.length()==1){ hex = "0"+hex; } ret += hex.toUpperCase(); //System.out.println(hex); } return ret; } private static String hexByte(byte abyte) { //byte 类型的十 进制转为 String 类型的十六进制 String hexstr0 = "0"+Integer.toHexString((int)abyte); String hexstr = hexstr0.substring(hexstr0.length()-2); return hexstr; } public static String[] stringToStringArray(String str2) { // 把 String 转 String[] String[] strArry = new String[str2.length()];
for(int i = 0;i < str2.length();i++) { strArry[i] = str2.substring(i,i+1); } return strArry; } public static int getAddress(String str0) throws IOException{ //获取地址(偏移量)函数 int quCode = 0; int weiCode = 0; int Address = 0; String quweiCode = "";//定义字符型区位码 byte[] chineseByte = str0.getBytes("GBK");//将输入的中文字 //定义区码 //定义位码 //定义偏移量地址 符转为 GBK 码(byte 类型) for(int i = 0;i < chineseByte.length;i++){ int a =Integer.parseInt(bytes2HexString(chineseByte[i]),16); //把获得的 GBK 码转十六进制再转为十进制(因为 GBK 码是带符号, 需要转为不带符号整型才可以进行十六进制运算) quweiCode = (a - 0xA0)+""; switch(i){ case 0: quCode = Integer.parseInt(quweiCode);//获得 case 1: weiCode = Integer.parseInt(quweiCode);//获 整型区码 得整型位码 } } System.out.print("区位码是:"); System.out.print(quCode+"\t"); System.out.println(weiCode); Address = 32 * ((quCode - 1) * 94 + (weiCode - 1)); System.out.print("地址是:"); System.out.println(Address); return Address; } public static void main(String[] args) { // TODO Auto-generated method stub String fileName = "HZK16X"; //String fileName = "word.txt"; Scanner scan = new Scanner(System.in); //新建文本输入流 System.out.println("请输入:"); String str = scan.nextLine(); //输入汉字字 符 String[] strarray = new String[str.length()];
int add; //byte hanzinum = getHanZiNum(str); //定义地址位移偏量 //获取汉字字符串 长度; //定义文件长度 long fileLength; byte ZiMo[] = new byte[32];//定义汉字存储字模数组 String[] ZiMoStr = new String[32]; boolean bool = false; File file = null; try { file = new File(fileName); FileInputStream fileIn = new //新建文件 FileInputStream(fileName);//打开 HZK16C 文件 bool = file.exists(); //判断文件是否存 在 if(bool){ fileLength = file.length(); int len = new Long(fileLength).intValue(); //把 long byte[] ZiMo16 = new byte[(int)file.length()]; //创 型的 fileLength 转为 int 型的 len 建临时数组 ZiMo16 fileIn.read(ZiMo16); add = getAddress(str); 移量函数 for(int i = 0; i < 32 ;i++){ ZiMo[i] = ZiMo16[add+i]; 取 ZiMo16 里 32 个数据 型十进制转为 String 十六进制 ZiMoStr[i] = hexByte(ZiMo[i]); //调用地址偏 //按要求截 //将 byte System.out.print(ZiMoStr[i]+" "); //输出 if((i+1)%10==0) System.out.println();//每十 个数据就换行 } System.out.println(); System.out.println("file length:"+fileLength); } scan.close();//关闭 Scanner 流 fileIn.close();//关闭 FileInputStream 流 } catch (Exception e) { e.printStackTrace(); }
} } 如果想实现多个汉字字模数据提取,只要把装载 32 个字模数据的 ZiMo 数组该 为二维数组,再对源程序稍作修改便可。
分享到:
收藏