我正在尝试将彩色表情符号作为叠加层添加到图像上,但表情符号似乎一直以黑白渲染,并且也是透明的:
这就是我当前正在使用的:
def add_text_overlay(image_path, text, font_path, emoji_font_path, font_size, text_spacing, x_padding, output_path,
text_position, offset_x, offset_y):
with PILImage.open(image_path) as img:
img = crop_and_resize(img, 1080, 1440)
draw = ImageDraw.Draw(img)
font = ImageFont.truetype(font_path, font_size)
# Load the emoji font using PIL
emoji_font = None
try:
emoji_font = ImageFont.truetype(emoji_font_path, 137) # Adjust pixel size as needed
except OSError as e:
logging.error(f"Unable to load the emoji font: {e}")
logging.error(f"Path checked: {os.path.abspath(emoji_font_path)}")
emoji_font = font # Fallback to regular font if emoji font fails
lines = wrap_text(text, 28)
fixed_line_height = font_size + text_spacing
total_text_height = fixed_line_height * len(lines)
initial_text_y = (img.height - total_text_height) / 2 + offset_y
for i, line in enumerate(lines):
text_bbox = draw.textbbox((0, 0), line, font=font)
text_width = text_bbox[2] - text_bbox[0]
if text_position == 'left':
text_x = x_padding + offset_x
elif text_position == 'right':
text_x = img.width - text_width - x_padding + offset_x
else:
text_x = (img.width - text_width) / 2 + offset_x
text_y = initial_text_y + i * fixed_line_height
if text_x < 0:
text_x = 0
if text_x + text_width > img.width:
text_x = img.width - text_width
# Draw each character with the appropriate font
for char in line:
char_font = emoji_font if is_emoji(char) else font # Use emoji font for emoji characters
draw.text((text_x, text_y), char, font=char_font, fill="black")
text_x += char_font.getbbox(char)[2] # Update this line to use getbbox
img.save(output_path)
我有“无效的像素大小”错误有一段时间,直到我将像素大小更改为 137。然后它只绘制了单色透明表情符号。
问题在于正在使用
fill="black"
为表情符号着色。为了保留表情符号的颜色,需要对文本和表情符号使用不同的绘制方法。
可以使用 PIL 的
Image.alpha_composite()
方法将表情符号作为单独的图像绘制在文本的顶部。这将保留表情符号的原始颜色和透明度。
以下是更新后的代码:
def add_text_overlay(image_path, text, font_path, emoji_font_path, font_size, text_spacing, x_padding, output_path,
text_position, offset_x, offset_y):
with PILImage.open(image_path) as img:
img = crop_and_resize(img, 1080, 1440)
draw = ImageDraw.Draw(img)
font = ImageFont.truetype(font_path, font_size)
# Load the emoji font using PIL
emoji_font = None
try:
emoji_font = ImageFont.truetype(emoji_font_path, 137) # Adjust pixel size as needed
except OSError as e:
logging.error(f"Unable to load the emoji font: {e}")
logging.error(f"Path checked: {os.path.abspath(emoji_font_path)}")
emoji_font = font # Fallback to regular font if emoji font fails
lines = wrap_text(text, 28)
fixed_line_height = font_size + text_spacing
total_text_height = fixed_line_height * len(lines)
initial_text_y = (img.height - total_text_height) / 2 + offset_y
for i, line in enumerate(lines):
text_x = x_padding + offset_x
text_y = initial_text_y + i * fixed_line_height
for char in line:
if is_emoji(char):
# Draw emoji as a separate image
emoji_img = Image.new("RGBA", emoji_font.getsize(char))
emoji_draw = ImageDraw.Draw(emoji_img)
emoji_draw.text((0, 0), char, font=emoji_font, fill="white") # Use white or any color you prefer for emoji
# Calculate emoji position and paste onto the main image
img.paste(emoji_img, (text_x, text_y), emoji_img)
text_x += emoji_img.width
else:
# Draw regular text
draw.text((text_x, text_y), char, font=font, fill="black")
text_x += font.getbbox(char)[2]
img.save(output_path)
在这个更新后的代码中:
- 我们为每个表情符号字符创建了一个新的
Image
对象。
- 我们在这个新图像上绘制了表情符号,填充颜色为白色(或喜欢的任何颜色)。
- 然后,我们使用
img.paste()
将表情符号图像粘贴到主图像上的计算位置。
此方法应该在不影响其颜色或透明度的情况下正确呈现表情符号。
标签:python,python-imaging-library From: 78789921