python PIL个人使用记录

Posted 南风丶轻语

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python PIL个人使用记录相关的知识,希望对你有一定的参考价值。

python PIL个人使用记录

1、gif转png

def gif_to_png(filename: str):
    """
    gif图片一帧一帧转换为很多png图片
    :param filename:
    :return:
    """
    filename = filename.strip()
    filename = os.path.abspath(filename)
    assert os.path.splitext(filename)[-1].lower() == \'.gif\', f\'文件后缀不是.gif "filename"\'  # 是否是.gif后缀
    assert os.path.isfile(filename), f\'不存在文件"filename"\'  # 是否存在文件
    index = 1
    basename = os.path.basename(filename)
    basename_without_suffix = basename.replace(os.path.splitext(filename)[-1], \'\')

    image = Image.open(filename)
    iterator: Iterator = ImageSequence.Iterator(image)  # GIF图片流的迭代器
    save_path = os.path.join(\'.\', \'image\', basename_without_suffix)
    save_path = os.path.abspath(save_path)
    if os.path.exists(save_path):
        shutil.rmtree(save_path)
    if not os.path.exists(save_path):
        os.makedirs(save_path)
    for img in iterator:  # img 是 GifImageFile对象
        save_name = os.path.join(save_path, f\'frame_index.png\')
        img.save(save_name)
        index += 1
    print(f"save to dir \'save_path\'")
    return save_path

2、png转gif

def png_to_gif(path: str, filename: str):
    """
    遍历文件夹图片, 按照名称排序 然后合成gif图片
    :param path:
    :param filename:
    :return:
    """
    path = os.path.abspath(path.strip())
    assert os.path.isdir(path), f\'不存在文件夹"path"\'  # 是否存在文件

    filename = os.path.abspath(filename.strip())
    if not os.path.exists(os.path.dirname(filename)):
        os.makedirs(os.path.dirname(filename))

    files = os.listdir(path)
    files.sort(key=lambda x: int(str(x).replace(\'frame_\', \'\').replace(\'.png\', \'\')))
    frames = []  # 读入缓冲区
    for img in files:
        f = os.path.join(path, img)
        assert os.path.splitext(f)[-1].lower() == \'.png\', f\'文件后缀不是.png "filename"\'  # 是否是.png后缀
        frames.append(imageio.imread(f))
    imageio.mimsave(filename, frames, \'gif\', duration=0.02)
    print(f"save to \'filename\'")
    return filename

学习链接 https://www.cnblogs.com/fly-kaka/p/11694011.html

3、获取所有像素点的颜色

def get_all_pixel(file):
    """
    获取所有的像素点的颜色
    :param file:
    :return:
    """
    img = Image.open(file)
    width = img.size[0]
    height = img.size[1]
    ret = list()
    for x in range(width):
        for y in range(height):
            pixel = img.getpixel((x, y))
            print(f"x,y -----> pixel")
            ret.append(dict(x=x, y=y, pixel=pixel))
    return ret

github

我如何编写一个不和谐的机器人,以便它能够使用 python PIL 发布修改后的 gif 和/或 png 个人资料图片?

【中文标题】我如何编写一个不和谐的机器人,以便它能够使用 python PIL 发布修改后的 gif 和/或 png 个人资料图片?【英文标题】:How do I code a discord bot so it becomes able to post modified gif and/or png profile picture using python PIL? 【发布时间】:2021-05-17 19:58:46 【问题描述】:

此代码适用于个人资料图片中具有.png 格式的用户,但是,对于具有.gif 动画个人资料图片的用户,该代码不起作用。它给出了这个错误OSError(f"cannot write mode mode as PNG") from e OSError: cannot write mode PA as PNG

我尝试将所有.png 更改为.gif,但仍然遇到问题。

ValueError: image has wrong mode

这是上述代码,仅适用于 .png 格式。

class avatar(commands.Cog):
    def __init__(self, client):
        self.client = client

    @commands.Cog.listener()
    async def on_member_join(self, member):
        guild = self.client.get_guild(GUILD_ID)
        general_channel = guild.get_channel(CHANNEL_ID)


        url = requests.get(member.avatar_url)
        avatar = Image.open(BytesIO(url.content))
        avatar = avatar.resize((285,285));
        bigsize = (avatar.size[0] * 3,  avatar.size[1] * 3)
        mask = Image.new('L', bigsize, 0)
        draw = ImageDraw.Draw(mask)
        draw.ellipse((0, 0) + bigsize, fill=255)
        mask = mask.resize(avatar.size, Image.ANTIALIAS)
        avatar.putalpha(mask)

        output = ImageOps.fit(avatar, mask.size, centering=(1420, 298))
        output.putalpha(mask)
        output.save('avatar.png')

        img = Image.open('welcomealpha.png')
        img.paste(avatar,(1408,265), avatar)
        img.save('wel.png')

        file = discord.File('wel.png')
        channel = self.client.get_channel(CHANNEL_ID)
        await channel.send(file=file)
        guild = self.client.get_guild(GUILD_ID)
        channel = guild.get_channel(CHANNEL_ID)

会不会是机器人不知道如何区分 .gif.png ?如果是这种情况,对于机器人识别每个新用户具有哪种个人资料图片格式以便根据其格式操作图像/gif 的最有效方法是什么?

【问题讨论】:

【参考方案1】:

这里的错误信息很清楚:您原来的Image 对象有mode P,即它是一个调色板图像。像您一样添加 Alpha 通道时,您将获得模式 PA。正如 Pillow 所说,不支持将模式为 PAImage 对象保存为 PNG。由于您只想保存到一些静态的PNG 而没有任何动画,我假设在开始时将Image 对象转换为模式RGB 是保存的,这样您就会得到一个RGBA 模式Image 对象最后,可以保存为PNG,没有任何问题。

我从您的代码中摘录了以下内容并将转换添加到模式RGB

from PIL import Image, ImageDraw, ImageOps

avatar = Image.open('homer.gif').convert('RGB')
avatar = avatar.resize((285, 285))
bigsize = (avatar.size[0] * 3,  avatar.size[1] * 3)
mask = Image.new('L', bigsize, 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((0, 0) + bigsize, fill=255)
mask = mask.resize(avatar.size, Image.ANTIALIAS)
avatar.putalpha(mask)

output = ImageOps.fit(avatar, mask.size, centering=(1420, 298))
output.putalpha(mask)
output.save('avatar.png')

GIF 输入是荷马;对应的Image 对象的模式为P

导出的PNG如下;好像是GIF的第一帧:

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.9.1
Pillow:        8.1.0
----------------------------------------

【讨论】:

首先,我要感谢您花时间回答我的问题!这对解决第一个问题有很大帮助,即机器人不会响应图像。是否有可能以能够区分 .gif.png 文件的方式对 Discord Bot & Pillow 进行编码?这里的想法是有两个输出——如果用户头像是.gif,那么最终输出的图像是一个 gif,因此他/她的头像可以动画。如果用户的头像是.png,那么它的输出就是png。非常感谢您的回复! 区分PNGGIF 非常容易。加载后只需检查avatar.format。尽管如此,处理GIF 包括调整大小、添加自定义Alpha 通道/透明度将比静态PNG 困难得多。有很多关于该主题的问答。

以上是关于python PIL个人使用记录的主要内容,如果未能解决你的问题,请参考以下文章

Python 学习记录Pycharm导入PIL包

使用 PIL 在 Python 中压缩 PNG 图像

屏幕截图小工具的制作过程问题记录 python PIL pynput pyautogui pyscreeze

python图像库PIL的完美替代品-Pillow

『Python』PIL图像处理_矩阵转化

pgmagick,pil不保存图片并且获取图片二进制数据记录