吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3369|回复: 11
收起左侧

[Python 原创] 用Python实现单片机点阵字体输出及制作点阵字体的思考

  [复制链接]
FeiyuYip 发表于 2022-6-8 09:50
本帖最后由 FeiyuYip 于 2022-6-8 09:59 编辑

最近对点阵字体比较有兴趣,所以主要参考了两个教程,实现了用python输出点阵字体需要说明的是,这种实现方法是读取字体的“字模”来生成的,而不是根据某款字的字形强转为点阵形式。
粗略地说一下字模的含义,有兴趣的可以去搜索一下
所谓字模又称HZK字模,一般见于上古时代的操作系统(如UCDOS等)或单片机行列,是由前辈们辛苦把某款字体按不同的矩阵排列,把它们收集整理成字模。
需要输出哪个字,就根据规律,在字模里寻找到这个字模的值即可。

免费的字模文件见:字模下载地址
言归正传,说一下参考的案例及

参考教程1:Python print 玩转点阵字(某乎的链接,不知道是否违规)
这篇教程用python写得很清晰明白,照猫画虎就能轻松实现16*16点阵的汉字输出。
微信截图_20220608092435.png
但这样似乎还嫌不够,因为字模文件有好多个,涉及12*12,16*16,24*24,32*32,40*40,48*48等,没有理由只止步于此。
于是又找到下面这个案例:
参考教程2:点阵字库HZK32的使用方法和显示(某猴的链接,不知道是否违规)
它是实现了32*32点阵的汉字输出,耐何是C语言实现的。鄙人对C知之甚少,但搜索点阵字体生成的原理,以及参考教程1的代码,终于发现了规律。
于是修改出来如下通用性的代码:
[Python] 纯文本查看 复制代码
import binascii
import os

# 用于测试当前位是否为1
KEYS = [0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01]
HZK_save_path = 'font'


def show_one_string(text_str, HZK_wei, HZK_file):
    HZK_wei = int(HZK_wei)
    rect_list = [] * HZK_wei
    for i in range(HZK_wei):
        rect_list.append([] * HZK_wei)
    # print(rect_list)

    HZK_path = f'{HZK_save_path}/{HZK_file}'
    # # 当24时,任选一个效果
    # if HZK_wei == 24:
    #     HZK_path = f'{HZK_save_path}/HZK{HZK_wei}K'
    #
    # if HZK_wei == 16:
    #     HZK_path = f'{HZK_save_path}/HZK{HZK_wei}F'

    # 此时开始进入循环
    for text in text_str:
        gb2312 = text.encode('gb18030')
        # 获取中文的gb2312编码,一个汉字是由2个字节编码组成
        hex_str = binascii.b2a_hex(gb2312)
        # 将二进制编码数据转化为十六进制数据
        result = str(hex_str, encoding='utf-8')
        # 前两位对应汉字的第一个字节:区码,每一区记录94个字符
        area = eval('0x' + result[:2]) - 0xA0
        # 后两位对应汉字的第二个字节:位码,是汉字在其区的位置
        index = eval('0x' + result[2:]) - 0xA0
        # hzk16为32字节,hzk32为32*32/8字节
        offset = (94 * (area - 1) + (index - 1)) * int(HZK_wei * HZK_wei / 8)
        # print(offset)
        # 读取HZK汉字库文件
        with open(f"{HZK_path}", "rb") as f:
            # 找到目标汉字的偏移位置
            f.seek(offset)
            # 从该字模数据中读取字节数据
            font_rect = f.read(int(HZK_wei * HZK_wei / 8))
            # print(font_rect)

        for k in range(HZK_wei):
            # 每行数据
            row_list = rect_list[k]
            for j in range(int(HZK_wei / 8)):
                for i in range(8):
                    asc = font_rect[k * int(HZK_wei / 8) + j]
                    # 此处&为Python中的按位与运算符,测试当前位是否为1
                    flag = asc & KEYS[i]
                    # 为1的变成为O,为0的变换为空
                    if flag:
                        flag = '0'
                    else:
                        flag = ' '
                    # 数据规则获取字模中数据添加到16行每行中16个位置处每个位置
                    row_list.append(flag)

    # 根据获取到的32*32点阵信息,打印到控制台
    for row in rect_list:
        for i in row:
            print(i, end=' ')
        print()

    with open(f'{text_str}.txt', 'w') as f:
        for i in range(len(rect_list)):
            string = str(rect_list[i]).replace('{', '').replace('}', '').replace("'", '').replace('[', '').replace(
                ']', '').replace(',', '') + '\n'
            # string = (re.sub(r"['{},]*", '', str(rect_list[i])) + '\n').replace(':', ',')
            f.write(string)

    print(f'“{text_str}”点阵显示效果已经保存')

    os.system('pause')


