在esp32(esp8266) 提供软字库显示中文的解决方案

这篇具有很好参考价值的文章主要介绍了在esp32(esp8266) 提供软字库显示中文的解决方案。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本方案已经开源到了 https://github.com/StarCompute/tftziku ,详细内容请访问Github.

本方案在esp32 下经过测试在tft屏幕上可以正常输出文字,也就是说经过了验证。

目录

说明

缘起

系统结构

软字库的创建

软字库包含的内容:

软字库的格式

字模的格式

软字库在单片机中的使用

在终端输出

通过单片机在tft屏幕显示


说明

本项目是为了在各种单片机使用中创建更方便易用的字库,配合使用了  ``TFT_eSPI`` 进行显示使用,实际上可以用于其他任何点阵屏。

缘起

我们都知道,要在单片机上使用汉字输出,都必须汉字点阵化,然后再集成到单片机中进行输出;然而这里有个弊病,就是你输出的汉字每次都必须使用类似于 PCtoLCD2018 这样的软件来处理,极其不方便;而如果单片机要同上位机进行文字通信的时候,上位机的文字其实不受限的,这个时候采取预处理文字的方式就不行了,虽然我自己采用过像素化进行通信,但是始终觉得非常不便。 事实上,文字的调整是个高频的事情,如果每次使用 PCtoLCD2018 来处理实在太繁琐了,因此就产生了一个基本问题:重复修改字体数据,这也同时提出了一个需求:使用软字库。 如果时光倒退无数年,会有专门卖 硬件字库 的,以及PC上类似于 UCDOS 这样软字库的东西。 单片机上各种中文的显示,大家常见的是U8G2这种东西,但是它的汉字非常不全面,基本用不起来。在使用 Tft_eSPI 的字库工具包 processing 过程中,网上有些教程误导我们先用 processing 创建vlw文件,再去转换成.h文件,最后编译进项目里面去。 这是一种完全的误导: - vlw 文件是可以被 tft_espi 项目直接使用的; - 无论是vlw还是.h格式的文件,如果是个别中文的处理毫无意义,而如果是完全的字符(类似于GB2312),这个vlw和.h文件都是非常巨大的,在我的esp32上是无法上传到flash空间中。

基于经验的积累和对于 tft_espi 的部分学习,尝试用自己的方式来创建包含 gb2312 字符集的字库,经过测试后发觉:自己创建的16号字体 GB2312 字符集整体只有507k,这个比vlw文件少了一半的空间占用。

并且, tft_espi 装载自己的vlw字库需要2秒,然后显示对应文字需要0.1x秒左右,而使用我自己创建字库利用tft_espi驱动显示同样的文字只需要0.28秒左右,整体性能提升已经达到了一个相对很高的程度。

从空间占用和显示速度上都b表现出了更优,为了方便大家更方便的进行单片机,所以把这个项目进行开源。

系统结构

软字库的创建

软字库包含的内容:

软字体用 python 进行创建,在本项目中是 getunicode.py ,它是把绝大部分能够显示出来的GB2312字符集包含进来了,然后包括进来了常见的大小写英文字母和字符(从chr(33)=chr(128)),由于 GB18030 的字库太大,所以是不可能使用 GB18030 ,使用了 GB2312 ,我们平常使用的文字基本都在这个字库中,例如“饕餮”这两个字都在GB2312中。

软字库的格式

  • 软字体以x.font方式进行命名,采用纯文本进行存储。
  • x.font文件被分成了4个部分:
  • 前6位16进制表示总共存储了多少字符;
  • 7-8位用10进制表示存储的是多少号字体,
  • 9-xxxx*5位存储的是字符的unicode编码,为了节省存储空间,一个汉字采取的是u+4位unicode编码;例如"u3001u3002u30fbu02c9u02c7" 是“、。・ˉˇ”对应的存储;每个GB2312字符转化为5个字符进行存储。
  • xxxx*5+1至xxxx*8存储的是每个字符对应的取字模数据的16进制编码

举例来说,假设我们的字库只有一个 “ “ 字,用16号字体存储,那么它的整体内容如下:

00000116u597d100010fc10041008fc102420242025fe24204820282010202820442084a00040

