U8glib之前并没有用过。最近为了让Marlin固件支持中文显示(需要支持图形显示的LCD,如常见的12864液晶),花时间研究了一下这个库。很强大、很好的一个库。在这里简单介绍一下如何使用U8glib显示中文或其它字体的字(包括英文或其它语言)。希望对有同样或类似需求的朋友能够提供帮助和参考。

强大的库

U8glib是非常一个非常强大的库,我体验到的强大之处有:
1、不同驱动芯片及不同分辨率的支持,这就让用户几乎不必关系底层驱动的部分,只需要写自己的程序就可以了,要知道底层驱动的调试比较费时间的;
2、不同连接方式支持,可以支持硬件SPI、软件SPI及8位并行控制方式;
3、支持Arduino、AVR及ARM等不同芯片,CPU升级时,移植代价比较小;
4、多种字体(几十种)可选,从4像素到42像素都有,不过都是最常见的ASCII码,中文等其它特殊字符需要自己定制(即使用自己的字体文件);
5、更换或定制字体还算容易,对于我来说,的确是研究了一段时间才搞明白如何添加新字体,不过一旦掌握,就很简单了;
6、支持横屏或竖屏显示;

局限性

虽然U8glib有很多优点,但也有它的局限性,至少我发现是这样的。尤其是对中文这样的无法用ASCII码覆盖的复杂字符(需要用Unicode标识)。
U8glib的局限性主要体现者对字体的处理方式上,虽然支持几十种字体,但每种字体最多只支持255个字符(0x01~0xFF),而对于中文、韩文及日文等的字符数量成千上万个,要想实现中文语句:创客实验室,可能需要切换不同的字体来实现对各个字的显示,总是切换字体确实比较麻烦,并且切换字体后,还需要重新确定显示坐标。
另一个局限也是提现在字体方面,就是U8glib字体都是0x00~0xFF的ASCII码,而中文则是Unicode,当用ASCII表示中文时,意味着不是完整的Unicode,而是发送\xab\x03\xef等之类的不易读的ASCII码(不是标准的)。所以要想实现显示一句中文,需要自己对应好正确的字体和ASCII码两个才可以正确显示一个汉字,并且每一个汉字都可能需要不同的字体和ASCII。说的有点模糊,看看下面这个例子吧。

如果你不想学这些东西,可以直接下载我整合的bdf文件:http://www.makerlab.me/guides/9/articles/82

举例

如何显示创客实验室这5个汉字呢?
要想显示这几个汉字,还真是不简单,让我们按照步骤一步步的走。注意,U8glib没有所谓的带或不带中文字库,所以带不带中文字库的显示屏都需要以下步骤(这是我的理解,如果我有错误,欢迎指正)。

第一步,确定<code>创客实验室</code>这几个汉字的Unicode码

这一部不难,有很多工具可以使用,我用的上这样网站: 转码工具 输入这5个汉字后,点击向下的箭头,就可以看到这几个字分别对应的Unicode了:

创  ‎521B  [CJK Unified Ideographs]客  ‎5BA2  [CJK Unified Ideographs]实  ‎5B9E  [CJK Unified Ideographs]验  ‎9A8C  [CJK Unified Ideographs]室  ‎5BA4  [CJK Unified Ideographs]
第二步,使用U8glib提供的工具,生产字体文件

