用Ruby和HZK16字库进行字模提取

又是5.1小长假(3天也叫假?!)。在宿舍补觉之余觉得万般无聊,于是准备把之前一直想做的字模提取的软件做了(主要原因还是之前接触到的12864的字模数据写入方式比较奇葩)。鉴于平时只写过C,而C写GUI简直坑爹。最后挑了个时髦的Ruby从头学学,而且貌似用Shoes做GUI还是挺惬意的样子。

这片短文大致记录一下字模提取的过程。

使用的是UCDOS这个时代的眼泪里自带的16x16点阵字库,从网上简体繁体都能下载到,关键词是HZK16和HZK16F。话说google一下首页都没有UCDOS的官方信息...果然是时代的眼泪么...

大致提取过程也很简单,就是计算一下偏移量(计算的过程网上一搜一大堆,就是计算一下和0xA1A1之间的相对位置关系,而之所以是0xA1A1是因为GB2312从0xA1A1开始),然后连着读取32个字节(16*16/8)存到数组里用16进制输出一下。代码如下所示。

str = "码".encode("gb2312")
arr = []
code = []

str.each_byte {|b| arr<< b}
offset = (arr[0]*94+arr[1]-15295)*32
print "offset:"
puts offset

f = File.new("HZK16")
#if traditional Chinese character is needed
#f = File.new("HZK16F")
f.seek(offset)
print "file pointer position:"
puts f.pos

for i in 0..31
	code[i] = f.getbyte		#code[i] type: string
    #code[i] = f.getc
	print code[i].to_s(16)
	#print code[i].unpack("H*")     #cant split A5FE
	print "tt"
	puts i
end

f.close
sleep

中间碰见的一个问题就是一开始是用f.getc来逐个字节获取字模的,但是不知道为什么第9行的数据0xA5和0xFE会被同时读出来,输出个0xA5FE。导致会把下一个字的字模的第1个数据读出来附到最后,导致无法正常显示。

最后也没找到原因,还是使用getbyte替代了getc来读取字节。

附上最后的输出结果(傻乎乎手动在其他人的字模软件中点亮的...),以后再抽时间把字模的其他的排列方式和GUI写了吧...目前GUI决定用ImageMagick和shoes来搞...到时候再记录吧。