如果用12好字体存储,那么存储内容如下::

00000112u597d200027c02040f880490049004fe091005100210051008b00

对比16号和12号字体::

000001  16  u597d   100010fc10041008fc102420242025fe24204820282010202820442084a00040
000001  12  u597d   200027c02040f880490049004fe091005100210051008b00

000001 表示 总共有1个字符 16和12表示存储的字号 u597d 是"好”字的unicode编码 再后面分别对应着

100010fc10041008fc102420242025fe24204820282010202820442084a00040

对应

{0x10,0x00,0x10,0xFC,0x10,0x04,0x10,0x08,0xFC,0x10,0x24,0x20,0x24,0x20,0x25,0xFE},
{0x24,0x20,0x48,0x20,0x28,0x20,0x10,0x20,0x28,0x20,0x44,0x20,0x84,0xA0,0x00,0x40},/*"好",0*/

200027c02040f880490049004fe091005100210051008b00

对应

{0x20,0x00,0x27,0xC0,0x20,0x40,0xF8,0x80,0x49,0x00,0x49,0x00,0x4F,0xE0,0x91,0x00},
{0x51,0x00,0x21,0x00,0x51,0x00,0x8B,0x00},/*"好",0*/

为了压缩存储内容,把0x10,0x00, 这种直接转化成了1000,这样的化,存储的内容就只有标志16进制格式的五分之二。

如果,这个字库存储的字符是 “你真好看啊!” ,它的整体内容如下::

00000612u4f60u771fu597du770bu554au00211400140027e024206940a10025402520252029202100230004007fc004003f8020803f8020803f802080ffe011002080200027c02040f880490049004fe091005100210051008b0003c07c0004007fc00800ffe020407fc0a0403fc020403fc00000eee0aa40abc0ad40ad40ab40abc0ea40ac40084008c0000000002000200020002000200000000000200000000000

经过整理后如下::

000006  12  u4f60   u771f   u597d   u770b   u554a   u0021   1400140027e024206940a10025402520252029202100230004007fc004003f8020803f8020803f802080ffe011002080200027c02040f880490049004fe091005100210051008b0003c07c0004007fc00800ffe020407fc0a0403fc020403fc00000eee0aa40abc0ad40ad40ab40abc0ea40ac40084008c0000000002000200020002000200000000000200000000000

掌握了这种格式的存储,就知道了如何获取到对应的内容,值得特别说明的是,为了方便计算,字模的16进制数据采取的是8位一个存储,12号字体其实可以认为是12*12个像素,但是存储的时候为了某种方便采取了16*12这种方式;所以一定程度来讲,这个字库还有压缩和提升性能的潜力可以挖掘;

在创建字库的时候,如果字符集里面有英文字母,将对英文字母补00进行操作,例如上面的"!" 它的unicode编码系统生产的是"u21",把它补0转换后就是"u0021". 字库中,字符的存储使用 ``u `` 一方面表示这是unicode 编码,另外一方面这个u也骑着分割符的重要作用,它能保证,这段编码被检索的时候不会重复,因为unicode编码不会一样,而如果没有使用 ``u `` ,只是存储 编码数字的话肯定会出现某个编码互相组合出现重复这种情况。

字模的格式

经过学习发现 TFT_eSPI 使用的vlw格式字库文件,其实是一种组合式的图片文件,而TFT_eSPI对于每个字符的显示其实就是动态取模。 本字库是提前对于字符取模,它采取把对应的字符画到图片上,然后获取每个位置的像素,每8个模 编码为16进制。取模顺序是从左到右,从上到下

软字库在单片机中的使用

字体文件在单片机中的使用,其实是一个逆向过程:

  • 上传生成的字库到单片机中
  • 输入要显示的汉字
  • 读取x.font文件,读取前6位,获得总共有多少个字符;
  • 再读取2位,确定字体对应的字号;
  • 读取unicode字符集,判断是否同输入汉字的unicode匹配
  • 利用匹配到的顺序,计算出字模的位置,依照字号获取对应长度的数据
  • 把字模的16进制编码重新编码为二进制
  • 利用TFT_eSPI 的 drawpix 方法把汉字输出到屏幕上(这里会有个方法计算能够显示多少汉字)
  • 字库调用完成
