micropython优雅的两个小功能块

本文探讨如何使用正则表达式提取字符串中的特定字符(如#1234)和计算两个矩形的交集面积,提升编程思维。通过实例演示了功能实现和优雅编码的重要性。

虽然做调库侠很爽,但是我还是建议大家尽可能写一写,看一看小的功能块,对于提升自己的编程思维和能力非常有帮助,而且如果做得够优雅是很爽快的!
功能1:
寻找两个置顶字符串之间的字符
比如chars=‘sdf#1234,rtiu@’
只想提取#和,之间的1234,怎么做?
万能的正则表达式,一定能做到,也许有其他的库也可以,但是何不尝试自己写一个呢?
上核心代码:

clist=[]
mark=0
text='sdf#1234,rtiu@'
for ch in text:
   if ch=='#':
       mark+=1
   elif ch==',':
       mark-=1
   else:
       if mark:
           clist.append(ch)
result=''.join(clist)

加个标志为,开始结尾拿捏,搞定!学到了
功能2:
求两个坐标矩形相交的面积
听上去是不像个有点复杂的数据问题?也许cv2或者某个库里有此功能,但自己尝试写一个真的很难吗?
上代码:

def calculate_U(predicted_bound, ground_truth_bound):
    """
    computing the IoU of two boxes.
    Args:
        box: (xmin, ymin, xmax, ymax),通过左下和右上两个顶点坐标来确定矩形位置
    Return:
        IoU: IoU of box1 and box2.
    """
    pxmin, pymin, pxmax, pymax = predicted_bound
    print("预测框P的坐标是:({}, {}, {}, {})".format(pxmin, pymin, pxmax, pymax))
    gxmin, gymin, gxmax, gymax = ground_truth_bound
    print("原标记框G的坐标是:({}, {}, {}, {})".format(gxmin, gymin, gxmax, gymax))

    parea = (pxmax - pxmin) * (pymax - pymin)  # 计算P的面积
    garea = (gxmax - gxmin) * (gymax - gymin)  # 计算G的面积
    print("预测框P的面积是:{};原标记框G的面积是:{}".format(parea, garea))

    # 求相交矩形的左下和右上顶点坐标(xmin, ymin, xmax, ymax)
    xmin = max(pxmin, gxmin)  # 得到左下顶点的横坐标
    ymin = max(pymin, gymin)  # 得到左下顶点的纵坐标
    xmax = min(pxmax, gxmax)  # 得到右上顶点的横坐标
    ymax = min(pymax, gymax)  # 得到右上顶点的纵坐标

    # 计算相交矩形的面积
    w = xmax - xmin
    h = ymax - ymin
    if w <=0 or h <= 0:
        return 0

    area = w * h  # G∩P的面积
    # area = max(0, xmax - xmin) * max(0, ymax - ymin)  # 可以用一行代码算出来相交矩形的面积
    print("的面积是:{}".format(area))

    # 并集的面积 = 两个矩形面积 - 交集面积
    U = area / garea

    return U

if __name__ == '__main__':
    IoU = calculate_U( (1,2, 4, 5), (3, 1, 6, 3))
    print("U是:{}".format(IoU))





想通了就不难,就是个比较,然后进阶想做一个,计算一个矩形跟多个矩形交集的总面积的,奥利给,动脑筋想就完了!

<think> 我们正在解决如何在MicroPython esp32中修改ssd1306字体大小的问题。 根据之前的讨论,我们知道在MicroPython中使用ssd1306驱动OLED屏,默认的字体大小是固定的(通常是8x8像素)。如果要改变字体大小,通常有两种方法: 1. 使用不同大小的字体(即使用不同尺寸的字模数据) 2. 通过软件缩放(例如每个像素放大为2x2像素)来实现放大效果,但这会降低分辨率且实现复杂。 根据引用[1]和引用[2]中提到的信息,我们可以通过以下步骤实现字体大小的修改: 步骤1:获取所需大小的字模数据 - 使用取模工具(如pctolcd2002)生成指定大小的汉字和字符的点阵数据。 - 取模时需要注意设置点阵大小(比如16x16、24x24等)。 步骤2:创建自定义的字体 - 在MicroPython中,我们可以将取模得到的数据以字节数组的形式存储在字典或模块中。 - 例如,对于16x16的字体,每个汉字需要32字节(16行,每行2字节,共16*2=32字节)。 步骤3:修改显示函数 - 使用自定义的字体数据替换默认的8x8字体。 - 在显示文本时需要根据字体的高度和宽度整显示位置。 以下是一个具体的代码示例,展示如何显示16x16的汉字: 1. 首先,取模得到汉字点阵数据(以16x16为例): 使用取模工具(如pctolcd2002)设置:阴码、逐列式、顺向、十六进制。 取模后得到的数据类似:0x00,0x00,0x7F,0xFC...(共32个字节) 2. 在代码中定义字体: ```python font16 = { '你': [0x00,0x00,0x7F,0xFC,...,0x00,0x00], # 32个十六进制数 '好': [0x00,0x00,0x7F,0xFC,...,0x00,0x00], # ...其他汉字 } ``` 3. 编写显示16x16汉字的函数: ```python def text16(string, x, y): for char in string: if char in font16: # 获取字模数据 data = font16[char] # 将16x16的点阵画到屏幕上 # 16x16点阵,每行2个字节(16位),共16行 for row in range(16): # 每行两个字节 byte1 = data[row*2] byte2 = data[row*2+1] # 处理两个字节的每一位 for col in range(8): if byte1 & (0x80 >> col): oled.pixel(x+col, y+row, 1) else: oled.pixel(x+col, y+row, 0) for col in range(8): if byte2 & (0x80 >> col): oled.pixel(x+col+8, y+row, 1) else: oled.pixel(x+col+8, y+row, 0) # 每个汉字占16个像素宽度,移动到下一个汉字的位置 x += 16 ``` 4. 使用该函数显示文本: ```python oled.fill(0) text16("你好", 0, 0) oled.show() ``` 注意:这种方法只能显示预定义字中的汉字,且需要事先取模。对于英文字符,也可以用同样的方式定义,或者使用多个不同大小的英文字体。 另外,也可以使用现成的支持多字体大小的,例如`micropython-font-to-py`工具可以将字体文件转换为MicroPython的字体,然后在ssd1306中使用。但是这种方法会增加内存占用。 如果只是需要放大英文字符,还有一种简单的方法:使用内置的framebuf提供的缩放功能,但ssd1306本身并不支持。我们可以自己实现缩放,例如将每个像素放大为2x2: 示例(将8x8字符放大为16x16): ```python def text_scaled(string, x, y, scale=2): # 原始字体大小为8x8,放大倍数scale for char in string: # 获取原始字符点阵(内置字体) # 这里我们假设使用内置的8x8字体,但是MicroPython的ssd1306默认字体是只读的,所以我们无法直接获取点阵。 # 因此,我们可能需要自己提供一个8x8字体,或者使用framebuf内置的字体(通过framebuf.FrameBuffer.text方法) # 但是,由于ssd1306并没有提供直接读取字符点阵的函数,所以这种方法比较复杂。 # 替代方案:先在framebuf中绘制到一个临时的8x8的FrameBuffer,然后读取每个像素并放大绘制到oled上。 # 这种方法比较慢,仅适用于少量字符。 pass ``` 由于内置字体的点阵数据不易获取,所以推荐使用自定义字体的方式。 总结:修改字体大小的关键在于使用自定义字,通过取模工具得到不同大小的字体点阵,然后在代码中实现对应的显示函数。 引用[1]中提到的中文下载站和取模工具,以及引用[2]中关于显示汉字的示例,都可以帮助我们完成这个任务。 相关问题: 1. 如何在MicroPython中显示自定义图形? 2. 如何减小自定义字的内存占用? 3. 如何在ssd1306上实现滚动文字效果? </think> 在 MicroPython ESP32 中修改 SSD1306 OLED 屏的字体大小,可以通过以下方法实现: ### 解决方案:使用自定义字缩放字体 SSD1306 默认仅支持 8×8 像素的英文字体。要修改字体大小,需通过字模工具生成自定义字体: #### 1. **获取字体点阵数据** ```python # 示例:16×16 点阵"微"字取模数据 font_16x16 = { '微': [0x00,0x00,0x27,0xF8,0x12,0x08,0x12,0x10, 0x82,0x20,0x42,0x20,0x41,0x40,0xF0,0x80, 0x10,0xFE,0x10,0x92,0x10,0x92,0x10,0x92, 0x1F,0x92,0x10,0xFE,0x10,0x00,0x10,0x00] # 32字节数据 } ``` **取模工具使用要点**: - 工具:PCtoLCD2002 (引用[1][^1]) - 设置: - 字体:选择需要的字体和字号(如微软雅黑16px) - 取模方式:阴码 + 逐列式 + C51格式 - 字符编码:UTF-8 (引用[1][^1]) #### 2. **实现字体渲染函数** ```python def draw_scaled_text(oled, text, x, y, scale=1): for char in text: if char in font_16x16: # 检查自定义字 data = font_16x16[char] for row in range(16): # 字体高度16px for col in range(8): # 每字节8位(半字符) pixel = data[row * 2 + col//8] & (0x80 >> (col % 8)) if pixel: # 缩放绘制:每个点绘制为 scale×scale 方块 oled.fill_rect( x + col * scale, y + row * scale, scale, scale, 1) x += 16 * scale # 移动到下一个字符位置 else: # 默认8px字符缩放处理 oled.text(char, x, y, 1) x += 8 * scale ``` #### 3. **完整使用示例** ```python from machine import Pin, SoftI2C import ssd1306 i2c = SoftI2C(scl=Pin(22), sda=Pin(21)) oled = ssd1306.SSD1306_I2C(128, 64, i2c) # 绘制缩放文本 (2倍放大) draw_scaled_text(oled, "温度:25℃", 0, 0, scale=2) oled.show() ``` ### 关键注意事项 1. **字内存优化**: - 仅存储所需字符(如常用汉字)减少内存占用 - 使用`freeze`工具将字编译进固件 (引用[2][^2]) 2. **缩放限制**: - 整数倍缩放效果最佳(`scale=2`或`3`) - 非整数缩放需插值算法(会显著增加复杂度) 3. **性能建议**: ```python # 区域刷新优化 (仅刷新文本区域) oled.fill_rect(0, 0, 128, 16, 0) # 先清除文本区域 draw_scaled_text(oled, "新内容", 0, 0, 2) oled.show() ``` ### 替代方案:矢量字体渲染 对于复杂需求可使用`micropython-ufont`: ```python import ufont # 加载TTF字体文件 font = ufont.BDFont("msyh.ttf", size=16) # 直接渲染文本 font.text(oled, "Micropython", 0, 0, 1) ``` > 需预先将TTF字体转换为`.bdf`格式(工具:`otf2bdf`) --- ### 字体缩放效果对比 | 缩放比例 | 字符尺寸 | 适用场景 | 优缺点 | |---------|---------|---------|-------| | `scale=1` | 8×8px | 全屏显示 | 原生支持快⚡️但字小 | | `scale=2` | 16×16px | 标题显示 | 清晰度高✨占4倍内存 | | `scale=3` | 24×24px | 大字标语 | 视觉冲击强🔥易出锯齿 | 通过自定义字和缩放渲染,即可突破默认字体限制[^1][^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值