You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Pillow圆角矩形绘制异常:Discord机器人等级卡经验条被截断

问题根源

你遇到的圆角截断问题来自两个原因:

  • 当已填充的进度条总宽度(length - 起始x坐标40)小于2倍圆角半径(你设置的15,两倍就是30px)时,Pillow的rounded_rectangle方法无法正常绘制完整圆角,会自动削平边角
  • 你同时给背景条和进度条都加了外描边,两层描边重叠也会导致边缘显示异常
解决方法

你可以按下面的方案修改代码:

  1. 动态调整进度条的圆角半径,确保半径永远不超过进度条宽度的一半
  2. 拆分填充和描边的绘制逻辑,先绘制背景填充、再绘制进度填充,最后统一给整个经验条加外描边,避免重叠

修改后的代码参考:

def draw(self, user: str, rank: str, level: str, xp: str, needed_xp: str, profile_bytes: BytesIO) -> BytesIO:
        
    profile_bytes = Image.open(profile_bytes)
    im = Image.new('RGBA', (800, 200), (44, 44, 44, 255))

    im_draw = ImageDraw.Draw(im)
    im_draw.text((154, 5), user, font=self.font, fill=(255, 255, 255, 255))

    rank_text = f'Rank:  #{rank}'
    im_draw.text((154, 37), rank_text, font=self.medium_font, fill=(255, 255, 255, 255))

    xp_text = f'Level: {level}'
    im_draw.text((154, 62), xp_text, font=self.small_font, fill=(255, 255, 255, 255))

    xp_text = f'Experience: {xp}/{needed_xp}'
    im_draw.text((154, 87), xp_text, font=self.small_font, fill=(255, 255, 255, 255))

    # 先画经验条背景填充,不带描边
    im_draw.rounded_rectangle((40, 180, 440, 150), fill=(64, 64, 64, 255), radius=15)
    
    length = 40 + int(xp)/int(needed_xp)*400
    # 计算进度条宽度,动态调整圆角半径
    progress_width = length - 40
    radius = 15 if progress_width >= 30 else progress_width / 2
    # 画进度填充,不带描边
    im_draw.rounded_rectangle((40, 180, length, 150), fill=(221, 221, 221, 255), radius=radius)
    
    # 最后统一画整个经验条的外描边
    im_draw.rounded_rectangle((40, 180, 440, 150), outline=(92, 23, 47, 255), width=3, radius=15)
    
    im.paste(profile_bytes, (10, 10))

    im.show()
额外优化建议

如果想要进度条右端永远保持圆角,哪怕进度为0的时候也显示小圆角,可以直接设置最小半径为2-3px,不会出现完全直角的情况。

内容的提问来源于stack exchange,提问作者Philskillz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 11:18:03