.. 注意:: 英文字符的特殊性暂未处理。

    由于英文基本都是半角符号,中文是全角符号,理论上英文的输出只有中文的一半,但是本字库暂时未处理英文的半角输出问题,全部是全角输出,后续再进行整理。

在终端输出

   String strBinDisplay = getPixBinStrFromString("这是一个软字体的显示你看看再多如何显示出来啊!你说你项羽突然的自我伍佰向天再借五百年");

    // 下面代码在终端输出文字点阵。
    Serial.println(strBinDisplay.length());
    for (int i = 0; i < strBinDisplay.length(); i++)
    {
        if (i % 16 == 0)
        Serial.print("\r\n");
        if (strBinDisplay[i] == '0')
        Serial.print(' ');
        if (strBinDisplay[i] == '1')
        Serial.print(strBinDisplay[i]);
    }

终端显示如下:::

   

           

           1

           1    111111  

           1         1  

           1        1  

        111111     1

          1  1    1

          1  1    1

          1  1 11111111

          1  1    1    

         1  1     1

          1 1     1

           1      1

          1 1     1

         1   1    1

        1    1  1 1

             1

           1     1

           1     1

           1     1      

        1111111  11111

          1     1    1

          1 1   1   1

         1  1  1  1

         111111   1

            1     1

            1    1 1

            111  1 1

        11111    1 1

         1  1   1   1

            1   1   1

            1  1     1

            1 1       1



 

通过单片机在tft屏幕显示


    // 下面代码在TFT屏幕输出文字
    int pX = 16;
    int pY = 0;
    int fontsize=16; //字号
    int amountDisplay=10; //每行显示多少汉字
    int singleStrPixsAmount=fontsize*fontsize;
    for (int i = 0; i < strBinDisplay.length(); i++)
    {
        // 这里必须有特别的说明,每个字符的像素点总数是singleStrPixsAmount=fontsize*fontsize,如果是16号字体就是256个;
        // 每行显示10个字,那么他们到一点阶段就必须换行,x坐标归0,y坐标必须加上字体对应的像素
        // 对于pX,每显示fontsize个像素后就必须字体归到起始点,注意每显示n字符后,这个起始点就必须加上fontsize*n这个起始值
        // 同时对于换行也必须处理。

        pX=int(i%fontsize)+int(i/(singleStrPixsAmount))*fontsize-int(i/(singleStrPixsAmount*amountDisplay))*fontsize*amountDisplay;

        // 对于pY,每fontsize个像素后+1,每singleStrPixsAmount个像素后归0,同时每换一行,pY要加上fontsize个像素;
        pY =int((i-int(i/singleStrPixsAmount)*singleStrPixsAmount)/fontsize)+int(i/(singleStrPixsAmount*amountDisplay))*fontsize;

        if (strBinDisplay[i] == '1')
        {
        tft.drawPixel(pX, pY, TFT_GREEN);
        }
    }

 

esp32显示汉字,ESP8266,Arduino,ESP32,单片机,嵌入式硬件,esp32,软字库,中文显示文章来源地址https://www.toymoban.com/news/detail-539908.html

