原创 工具软件之字模提取(一)

2008-12-29 15:42 6796 10 10 分类: 软件与OS

     使用MCU控制点阵LCD时,由于一般的LCD驱动IC不带有字库,需要将即将显示的汉字的字模从标准字库中提取出来,并且需要按照对应的取模方式。现如今的网络资源庞大,即便是制造原子弹,也可以从网络上找到相应的参考资料,像这样的工具软件网络上自然是有很多的免费/收费版本可供选择,C51BBS的版主便编写有这样的软件在网上卖,也有很多免费的软件。


    因为偶然的情况,下载的字模提取软件生成的字模中间有一条黑线(免费试用过期以后,崔款通知),很是不爽,便自己收集字模提取的技术材料,用VB写了个小工具,由于代码中只有一种字模提取方式,也不便分享流传,所以在blog上记录字模提取的方法和步骤,以便以后应急之用。


    字模提取比较简单的办法有两种,一种是通过使用DOS下的通用字库hzk16,另一种通过提取显示区域的像素点的RGB值自己换算。这个日记记录第一种方法的具体步骤。HZK16文件是一个DOS系统下的字库文件,里面包含有GB2312种对应汉字的字库(字模),但是这个文件比较大有200kb多,一般的MCU不能提供如此大的ROM来存放完整的HZK16文件,而且取模方式和一般的LCD的扫描方式不同,所以需要进行字库提取和转换。


1、字库提取和转换的步骤如下:


(1)、取得汉字的GB2312编码,比如说汉字“我”的GB2312编码为0xCED2, 52946,其中高字节用Hbyte=0xCE表示,低字节用Lbyte=0xD2表示


(2)、计算汉字“我”在HZK16中的偏移量。公式:偏移量LocationOffset=[(Hbyte-0xA1)*94+(Lbyte-0xA1)]*32+1,以“我”为例 LocationOffset="0x216e1"


(3)从HZK16文件的位置LocationOffset处读出32个字节数据,这32个数据便是字库数据,如果需要进行取模方式转换,还要加入转换取模方式的算法。


(4)一般的单片机系统的字库用source code的方式保存的,所以还要将字库数据变成sorcecode的数组定义,汇编用(DB XX)


2、VB实现字模提取


如图1所示,为VB实现字库提取的界面


点击看大图


新建一个单form的工程,在form添加两个textbox控件text1和text2,和一个button控件command1,然后添加下面的代码


Dim hzbyte(0 To 31) As Byte
Dim fzByte(0 To 31) As Byte
Private Sub Command1_Click()
On Error GoTo err
'Dim hanzi As String
'Dim zimo As String
'Dim zimoArr(32) As Integer
Dim txtStr As String
Dim P(1 To 2) As Byte
Dim LoCation As Long


Dim C1, C2
'Dim tempFile As String
Dim HzFilepath As String
'Dim tempSrcFile As String
'Dim TempDestFile As String
Dim tempFilepath As String
Dim txtLen As Integer
Dim j As Integer
Dim path As String
If Me.Text1.Text = "" Then Exit Sub
tempFilepath$ = App.path & "\" & "tempfile.txt"
HzFilepath = App.path & "\" & "hzk16"
txtLen = Len(Trim$(Me.Text1.Text))
Dim str As String
Open tempFilepath For Output As #1
Print #1, Trim$(Me.Text1.Text)
Close #1
str = "//一共输入" & CStr(txtLen) & "个汉字" & Chr(13) & Chr(10)
For j = 0 To txtLen - 1
    str = str & Chr(13) & Chr(10)
    Open tempFilepath For Binary Access Read As #1
    Get #1, (2 * j + 1), P
    Close #1
    C1 = CStr(P(1)) - &HA1
    C2 = CStr(P(2)) - &HA1
    Dim rec As Integer
    rec = C1 * 94 + C2
    LoCation = CLng(rec) * 32 + 1
    'path = App.path & "\" & "hzk16"
    Open HzFilepath For Binary Access Read As #1 ' Len = 32
    Get #1, LoCation, hzbyte
    Close #1
    'fanzhuan
    Dim i As Integer
    Dim s As String
    s = Left$(Me.Text1.Text, j + 1)
    s = Right$(s, 1)
   
    str = str & Chr(13) & Chr(10)
    str = str & "unsigned char code hanzi_" & C1 & C2 & "[]=" & Chr(13) & Chr(10)
    str = str & "//第" & CStr(j) & "个字的字吗:" & s & Chr(13) & Chr(10)
    str = str & "{"
    For i = 0 To 31


        If Len(Hex(hzbyte(i))) = 1 Then
            str = str & "0x0" & Hex(hzbyte(i)) & ","
'End If
        Else
            str = str & "0x" & Hex(hzbyte(i)) & ","
        End If
 
'Debug.Print " "
        If i = 15 Then
            str = str & Chr(13) & Chr(10)
        End If


'去模方向————〉
'|
'|
'V


    Next i
    str = str & "};"
Next j
   
Me.Text2.Text = str


 



Exit Sub
err:
MsgBox err.Description



End Sub


Function fanzhuan()
Dim temp As Byte
'/temp = 1
Dim i As Integer
For i = 0 To 31
fzByte(i) = 0
Next i
Dim j As Integer
For j = 0 To 7
    For i = 0 To 7
        fzByte(j) = fzByte(j) + getxnbit(hzbyte(i * 2), j) / twoxf(7 - i)
        fzByte(j + 8) = fzByte(j + 8) + getxnbit(hzbyte(i * 2 + 1), j) / twoxf(7 - i)
        fzByte(j + 16) = fzByte(j + 16) + getxnbit(hzbyte(16 + i * 2), j) / twoxf(7 - i)
        fzByte(j + 24) = fzByte(j + 24) + getxnbit(hzbyte(17 + i * 2), j) / twoxf(7 - i)
    Next i
Next j


 



End Function
Function RLC(x As Byte) As Integer
Dim temp As Integer
Dim c As Integer
c = 0
temp = x
temp = temp * 2
If temp >= 128 Then
c = 1
End If
RLC = c


End Function
'Function RRC(x As Byte) As Integer
'Dim temp As Integer
'Dim c As Integer
'c = 0
'temp = x
'If (x Mod 2) > 0 Then
'c = 1
'End If
'RRC = c


'End Function
Function getxnbit(x As Byte, n As Integer) As Byte


Dim temp As Integer
Dim ret As Integer
Dim i As Integer


ret = 256
temp = x
For i = 0 To n
temp = temp * 2
ret = ret / 2
If i = n And temp >= 256 Then
    'getxnbit = ret
    getxnbit = 128
    Exit For
End If
temp = temp Mod 256
Next i
End Function


 


然后把文件HZK16拷贝到代码指定的路径,便可以运行了。


3 说明代码中取得汉字内码的方法是先将text1控件的汉字保存到一个临时文件tempfile.txt中,然后再从文件中以二进制的方式读取。代码没有添加提取方式转换的算法,使用的是HZK16的默认的取模方式。


 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
10
关闭 站长推荐上一条 /3 下一条