mysql unicode转汉字_任意汉字显示,给你的嵌入式系统(含MCU)装上字库
0 引言
還記得通常在MCU驅(qū)動(dòng)LCD,OLED是怎樣顯示漢字的嗎?采用取字模工具,生成字模數(shù)組,然后要顯示某個(gè)字符,直接索引這個(gè)字符的數(shù)組,然后對(duì)這個(gè)數(shù)組數(shù)據(jù)進(jìn)行顯示就行了,就像這樣:
最近有開(kāi)發(fā)一個(gè)物聯(lián)網(wǎng)項(xiàng)目,將網(wǎng)絡(luò)端的發(fā)過(guò)來(lái)的漢字顯示到屏幕上,但問(wèn)題來(lái)了,我還不知道網(wǎng)絡(luò)端要發(fā)送具體哪些漢字,我是無(wú)法對(duì)具體的漢字取模,因此,得想辦法先對(duì)所有漢字進(jìn)行取模,或使用字庫(kù),于是就有了下文。
1 字符編碼
先從字符編碼說(shuō)起:參考阮一峰博客字符編碼
- ASCII碼:一共規(guī)定了128個(gè)字符的編碼,這128個(gè)符號(hào)(包括32個(gè)不能打印出來(lái)的控制符號(hào)),只占用了一個(gè)字節(jié)的后面7位,最前面的一位統(tǒng)一規(guī)定為0。
- 非ASCII碼:英語(yǔ)用128個(gè)符號(hào)編碼就夠了,但是用來(lái)表示其他語(yǔ)言,128個(gè)符號(hào)是不夠的。
- GB2312,GBK,Unicode,UTF-8均為非ASCII編碼
- Unicode碼:如果有一種編碼,將世界上所有的符號(hào)都納入其中。每一個(gè)符號(hào)都給予一個(gè)獨(dú)一無(wú)二的編碼,那么亂碼問(wèn)題就會(huì)消失。這就是 Unicode,就像它的名字都表示的,這是一種所有符號(hào)的編碼。
- 注意:Unicode 只是一個(gè)符號(hào)集,它只規(guī)定了符號(hào)的二進(jìn)制代碼,卻沒(méi)有規(guī)定這個(gè)二進(jìn)制代碼應(yīng)該如何存儲(chǔ)
- UTF-8碼:UTF-8 就是在互聯(lián)網(wǎng)上使用最廣的一種 Unicode 的實(shí)現(xiàn)方式,是Unicode 的實(shí)現(xiàn)方式之一。
- GB2312,GBK:GB2312是常用漢字的專用編碼,GBK是所有漢字的專用編碼。
- 注意:GB類的漢字編碼與后文的 Unicode 和 UTF-8 是毫無(wú)關(guān)系的
2 液晶屏漢字顯示原理
- ASCII字符顯示,由于ASCII字符僅128個(gè),可以實(shí)現(xiàn)對(duì)每個(gè)字符一一取模,且占用MCU的RAM不會(huì)過(guò)大,此處不再介紹ASCII字符的顯示。
- 為什么顯示英文一般不用字庫(kù)芯片? 英文的單詞都是由26個(gè)字母構(gòu)成了,加上大小寫的區(qū)別和其它一些字符,也不過(guò)才95個(gè)。假如要顯示8 * 16像素大小的字符,每一個(gè)字符需要16個(gè)字節(jié)的字庫(kù)空間,95個(gè)字符即是95 * 16=570個(gè)字節(jié)。即占用570個(gè)字節(jié)的RAM。對(duì)于小型MCU幾K字節(jié)的RAM來(lái)說(shuō),綽綽有余了。
- 為什么顯示中文需要字庫(kù)芯片? 顯示中文的話,需要每一個(gè)字的字模,16*16像素大小的中文,每一個(gè)中文都要32個(gè)字節(jié)。GBK收錄了中文兩萬(wàn)多個(gè),如果要都能顯示,需要700多K字節(jié)的空間。所以,我們選擇了把這些字庫(kù)放在外部存儲(chǔ)器當(dāng)中,可選擇2M的FLASH存儲(chǔ)芯片W25Q16做為存儲(chǔ)媒介。放個(gè)700多K的字庫(kù)足夠了,并且,同時(shí)放兩種字體的字庫(kù)都沒(méi)問(wèn)題。
- 常規(guī)漢字顯示,采用相關(guān)的漢字取字模工具(PCtoLCD2002完美版),取出字模,相關(guān)參數(shù)設(shè)置如下所示:
由于我采用的液晶屏是逐行顯示的,不同的液晶屏采用不同的顯示模式,需根據(jù)具體情況選擇字模。 取出“你”字模后,將字模數(shù)據(jù)復(fù)制到notepad++,調(diào)整成設(shè)置好的16列,21行的樣式,在將16進(jìn)制數(shù)據(jù)轉(zhuǎn)換成2進(jìn)制數(shù)據(jù),然后將0替換成空格,即可找出漢字“你”的原型。
- 對(duì)于液晶屏而言,字符,圖片的顯示都是像素點(diǎn)的點(diǎn)陣顯示,因此,只要將上述數(shù)組中的數(shù)據(jù)轉(zhuǎn)換成點(diǎn)陣數(shù)據(jù)顯示到液晶屏中即可,對(duì)于二進(jìn)制位1的位數(shù)據(jù),顯示出該像素點(diǎn),對(duì)于二進(jìn)制位0的位數(shù)據(jù),不顯示該像素點(diǎn),即可顯示出該漢字(暫不考慮顏色顯示)。
3 字符顯示的實(shí)現(xiàn)
上面講到了字符顯示的原理,接下來(lái)將講解字符顯示的實(shí)現(xiàn),相關(guān)代碼不依賴于底層,具有很好的移植性,且在文章最后放出了Github鏈接,要實(shí)現(xiàn)該代碼的功能,需要以下前提條件:
- 已經(jīng)在液晶屏上實(shí)現(xiàn)了畫點(diǎn)功能,該函數(shù)將直接調(diào)用該功能
- 液晶屏在顯示時(shí),逐行掃描,且需要高位在前(參考上一節(jié)相關(guān)參數(shù)設(shè)置,其它類型的屏幕可能有所不同)
注:由于代碼過(guò)長(zhǎng),為不影響閱讀,僅放部分關(guān)鍵代碼,如有需求,更多請(qǐng)參考文末的Github
for此代碼簡(jiǎn)單地實(shí)現(xiàn)了索引字模數(shù)組中的一個(gè)unsigned char類型的元素中的8位,將該8位繪制成像素點(diǎn),此為字符顯示的基本實(shí)現(xiàn),
4 任意漢字顯示的實(shí)現(xiàn)(采用取模法)
本節(jié)將講述如何實(shí)現(xiàn)任意漢字的顯示。 需要準(zhǔn)備以下工具:
- GBK字庫(kù)
- 取模軟件
- 二進(jìn)制文件生成工具 如下圖所示,且相關(guān)工具可從文末Github中直接獲取得:
具體操作步驟如下:
- 將字庫(kù)取模
在工具欄處點(diǎn)“打開(kāi)”按鈕,打開(kāi)gbk_ziku.txt文件,然后根據(jù)自己的需要,設(shè)置想要的取模方式,然后點(diǎn)工具欄上的“輸出”按鈕 并等待其完成,完成后會(huì)在取模軟件所在路徑生成了一個(gè)temp.txt文件。現(xiàn)在我是按照“宋體、點(diǎn)陣數(shù)為16、字重為4、取模為為16*16、對(duì)齊設(shè)置為左上、方向設(shè)置為橫向取模,高位在左”的方式來(lái)取的字模,也就是我平時(shí)TFT液晶屏常用的一種字模。
打開(kāi)temp.txt文件可知, 該文件包含了所有字庫(kù)的點(diǎn)陣,且采用GBK編碼排序:
- 將取模的文件生成二進(jìn)制文件
將該temp.txt文件轉(zhuǎn)換為二進(jìn)制文件,供程序讀取。在windows下進(jìn)入CMD命令控制臺(tái),進(jìn)入到相關(guān)文件所在的路徑,接著,執(zhí)行命令ziku.exe temp.txt命令,執(zhí)行效果如下圖所示,執(zhí)行后將生成一個(gè)ziku.bin的文件:
- 將二進(jìn)制文件存入外部Flash,或Linux系統(tǒng)用戶文件夾下: 得到ziku.bin文件后,可將該字庫(kù)二進(jìn)制文件存入外部Flash如W25Q16中(MCU),或者Linux系統(tǒng)用戶文件夾下(Linux);其中,將該bin文件存放如外部Flash的方法為:
- 單片機(jī)與電腦采用串口連接,單片機(jī)與W25Q16采用SPI方式連接。所以,我們只需要給單片機(jī)寫一個(gè)接收串口數(shù)據(jù)再把數(shù)據(jù)通過(guò)SPI口傳輸?shù)絎25Q16中的程序即可。
- 使用FT232H芯片工具,該工具實(shí)現(xiàn)了USB轉(zhuǎn)SPI,USB轉(zhuǎn)I2C的功能,可直接通過(guò)PC的USB接口下載到帶I2C或SPI接口的Flash或E2PROM中。
- 檢驗(yàn)二進(jìn)制文件的可用性
本文將只在Linux系統(tǒng)下進(jìn)行檢驗(yàn),MCU環(huán)境下的檢驗(yàn)同理:
該bin文件的檢驗(yàn)程序如下所示(相關(guān)程序均已上傳文章末尾的Github):
#include將以上程序保存為:fontTest.c,gcc編譯,執(zhí)行,結(jié)果如下圖所示:
由執(zhí)行結(jié)果可見(jiàn),程序能夠從二進(jìn)制bin文件中提取有用信息,并且,該bin文件保存了GBK編碼的所有漢字,將“你好”替換成其他任意漢字也是可從bin文件中提取出子模的,生成的bin文件是有效的。 接下來(lái)講解程序中的幾個(gè)注意事項(xiàng):
- 該程序源文件必須以GBK編碼或GB2312編碼保存(GBK編碼兼容GB2312編碼),在notepad++中,保存方式如下圖所示:
- 解釋下如何獲得內(nèi)存中字符的偏移量: GBK編碼:每個(gè)GBK碼由2個(gè)字節(jié)組成:
一是0X40-0X7E
二是0X80-0XFE
例如漢字“瑞”的GBK編碼為C8 F0,第一字節(jié)C8,位于0X81-0XFE之間,第二字節(jié)F0,位于0X40-0XFE之間
第一個(gè)字節(jié)代表的意義稱為區(qū),那么GBK里面總共有126個(gè)區(qū)(0XFE-0X81+1=126) 第二個(gè)字節(jié)代表的意義就是每個(gè)區(qū)內(nèi)有多少個(gè)漢字,算了一下,一共有190個(gè)(0XFE-0X80+0X7E-0X40+2=190)。那么,GBK一共存儲(chǔ)了126X190=23940個(gè)漢字。
仔細(xì)看GBK編碼第二個(gè)字節(jié)兩部分中,0X40-0X7E和0X80-0XFE,也就是說(shuō)它是從0X40~到0XFF,中間的0x7F和最后的0xFF沒(méi)有用到。但是為了能夠線性查找,我們暫且認(rèn)為這兩個(gè)字節(jié)也存在,就是我們強(qiáng)制把每個(gè)區(qū)190個(gè)漢字當(dāng)做每個(gè)區(qū)192個(gè)漢字,不過(guò)0X7F和0XFF上沒(méi)有漢字。
定義GBKH代表第一個(gè)字節(jié),GBKL代表第二個(gè)字節(jié),字庫(kù)的偏移量offset,那么其計(jì)算方法如下:
GBKH實(shí)現(xiàn)了在控制臺(tái)窗口打印漢字字模,那么在TFTLCD,OLED,墨水屏等屏幕上,只要先實(shí)現(xiàn)了畫點(diǎn)功能,那么,顯示任意漢字也可以實(shí)現(xiàn)的了。
5 任意漢字顯示的實(shí)現(xiàn)(采用字庫(kù)法)
最后再介紹一種顯示漢字的方法,該方法采用Python實(shí)現(xiàn),直接調(diào)用字體庫(kù),僅在Linux系統(tǒng)上可實(shí)現(xiàn),下面將以樹(shù)莓派為例,相關(guān)的操作如下:
首先安裝好Pillow庫(kù)以及必要液晶屏顯示必要的SPI庫(kù),GPIO庫(kù)等:
sudo apt-get install python3-pip sudo apt-get install python-imaging sudo pip3 install spidev sudo pip3 install RPi.GPIO sudo pip3 install Pillow安裝 Pillow 如果報(bào)錯(cuò): ImportError: libopenjp2.so.7: cannot open shared object file: No such file or directory,則先執(zhí)行如下指令:
sudo apt-get install libopenjp2-7-dev安裝必要的字體:
sudo apt-get install ttf-wqy-zenhei ttf-wqy-microhei接下來(lái)是調(diào)用微軟雅黑字體進(jìn)行顯示的部分示例(python3),詳情代碼參考文章末尾留下的Github:
#!/usr/bin/python該代碼的精髓在于,先創(chuàng)建一段緩存,然后采用pillow庫(kù)的相關(guān)方法通過(guò)字符串獲取對(duì)應(yīng)字庫(kù)中字符的字模,將字模數(shù)據(jù)存入緩存中,然后將緩存數(shù)據(jù)顯示到屏幕上,詳情參考pillow庫(kù)中的Image,ImageDraw,ImageFont方法對(duì)應(yīng)的手冊(cè)。
注意,代碼中的中文采用UTF-8編碼,保存的時(shí)候,為防止亂碼,必須以UTF-8編碼保存(可采用notepad++工具保存為UTF-8編碼)最后,放出相關(guān)代碼的Github: 軟件工具,字模bin文件校驗(yàn)代碼 刷屏代碼示例
總結(jié)
以上是生活随笔為你收集整理的mysql unicode转汉字_任意汉字显示,给你的嵌入式系统(含MCU)装上字库的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 曝iPhone 14亮黄色要来了!苹果或
- 下一篇: 古巴一波音737客机撞鸟 引擎起火客舱浓