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
我如何编写一个不和谐的机器人,以便它能够使用 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 所说,不支持将模式为 PA
的 Image
对象保存为 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。非常感谢您的回复!
区分PNG
和GIF
非常容易。加载后只需检查avatar.format
。尽管如此,处理GIF
包括调整大小、添加自定义Alpha 通道/透明度将比静态PNG
困难得多。有很多关于该主题的问答。以上是关于python PIL个人使用记录的主要内容,如果未能解决你的问题,请参考以下文章