if __name__ == '__main__':
    text_str = input('请输入要显示的字:' + '\n')
    # text_str = '安'
    HZK_wei = input('请输入点阵字体的位数:(如16/24/32/40/48)' + '\n')
    # HZK_wei = 48
    HZK_file = input('请输入点阵字体库文件名:见font文件夹内' + '\n')
    # HZK_file = 'HZK48'
    show_one_string(text_str, HZK_wei, HZK_file)

不同字模对应的不同规格的点阵字体,以及不同的字体,输入时要注意对应上,若干参考见下。
执行本程序,字模文件须放置在程序中的font文件夹内
微信截图_20220608093016.png

微信截图_20220608093137.png
若干不足:

字模文件内包含的文字数量及字形限制了输入文字的上限,字模文件中没有包含的文字则报错。一般而言这些字模只覆盖了gb2313编码的文字,即不能输出繁体字。有一个例外,HZK16F是对应繁体输出,输入简单字直接输出繁体字。
字形如楷体、宋体、仿宋、黑体等也不是各个规格的字模文件都包含的
扩展联想:
1.如果仅是输出点阵文件当然不太好玩,搞明白了这个思路,可以尝试制作点阵字体(像素字体)。我相信市面上流通的某些像素字体也是基于这个原理来弄的。
我目前也在研究这方面,有兴趣的朋友可以参考以下几篇案例(同样是外链,如违规则删除):
ipix中文像素字体的制作
中文像素字体制作 (重点看这篇)
如何将点阵汉字矢量化
2.基于将点阵文字制作成矢量字体的思路,通过上面的方法被证明是可行的。我又找到了上古时期UCDOS7.0文件,它里面很多字模文件:
微信截图_20220608094553.png
微信截图_20220608094647.png
根据这个说明,这就很多玩法了,但是我确实不知道这些字模文件怎样对应把文字提取出来,请问有没有明白的大神指导一下,或提供相关的资料、思路,多谢多谢!!
涉及字模文件分享如下:
链接:https://pan.baidu.com/s/1ErOaUvxKdpwWDzjyJFL17Q
提取码:6ukk

免费评分

参与人数 1吾爱币 +16 热心值 +1 收起 理由
wushaominkk + 16 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| FeiyuYip 发表于 2022-6-8 11:58
androllen 发表于 2022-6-8 10:31
有点新意,可以换aliyun 吗

https://github.com/aguegu/BitmapFont
您可以去这里下载
 楼主| FeiyuYip 发表于 2022-6-8 12:52
立竿见影 发表于 2022-6-8 12:19
灯箱或者店铺led灯牌匾是不是就是这么弄的?

原理应该都是这样。
只是实际操作不会这么麻烦,商家肯定配了专门的烧录工具,把逻辑封装在工具中了,输入文字后就直接输出文字。
androllen 发表于 2022-6-8 10:31
 楼主| FeiyuYip 发表于 2022-6-8 10:52
androllen 发表于 2022-6-8 10:31
有点新意,可以换aliyun 吗

抱歉,怎么换aliyun?
立竿见影 发表于 2022-6-8 12:19
灯箱或者店铺led灯牌匾是不是就是这么弄的?
itxpl0907 发表于 2022-6-8 13:50
学习了,感谢分享
aonima 发表于 2022-6-8 15:15
感谢分享
zm55555 发表于 2022-6-10 07:31
谢谢分享!
card51 发表于 2022-8-25 07:42
新人,你们都是自学的Python吗学校根本不教
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 01:24

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表