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

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

在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模式,简单的看就是一个锯齿的问题,其实并不是这么简单,因为这其实又涉及到两种图的基本构成,所以并不是简单的锯齿化这个问题。

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

相关推荐
菜菜why1 分钟前
esp32课设记录(三)mqtt通信记录 附mqtt介绍
c语言·esp32·嵌入式软件
长流小哥15 分钟前
STM32实战指南:DHT11温湿度传感器驱动开发与避坑指南
stm32·单片机·嵌入式硬件·keil5
Dev_XH21 分钟前
【成品设计】基于Arduino的自动化农业灌溉系统
单片机·智能家居
Wythzhfrey1 小时前
单片机Day11
c语言·单片机·嵌入式硬件·学习·51单片机
HHONGQI1232 小时前
STM32 片上资源之串口
stm32·单片机·嵌入式硬件
搬砖的小码农_Sky2 小时前
低功耗:XILINX FPGA如何优化功耗?
嵌入式硬件·fpga开发·硬件架构·硬件工程
芯眼3 小时前
正点原子STM32新建工程
开发语言·c++·stm32·单片机·软件工程
芯动力小子6 小时前
MCU开发学习记录17* - RTC学习与实践(HAL库) - 日历、闹钟、RTC备份寄存器 -STM32CubeMX
单片机·学习·实时音视频
广药门徒15 小时前
STM32简易计算机设计
stm32·单片机·嵌入式硬件
Ronin-Lotus17 小时前
嵌入式硬件篇---拓展板
嵌入式硬件