少走弯路:单片机使用点阵字体通过像素化的正确获取

要在单片机内自由显示文字,必须准备相应的字库。之前也发文介绍过:

在esp32(esp8266) 提供软字库显示中文的解决方案_esp32中文字库-CSDN博客

包括已经开源的项目:

https://github.com/StarCompute/tftziku

这种字体获取思路是:把GB2312字符集输出到一块画布上,然后获取画布的像素点,依照像素点的值解析成0或者1。单片机的输出类似如下:

对于字符的显示基本没有问题,但是如果你仔细看就会察觉到这里面有瑕疵:

"2"显示不完整,3的显示不标准。

造成这一问题的原因是因为字符被输出到画布的时候都会边缘模糊,每个像素都是RGB的,哪怕我们使用的字体颜色是纯黑black也同样有这个问题,所以在实际生成这个字库的时候使用了某个值来判断,例如:

python 复制代码
            if dotpix[0] > 90 and dotpix[1] > 90 and dotpix[2] > 90:
                # img.getpixel()
                ss += " 1"
                chars += "1"

            else:
                ss += "  "
                chars += "0"

上面的dotpix是dotpix = img.getpixel((d, i)) 从画布获取的对应像素点,dotpix是个RGB的像素点,这个90是一遍一遍尝试过后相对最优的取值。

这个判断值如果给的太大,字库会存在残缺,反之出现严重的粘连,笔画越密集的地方越容易出问题。

这个问题困扰了好久,尝试过各种方案都无法解决,你们从网上能找到的字符像素化很多都是HZK16这种宋体16号的字库,如果要使用其他楷体,雅黑等等以及不同字号的时候就无解了。

哥有强迫症,隔一段时间就尝试找一下方案,各种调整参数,反正各种折腾下来这个时间跨度有一年以上了,直到今天又看了一下,还是不行,然后深入了一下:

python 复制代码
im = Image.new('RGB', (256, 256), (0, 0, 0))

在这个Image对象的new方法中深入了一下,看到了

python 复制代码
    im = Image()
    if mode == "P" and isinstance(color, (list, tuple)) and len(color) in [3, 4]:
        # RGB or RGBA value for a P image
        from . import ImagePalette

        im.palette = ImagePalette.ImagePalette()
        color = im.palette.getcolor(color)

这个mode,除了RGB和RGBA外居然还有一个P,虽然不懂这个P到底是干啥的,但是大胆尝试了一下:

python 复制代码
im = Image.new('P', (256, 256), (0, 0, 0))

这一改就发现之前的dotpix = img.getpixel((d, i)) 工作不正常,以前是个RGB的像素点,现在居然这个像素点直接返回了0或者1,我靠,一下就猜测可能这次对了。

以前是:

python 复制代码
            dotpix = img.getpixel((d, i))
            if dotpix[0] > 90 and dotpix[1] > 90 and dotpix[2] > 90:
                # img.getpixel()
                ss += " 1"
                chars += "1"

            else:
                ss += "  "
                chars += "0"

现在是:

python 复制代码
            dotpix = img.getpixel((d, i))
            chars+=str(dotpix)

验证如下:

python 复制代码
            
            
 111        
1   1       
1   1       
   1        
  1         
 1          
1           
11111       
            
            

对比一下像素方式生产的结果:

python 复制代码
     1 1 1
   1     1
   1     1
         1
       1

         1
   1 1 1 1

最后重新生成的字库显示如下:

这个就是完全正常的,和PCtoLCD2018的输出是一模一样的 。

两种不同模式生成的字放大很多倍后进行对比:

前面是RGB模式,后面是P模式,简单的看就是一个锯齿的问题,其实并不是这么简单,因为这其实又涉及到两种图的基本构成,所以并不是简单的锯齿化这个问题。

详细代码就不贴出来了,了解了原理怎么都可以写出代码来。

相关推荐
AOI小白新手上路1 天前
韦东山 3-5 I.MX6ULL 的 LED 编程 · 学习笔记
arm开发·笔记·单片机·学习·架构·硬件架构
测试学习test1 天前
SPI读取W25Q64硬件驱动(HAL库)
数据库·stm32·嵌入式硬件·算法
xingzhemengyou11 天前
STM32对函数进行CRC校验
stm32·单片机·嵌入式硬件
FPGA小徐1 天前
STM32引脚详解:PC13-TAMPER-RTC 多功能复用引脚完全剖析(踩坑+配置+布线)
单片机·嵌入式硬件
M78佐菲1 天前
ARM学习笔记(9)
linux·arm开发·笔记·嵌入式硬件·学习
铅笔小新z1 天前
【stm32】中断与异常
stm32·单片机·嵌入式硬件
沐欣工作室_lvyiyi1 天前
无线遥控电动阀门开关模块设计(论文+源码)
单片机·无线遥控
番茄灭世神1 天前
PN学堂GD32教程第11篇——I2C与EEPROM
c语言·stm32·单片机·嵌入式·gd32
阿钱真强道1 天前
27 嵌入式操作系统 | C 网关:串口 ⇄ UDP 转发(先用 UDP 当上位机替身)
c语言·单片机·网关·udp·uloop
沐欣工作室_lvyiyi1 天前
基于STM32的便捷式智能气象仪设计(论文+源码)
stm32·单片机·嵌入式硬件·单片机毕业设计·电子信息工程毕业设计·河北工程技术学院·廊坊师范学院