U8glib为我们提供了必要的工具和文档,下载U8glib后(https://code.google.com/p/u8glib/ ,由于这个地址需要翻墙,所以没办法翻墙的朋友可以到网盘下载:http://pan.baidu.com/s/1dDfApod ,提供了多个不同版本,我使用的是Arduino版本,并且我把所有的源文件都下载了下来,因为有几个工具及文件在Arduino版本代码里面并没有,需要单独下载),可能需要另外下载的工具上 bdf2u8g(.exe)【用来把字体文档bdf转化为字体数据的】,Unicode.bdf(则是完整的Unicode字体文件,比较大,在U8glib源码中可以下载到Unicode.bdf 9.8M大小),都下载完成后,放入同一个文件夹,来转换字体,命令如下(主要windows版本需要加.exe,linux系统不需要):
linux系统命令是:./bdf2u8g -b 0 -e 255 -l 156 -u 157 unifont.bdf chinese_test chinese_test.c
windows系统命令是:bdf2u8g.exe -b 0 -e 255 -l 156 -u 157 unifont.bdf chinese_test chinese_test.c
等等,这都是什么意思?
bdf2u8g命令的参数说明:
必须的参数:
bdf文件,这是你需要转换的字体文件,bdf格式;
字体名称,用于生产代码数据的标识;
.c文件,c语言文件;
可选参数:
[-b 数字] ASCII码的起始位,范围是0~255;
[-e 数字] ASCII码的结束位,范围是0~255;
[-l page] 用于定位超出0~255范围的Unicode的页数,如果ASCII码范围是0~127,则使用这个参数,如果范围在128~255,则使用下面的-u参数;
[-u page] 用于定位超出0~255范围的Unicode的页数,如果ASCII码范围是128~255,则使用这个参数,如果范围在0~127,则使用上面的-l参数;
创 521B计算页地址为:0x521B/0x80 = 0xA4 = 164,由于1B=27 < 7F,所以使用-l参数即可,命令为:./bdf2u8g -b 27 -e 27 -l 164 unifont.bdf chinese_test chinese_test.c执行命令后,会输出:

encoding range 27..27bbx 14 16 0 -2 encoding 27input file '../bdf/unifont.bdf'u8g font name 'chinese_test'output file 'chinese_test.c'

这时打开生产的c代码文件内容如下:

#include "u8g.h"const u8g_fntpgm_uint8_t chinese_test[55] U8G_FONT_SECTION("chinese_test") = {  0,16,16,0,254,0,0,0,0,0,27,27,0,14,254,0,  0,14,16,32,16,0,254,8,4,8,4,20,4,18,36,33,  36,64,164,190,36,34,36,34,36,34,36,42,36,36,36,32,  132,32,132,31,148,0,8};

需要注意的是,如果在Arduino IDE下使用,需要调整为:

#include "utility/u8g.h"const u8g_fntpgm_uint8_t chinese_test[55] U8G_SECTION(".progmem.chinese_test") = {  0,16,16,0,254,0,0,0,0,0,27,27,0,14,254,0,  0,14,16,32,16,0,254,8,4,8,4,20,4,18,36,33,  36,64,164,190,36,34,36,34,36,34,36,42,36,36,36,32,  132,32,132,31,148,0,8};

前面的include部分是必须改的,U8G_SECTION(".progmem.chinese_test")这个部分可能不同版本需要不同的写法,我用的版本必须改为下面的,否则会有错误。
完整的Arduino代码(显示一个字):

#include "U8glib.h"#include "utility/u8g.h"const u8g_fntpgm_uint8_t chinese_test[55] U8G_SECTION(".progmem.chinese_test") = {  0,16,16,0,254,0,0,0,0,0,27,27,0,14,254,0,  0,14,16,32,16,0,254,8,4,8,4,20,4,18,36,33,  36,64,164,190,36,34,36,34,36,34,36,42,36,36,36,32,  132,32,132,31,148,0,8};

U8GLIB_MINI12864 u8g(45,47);

void draw(void) {  // graphic commands to redraw the complete screen should be placed here    u8g.setFont(chinese_test);  //u8g.setFont(u8g_font_osb21);  u8g.drawStr( 0, 22, "\x1b");}

void setup(void) {

  // flip screen, if required  // u8g.setRot180();

  // set SPI backup if required  //u8g.setHardwareBackup(u8g_backup_avr_spi);

  // assign default color value  if ( u8g.getMode() == U8G_MODE_R3G3B2 )     u8g.setColorIndex(255);     // white  else if ( u8g.getMode() == U8G_MODE_GRAY2BIT )    u8g.setColorIndex(3);         // max intensity  else if ( u8g.getMode() == U8G_MODE_BW )    u8g.setColorIndex(1);         // pixel on}

void loop(void) {  // picture loop  u8g.firstPage();    do {    draw();  } while( u8g.nextPage() );

  // rebuild the picture after some delay  delay(500);}

那么如何显示创客实验室5个汉字呢?你可能注意到了。这5个汉字并没有在unicode的同一页,也就是如果你想节省flash空间,降低字体数据大小的话,需要每个字生产一个字体,并且每个字切换一下字体(严格来说不是字体了,而是字数据),其它几个字的生产代码分别是:
客 5BA2生产代码:./bdf2u8g -b 162 -e 162 -u 183 unifont.bdf chinese_ke chinese_ke.c
实 ‎5B9E生产代码:./bdf2u8g -b 158 -e 158 -u 183 unifont.bdf chinese_shi chinese_shi.c
验 ‎9A8C生产代码:./bdf2u8g -b 140 -e 140 -u 132 unifont.bdf chinese_yan chinese_yan.c
室 ‎5BA4生产代码:./bdf2u8g -b 164 -e 164 -l 183 unifont.bdf chinese_shi2 chinese_shi2.c

其中有几个字,都在5B00~5BFF范围内,可以生产在一个文档中,不过夹杂的一些不相关字会占用flash空间。
数据都生产完成了,但每个字都需要切换一次字体,真的让人受不了,有没有解决办法呢?答案是有的,我经过很多测试和对比,发现如果直接将字体数据进行合并,会导致显示不正常,为了克服这个问题,需要对单独生产的数据进行调整,调整后的创客实验室5个字的数据为:

const u8g_fntpgm_uint8_t chinese_test[] U8G_SECTION(".progmem.chinese_test") = {  0,16,16,0,254,0,0,0,0,0,161,165,0,14,254,0,/\*单独生成的字体,每个字体的第一行都是这种字体是属性信息,由于咱们这几个汉字除了编码不同,其它属性完全一样,所以我们可以用一个来进行修改,注意<b>161,165</b>这两个数据非常重要,分别代表编码的起始和终止位置161~165就是十六进制的A1~A5 \*/    //Chinese "创"  0,14,16,32,16,0,254,8,4,8,4,20,4,18,36,33,  36,64,164,190,36,34,36,34,36,34,36,42,36,36,36,32,  132,32,132,31,148,0,/\*8,每个单独生产的数据,最后一位貌似有特殊用途,如果合并,需要将这一位删除,否则后面的字都无法显示 \*/  //Chinese "客"  0,15,16,32,16,0,254,2,0,1,0,127,254,64,2,136,  4,15,240,16,32,44,64,3,128,28,112,224,14,31,240,16,  16,16,16,31,240,16,/\*16\*/  //Chinese "实"  0,15,16,32,16,0,254,2,0,1,0,127,254,64,2,136,  132,4,128,4,128,16,128,8,128,8,128,255,254,1,64,2,  32,4,16,24,8,96,/\*4\*/  //Chinese "验"  0,15,16,32,16,0,254,0,32,248,32,8,80,72,80,72,  136,73,4,74,250,124,0,4,68,4,36,29,36,228,168,68,  136,4,16,43,254,16,/\*0\*/  //Chinese "室"  0,15,15,30,16,0,255,2,0,1,0,127,254,64,2,128,  4,63,248,4,0,8,32,31,240,1,16,1,0,63,248,1,  0,1,0,255,254};

要想显示这5个字,只需要将之前提到的arduino代码中的显示代码改为u8g.drawStr( 0, 28, "\xa1\xa2\xa3\xa4\xa5");就可以显示了,如图:

可以看到,中文可以显示了,但字体是Unicode.bdf文件中标准的字体,16X16像素,如果想显示个性字体,请参考下一部分

转自:http://www.makerlab.me/guides/9/articles/51

U8glib如何显示中文相关推荐

  1. window系统mysql无法输入和无法显示中文的处理配置

    第一步:使用记事本打开mysql安装目录下的"my.ini"文件. # MySQL client library initialization. [client] port=330 ...

  2. python图像中如何显示中文

    python图像中如何显示中文 在开头加入这两行即可 from pylab import * mpl.rcParams['font.sans-serif'] = ['SimHei']

  3. hbase shell编码显示中文

    最近测试hbase shell,碰到个中文显示编码问题,最后通过Python解决了问题,具体操作如下: hbase(main):015:0* scan 'fr_test_hbase:test_log1 ...

  4. php运行显示中文乱码,如何解决PHP界面显示中文乱码的问题

    如何解决PHP界面显示中文乱码的问题 发布时间:2020-07-14 15:19:00 来源:亿速云 阅读:74 作者:Leah 这期内容当中小编将会给大家带来有关如何解决PHP界面显示中文乱码的问题 ...

  5. jQuery里面的datepicker日期控件默认是显示英文的,如何显示中文或其他语言呢?...

    jQuery里面的datepicker日期控件默认是显示英文的,如何让他显示中文或其他呢? [官方的写法]: (1)引入JS文件: <script type="text/javascr ...

  6. Ubuntu下用matplotlib作图时显示中文

    之前在Ubuntu下用matplotlib作图的时候发现无法正常显示中文,查了一番以后发现是Ubuntu系统和matplotlib库没有共同可显示的中文字体库的原因.用此文章的方法可以解决这一问题. ...

  7. wingide 显示中文 及 配色方案

    网上收集的方法: 显示中文: 任意文本编辑器打开:x:\Wing IDE\bin\gtk-bin\etc\pango\pango.aliases 修改内容为: courier = "micr ...

  8. vc++ 6.0对话框上无法显示中文(乱码)

    是英文版的vc++,建立mfc向导时无法选择中文,到对话框里面改成中文还是乱码,怎么版啊 问题补充: 一般对话框是可以的,就是那个CPropertyPage 不可以对话框资源选成中文以后要ReBuil ...

  9. lxml xpath 爬取并正常显示中文内容

    在使用python爬虫提取中文网页的内容,为了能正确显示中文的内容,在转为字符串时一定要声明编码为utf-8,否则无法正常显示中文,而是显示原编码的字符,并没有正确转换.比如下面这个简单的爬取百度页面 ...

  10. 解决zabbix3.4图表显示中文乱码问题

    问题描述: 在Zabbix界面设置中,已经调成中文语言,可能zabbix自身携带的字体还不够完美,出现如下乱码: 测试环境: zabbix 3.4(经测试,目前3.x版本都适用) 解决步骤: 1. 寻 ...

最新文章

  1. 二叉树结点地址小错误
  2. Habana Labs
  3. React和设计良好的jQuery插件并没有什么不兼容的问题。
  4. oracle unpivot 空值,sql – 处理UNPIVOT中的NULL值
  5. [渝粤教育] 西南科技大学 计算机工业控制 在线考试复习资料
  6. unsigned int + int型结果分析
  7. RiPro主题-子主题huzao-child V4.0简洁大气集成后台美化包
  8. TwentyTwelve透明主题二次美化版
  9. python做数据分析需要oracle_精通 Oracle+Python,第 1 部分:查询最佳应践
  10. Java对字符串进行的操作
  11. concurrent包的实现示意图
  12. vivado仿真时候报错Common 17-39
  13. 国产系统之光deepin之Java开发环境安装实录
  14. 猴王问题(项目分析以及项目实现)
  15. 古诗名句分类二:事理哲理
  16. IIQ文件内gps信息的分析
  17. 使用 * 打印等腰三角形
  18. 基于FPGA的CAN总线控制器的设计(下)
  19. startAgent.bat在win2008上运行闪退
  20. Treasure Island(简单图论题)

热门文章

  1. python安装库之----有些库库真是小妖精
  2. 【VBox】解决复制VBox虚拟机后提示硬盘UUID 已经存在的问题
  3. Absolute Enable Right Click Copy 简单快速解除滑鼠右键使用限制
  4. snapchat_Snapchat的新地图功能介绍(以及如何禁用它)
  5. Contrastive Multiview Coding
  6. c语言分数乘法,武汉小学数学六年级
  7. android FTP上传下载文件
  8. 读取和修改JPEG图片文件的头信息EXIF和JFIF
  9. 最大化印刷MES管理系统价值,提升印刷车间效率与质量
  10. NoSQLBooster for MongoDB 5x版本商业版(mac os)