afrcmg 2022-07-12 14:18 采纳率: 87.5%
浏览 63
已结题

pygame字体相关问题

我想要在pygame中,实现一段话(每一行都等宽)的信息展示。
能否推荐一下比较好的做法,能实现比较规整的显示一段话?发信息也可以

目前我的做法是,比如txt是一段话,我先把txt中的换行符之类去掉。
然后,根据想要的段落的总宽度width和字体大小size,计算出一行有多少字。

然后根据一行字数,将txt切成若干单行,每行分别用font.render变成图像,并记录下它的位置。
然后把这些图像连同位置,作为返回值。
下面是代码:

def cut_txt(txt, num, labels=[]):
    """将字符串txt,每num个字符进行切片,返回切片的列表,labels应为空"""
    txt = re.sub(r"\s", '', txt)
    if len(txt) > num:
        labels.append(txt[:num])
        return cut_txt(txt[num:], num, labels)
    else:
        labels.append(txt)
        return labels


def create_multi_label(txt, width=400, size=40, pos=(0, 0), color=(255, 255, 255)):
"""将一段话txt,以宽度width,字高size,坐标pos,颜色color的形式表现出来,返回每行字的图片,及其位置坐标"""
    font = pygame.font.SysFont(C.FONT, size)
    columns = ceil(width / size)
    txt_list = cut_txt(txt, columns)
    labels = []
    for i in range(len(txt_list)):
        label_img = font.render(txt_list[i], True, color)
        # label_img = pygame.transform.scale(label_img, (width, size))
        p = (pos[0], pos[1] + i * size)
        # labels.append((surface, p))
        labels.append((label_img, p))
    return labels

但是结果是这样的:

img

就是说,存在以下问题:
1.每行的字数一样,但字数一样不代表宽度一样,特别是有符号(符号还分中英文)、数字时,所以最终无法实现很规整的效果。
2.字母也比较奇怪,比如图中那个q,它明显位置比较低。当然这一条不重要,在能解决问题1时可以顺便看看。

我想了一下,或者可以计算一段话的实际宽度(比如2个数字的宽度大概等于1个汉字),然后根据宽度重新排版,但是稍微一想就觉得好麻烦,是否能有朋友帮忙写下,或是提供思路——比如流程,用到的模块等

  • 写回答

2条回答 默认 最新

  • 脚踏南山 2022-07-12 17:18
    关注

    如有帮助,敬请采纳,你的采纳是我前进的动力,O(∩_∩)O谢谢!!!!!!!!

    img

    
    import numpy as np
    import cv2 as cv
    from PIL import Image
    from PIL import ImageDraw
    from PIL import ImageFont
    
    def test_fsf():
        font_path = '/sdb1/数据/知识/字体/fzztk/4091_方正楷体_GBK.TTF'
        img_path = '/sdb1/数据/知识/壁纸和文本/4K星云宇宙空间壁纸/4K壁纸 (2).jpg'
        txt_str = r"""就是说,存在以下问题:
            1.每行的字数一样,但字数一样不代表宽度一样,特别是有符号
            (符号还分中英文)、数字时,所以最终无法实现很规整的效果。
            2.字母也比较奇怪,比如图中那个qAahQ(字母是三线格书写),它明显位置比较低。
            当然这一条不重要,在能解决问题1时可以顺便看看。
            我想了一下,或者可以计算一段话的实际宽度(比如2个数字的宽度大概等于1个汉字),
            然后根据宽度重新排版,但是稍微一想就觉得好麻烦,是否能有朋友帮忙写下,
            或是提供思路——比如流程,用到的模块等"""
    
        image = Image.open(img_path)
        draw = ImageDraw.Draw(image)
        font_size = 40
        font_color = (255, 0, 0)
        # 配置font
        kumo_font = ImageFont.truetype(font_path, size=font_size)
        每行宽度 = 1000
        show_label = ''
        h_start = 0  # 字体起始h位置
        w_start = 100  # 字体起始w位置
        font_location = 0
    
        for txt in txt_str:
            txt = txt.strip()
            if len(txt) == 0:
                continue
            show_label += txt
            # 计算文字大小
            font_w, font_h = draw.textsize(show_label, kumo_font)
            if font_w >= 每行宽度:
                font_location += font_h
                # 画文字
                (left, top) = (w_start, h_start + font_location)
                draw.text((left, top), show_label, font_color, font=kumo_font)
                # 重置变量
                show_label = ''
        img_np = np.array(image)
        cv.imshow('', img_np)
        cv.waitKey()
        cv.destroyAllWindows()
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 7月21日
  • 已采纳回答 7月13日
  • 创建了问题 7月12日

悬赏问题

  • ¥15 Sharepoint JS开发 付费技术指导
  • ¥15 输入程序运行仿真后,烟雾值不实时检测,变成固定值
  • ¥20 数据排序,可选择排序方向
  • ¥15 修改一下代码,考虑进程到达时间不同的情况
  • ¥15 帮我看看这是个啥题,带解题过程和结果,条件如下FCF = 290471.33 g1 = 15% r = 8% g2 = 4% n = 5
  • ¥15 edem模拟颗粒不显示或者生成失败
  • ¥15 Python代码编写
  • ¥15 php 将rtmp协议转hls协议,无法播放
  • ¥20 python代码编写
  • ¥20 使用MPI广播数据遇到阻塞