gpt4 book ai didi

python - 我怎样才能用 python 的枕头使我裁剪的 gif 角透明?

转载 作者:行者123 更新时间:2023-12-04 13:50:58 26 4
gpt4 key购买 nike

我正在尝试使用 GaussianBlur 滤镜编辑来 self 的 discord 用户的 avatar 图像,将其裁剪成圆形并覆盖图像。所以所有这些都有效,但是裁剪后的 gif 有角,我不想要它们。它应该是透明的。我搜索了很多解决方案但找不到。我对使用 python 的 pillow 编码没有经验库,不知道如何修复它。

我当前的代码对此进行了转换(图片 1):

enter image description here

进入这个(图片 2):

enter image description here

但它应该是这样的(适用于静态图像,但 GIF 应该在最后保留它们的动画):

enter image description here

您可以看到我裁剪后的 GIF 图像有白角。如果图片 1 是 PNG,它不包含它们。那么如何去除这些白角呢?

这是我目前使用的代码:

    def crop_center(pil_img, crop_width, crop_height):
img_width, img_height = pil_img.size
return pil_img.crop(((img_width - crop_width) // 2,
(img_height - crop_height) // 2,
(img_width + crop_width) // 2,
(img_height + crop_height) // 2))

def crop_max_square(pil_img):
return crop_center(pil_img, min(pil_img.size), min(pil_img.size))

def mask_circle_transparent(pil_img, blur_radius, offset=0):
offset = blur_radius * 2 + offset
mask = Image.new("L", pil_img.size, 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((offset, offset, pil_img.size[0] - offset, pil_img.size[1] - offset), fill=255)
mask = mask.filter(ImageFilter.GaussianBlur(blur_radius))

result = pil_img.copy()
result.putalpha(mask)

return result


async def on_message(message):

if ".gif" in str(message.author.avatar_url):

frames = []

gif = Image.open(BytesIO(await message.author.avatar_url.read()))

for frame in ImageSequence.Iterator(gif):
frame = frame.copy()
frame = frame.convert("RGB")
frame = frame.resize((256, 256))
frame = mask_circle_transparent(frame, 4)

background = background.resize((256, 256))

frame.paste(background, (0, 0), background)
frames.append(frame)

print(str(frames))
frames[0].save('temp_images/result.gif', save_all=True, append_images=frames[1:])

else:

im_square = crop_max_square(Image.open(BytesIO(await message.author.avatar_url.read())).convert("RGB"))
im_square = im_square.resize((256, 256))
im_thumb = mask_circle_transparent(im_square, 4)

background = background.resize((256, 256))

im_thumb.paste(background, (0, 0), background)
im_thumb.show()

im_thumb.save('temp_images/result.png')

编辑:我现在测试了很多,我认为 frame = mask_circle_transparent(frame, 4) 是这里的问题,在我调用该函数之前我的框架是空白的,只是一个背景。我不知道为什么。显然,角落不是白色的,它是图像背景的颜色或类似的颜色?我不知道。

最佳答案

使用 GIF 格式无法制作平滑的边缘。 GIF 没有 alpha channel ,因此不支持部分透明度(来源:How to get better transparency with GIFs?)。这意味着您在静态图像上取得的结果无法在动态 GIF 上取得。

但是,可以使用以下答案使 GIF 中的背景透明:transparent background in gif using Python Imageio .您可以在下面找到生成的 GIF 和实现此结果的代码。 (我不得不跳过你代码的一些部分,因为我没有背景图片和 Discord 连接)。

transparent lizard

from PIL import Image, ImageDraw, ImageFilter, ImageSequence
import numpy as np

def crop_center(pil_img, crop_width, crop_height):
img_width, img_height = pil_img.size
return pil_img.crop(((img_width - crop_width) // 2,
(img_height - crop_height) // 2,
(img_width + crop_width) // 2,
(img_height + crop_height) // 2))

def crop_max_square(pil_img):
return crop_center(pil_img, min(pil_img.size), min(pil_img.size))

def mask_circle_transparent(pil_img, blur_radius, offset=0):
offset = blur_radius * 2 + offset
mask = Image.new("L", pil_img.size, 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((offset, offset, pil_img.size[0] - offset, pil_img.size[1] - offset), fill=255)
mask = mask.filter(ImageFilter.GaussianBlur(blur_radius))

result = pil_img.copy()
result.putalpha(mask)

return result


def transparent_frame(im):
# im = Image.open(path)
alpha = im.getchannel('A')

# Convert the image into P mode but only use 255 colors in the palette out of 256
im = im.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255)

# Set all pixel values below 128 to 255 , and the rest to 0
mask = Image.eval(alpha, lambda a: 255 if a <=128 else 0)

# Paste the color of index 255 and use alpha as a mask
im.paste(255, mask)

# The transparency index is 255
im.info['transparency'] = 255

return im


def on_message(message):

# if ".gif" in str(message.author.avatar_url):

frames = []

gif = Image.open('a.gif')

for frame in ImageSequence.Iterator(gif):
frame = frame.copy()
frame = frame.convert("RGB")
frame = frame.resize((256, 256))
frame = mask_circle_transparent(frame, 4)

# I did not have the background image that you used, so i skipped this part
# background = background.resize((256, 256))
# frame.paste(background, (0, 0), background)

# make transparent using the transparent_frame() function
frame = transparent_frame(frame)
frames.append(frame)

# print(str(frames))
frames[0].save('result.gif', save_all=True, append_images=frames[1:], optimize=False) # optimize must be false to preserve the transparent channel

# else:

# im_square = crop_max_square(Image.open(BytesIO(await message.author.avatar_url.read())).convert("RGB"))
# im_square = im_square.resize((256, 256))
# im_thumb = mask_circle_transparent(im_square, 4)

# background = background.resize((256, 256))

# im_thumb.paste(background, (0, 0), background)
# im_thumb.show()

# im_thumb.save('temp_images/result.png')

if __name__ == "__main__":
on_message('hi')

关于python - 我怎样才能用 python 的枕头使我裁剪的 gif 角透明?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69467726/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com