如何裁剪Discord用户头像并使裁剪区域透明生成圆形头像
问题根源
生成的头像边缘出现黑色区域是两个代码逻辑错误导致的:
- 你先给原始128尺寸的头像添加圆形alpha蒙版,之后才执行放大到382*298的操作,图片缩放过程会破坏原有alpha通道的抗锯齿效果,透明区域会被默认填充为黑色
- 调用
paste()方法将头像粘贴到通缉令底图时,没有传入alpha蒙版参数,Pillow会直接将透明区域按黑色像素渲染到底图上
修复方案
调整图片处理顺序,先完成头像缩放再生成对应尺寸的圆形蒙版,粘贴时显式传入蒙版参数即可解决黑边问题,修复后完整代码如下:
import discord from discord.ext import commands from PIL import Image, ImageDraw from io import BytesIO @bot.command() async def wanted(ctx, user: discord.Member = None): if user is None: user = ctx.author # 读取通缉令素材 wanted = Image.open("wanted.jpg").convert("RGBA") # 获取目标用户头像,调大原始尺寸提升缩放后清晰度 asset = user.avatar_url_as(size=256) img_data = BytesIO(await asset.read()) pfp = Image.open(img_data).convert("RGBA") # 第一步先把头像缩放到目标粘贴尺寸 target_pfp_size = (382, 298) pfp = pfp.resize(target_pfp_size, Image.LANCZOS) # 生成和缩放后头像尺寸完全匹配的圆形蒙版 mask = Image.new("L", target_pfp_size, 0) draw = ImageDraw.Draw(mask) # 内缩2像素绘制圆形,避免边缘裁切生硬产生锯齿 draw.ellipse((2, 2, target_pfp_size[0]-2, target_pfp_size[1]-2), fill=255) # 粘贴时传入mask参数,圆形外区域自动透明,不会产生黑边 wanted.paste(pfp, (40, 221), mask=mask) # 保存生成结果并发送 wanted.save("profile.png") await ctx.reply(file=discord.File("profile.png")) bot.run("你的机器人Token")
优化说明
- 移除了代码中未使用的
matplotlib、numpy、ImageFont、ImageOps等冗余导入,减少不必要的依赖加载 - 头像拉取尺寸从128调整为256,缩放后清晰度更高,不会出现模糊问题
- 圆形蒙版绘制时留了2px内边距,边缘抗锯齿效果更自然,不会出现生硬的裁切感
- 所有图片统一转RGBA模式处理,避免不同格式图片通道不匹配导致的渲染异常
内容的提问来源于stack exchange,提问作者Sierra
相关产品推荐
相关产品推荐