到了这里,关于在esp32(esp8266) 提供软字库显示中文的解决方案的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity中TMP中文字体导入及字库显示不全问题解决

    记录Unity中TMP第三方中文字体导入及字库显示不全问题解决的方法。 https://www.100font.com/ 为了项目方便管理,一般在Assets资源下新建Fonts文件夹,把字体资源拖入 记录Unity中TMP中文字体导入及字库显示不全问题解决的方法。

    2024年02月05日
    浏览(101)
  • STM32+ESP8266+OneNet共同完成温度显示功能

    这次实验对应的是我的本科毕业设计,目标是完成一个温度测试平台,具有本地显示,远程显示,算法后台校正的功能。为了适应当前信息化的物联网发展方向,本文选择一款分辨率可调的高线性度CMOS温度传感器作为感温芯片,运用STM32F103C8T6作为微控制器主控芯片,使用W

    2024年02月20日
    浏览(87)
  • ESP8266+STM32获取网络时间、OLED显示时间&图片&视频。

    先说说我的设计内容的组成: 目录 学习过程不易,发文共享以下学习过程~ 1. STM32控制ESP8266获取网络时间 第一步:电脑控制ESP8266获取时间数据; 2. STM32基于获取到的时间使用定时器本地运行 3. 使用OLED显示时间数据,包括自定义的文字显示,图片显示,视频显示; 4. 完整的

    2024年02月08日
    浏览(37)
  • STM32+ov7725+ESP8266实现无线图传-完成上位机图像显示

    stm32f407探索者开发板和STM32F103ZET6战舰开发板。接正点原子ov5640、OV7725、OV2640摄像头,通过esp8266Wi-Fi模块(透传模式)将摄像头采集到的rgb565格式图片通过tcp/ip协议上传到上位机显示。 【1】使用QT开发上位机,建立TCP服务器,接收ESP8266发送过来的图像数据显示。 【2】编写S

    2024年02月08日
    浏览(69)
  • STM32+ESP8266+QT客户端上位机显示DHT11温湿度与点灯

    目录 1、简介 2、硬件连接 3、上位机源码 3.1 widget.h 3.2 widget.c  3.3 显示图  4、下位机源码 4.1 cubemax配置  4.2 keil源码 本文使用STM32F103C8T6单片机使用单片机通过ESP8266WIFI模块与QT设计的上位机进行通讯,ESP8266设置AP模式。实现DHT11传感器温湿度的显示与远程控制LED小灯的亮灭

    2024年02月06日
    浏览(49)
  • STM32--ESP8266物联网WIFI模块(贝壳物联)--温湿度数据上传服务器显示

    本文适用于STM32F103C8T6等MCU,其他MCU可以移植,完整资源见文末链接 一、简介 随着移动物联网的发展,各场景下对于物联控制、数据上传、远程控制的诉求也越来越多,基于此乐鑫科技推出了便宜好用性价比极高的wifi物联模块——ESP8266,话不多少我们先来看看这个神奇的模

    2024年02月08日
    浏览(49)
  • 毕业设计——基于STM32的智能家具控制系统(ESP-01S(8266)、手机app远程控制、远程显示温度)

    智能家具系统分为两个不同版本系列: ①系列一:手机app远程控制、远程检测温湿度显示在app,(云平台)    ---------本文章 ②系列二:语音识别控制                https://blog.csdn.net/m0_59113542/article/details/123742383 步进电机及相关驱动 步进电机28BYJ48 uln2003驱动板器4相5线

    2023年04月09日
    浏览(71)
  • STM32+ESP8266(AT固件)连接阿里云物联网 保姆级教学(附代码)--2. 设置产品Topic数据和功能定义设备物模型数据显示

    提示:这里是从实际应用如何使用教学配置,未从原理讲解,适合小白从零开始到成功,比较有成就感 STM32+ESP8266(AT固件)连接阿里云物联网系列保姆级教学 1. 创建产品和设备 2. 设置产品Topic数据和功能定义设备物模型数据显示 3. 硬件连接+代码修改 4. Web数据可视化 5.功能

    2024年02月03日
    浏览(57)
  • ESP32+VSCode开发环境搭建(全网最强最终解决方案)

    本文必然会解决你在ESP开发道路上遇到VSCode开发环境搭建的问题! 本文一定能解决你ESP开发道路上遇到的开发环境搭建问题! 本文必须解决你在ESP开发道路上遇到的开发环境搭建问题! 如果发现看了本文解决不了你的开发问题,请在评论区轰炸我!轰炸我!轰炸我!我随时

    2024年02月08日
    浏览(40)
  • Python利用Matplotlib绘图无法显示中文字体的解决方案

    问题描述 在Python利用Matplotlib绘图的时候,无法显示坐标轴上面的中文和标题里面的中文 运行显示: 解决方法一: 解决方法二: 两种方法都可以使中文正常显示 补充: SimSun :宋体;KaiTI:楷体;Microsoft YaHei:微软雅黑 LiSu:隶书;FangSong:仿宋;Apple LiGothic Medium:苹果丽中黑

    2024年01月23日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包