如何在Pillow中将图片裁剪并粘贴到椭圆区域内?
实现头像嵌入椭圆区域的解决方案
可以实现这个需求,你需要通过创建椭圆遮罩的方式粘贴头像,这样头像只会显示在椭圆内部,不会覆盖椭圆的红色边框。
核心思路
- 确定椭圆的实际区域:你绘制的椭圆坐标为
(280, 280, 530, 530),对应一个250×250的正圆形区域。 - 处理头像:将头像缩放/裁剪至与椭圆区域匹配的尺寸。
- 创建椭圆遮罩:生成一个和椭圆大小一致的透明图像,在遮罩上绘制白色椭圆(作为显示区域),其余部分保持透明。
- 使用遮罩粘贴头像:通过
paste方法的mask参数,让头像仅在遮罩的白色区域显示。
修改后的完整代码
from PIL import ImageFont, ImageDraw, Image from IPython.display import Image as jpImg import textwrap # 初始化画布和绘图对象 image = Image.new('RGB', (1200, 630), color='white') draw = ImageDraw.Draw(image) # 文本内容 txt = "This is the title of this entry This is the title of this entry" list_sections = ['Some section text will go here', 'Some section text will go here 1', 'Some section text will go here 2','Some section text will go here 3', 'Some section text will go here 4'] category_list = ['category 1', 'category 2', 'category 3', 'category 4'] # 绘制红色斜线区域 draw.line((10,960,1700, 75), fill='red', width=600) # 自动匹配文本字体大小 img_fraction = 0.50 fontsize = 1 font = ImageFont.truetype("/Library/Fonts/Arial.ttf", fontsize) while font.getsize(txt)[0] < img_fraction*image.size[0]: fontsize += 1 font = ImageFont.truetype("/Library/Fonts/Arial.ttf", fontsize) fontsize -= 1 font = ImageFont.truetype("/Library/Fonts/Arial.ttf", fontsize) # 标题字体 font_title = ImageFont.truetype("/Library/Fonts/Arial.ttf", 50) # 绘制左侧文本列表 top = 100 for section in list_sections: draw.text((35, top), section, font=font, fill="red") top += 40 # 绘制右侧分类列表 top = image.size[1] / 2 side = image.size[0] - 400 for cat in category_list: draw.text((side, top), cat, font=font, fill="white") top += 40 # 绘制分类列表的大括号 font_title_parent_0 = ImageFont.truetype("/Library/Fonts/Arial.ttf", 350) draw.text((side - 100, top-300), '{', font=font_title_parent_0, fill=(255, 255, 255, 128)) draw.text((side + 240, top-300), '}', font=font_title_parent_0, fill="white") # 绘制椭圆边框和填充 ellipse_coords = (280, 280, 530, 530) # 简化后的椭圆坐标 draw.ellipse(ellipse_coords, fill='white', outline="red", width=25) # 处理头像并嵌入椭圆 # 1. 打开头像并缩放至椭圆尺寸(250x250) avatar = Image.open('data/images/avatar.jpeg').resize((250, 250)) # 2. 创建椭圆遮罩 mask = Image.new('L', avatar.size, 0) mask_draw = ImageDraw.Draw(mask) mask_draw.ellipse((0, 0, avatar.size[0], avatar.size[1]), fill=255) # 3. 用遮罩粘贴头像到椭圆位置 image.paste(avatar, (ellipse_coords[0], ellipse_coords[1]), mask=mask) # 绘制标题文本 draw.text((10, 15), textwrap.shorten(txt, width=55, placeholder='..'), font=font_title, fill="red") # 保存并显示结果 image.save('data/images/final_card.png') jpImg(filename='data/images/final_card.png')
关键代码解释
ellipse_coords:明确椭圆的位置和尺寸,方便后续计算。- 头像缩放:
resize((250,250))让头像刚好填满椭圆内部区域。 - 遮罩创建:
mask是一个灰度图像,白色区域(255)表示允许头像显示,黑色区域(0)表示透明,这样粘贴时只有椭圆内的部分会显示。 paste方法的mask参数:指定遮罩后,头像只会在遮罩的白色区域显示,完美嵌入椭圆内,不会覆盖边框。
内容的提问来源于stack exchange,提问作者Kjobber
相关产品推荐
相关产品推荐

