繁体   English   中英

Python枕头从像素制作gif

[英]Python pillow make gif from pixels

在此处输入图片说明

我有图像和蓝色像素列表。 我想遍历蓝色像素,将它们更改为红色并从中制作 gif。 所以它一定是一条线,因此颜色从蓝色变为红色,但出了点问题

im = Image.open(r"test2.png")
pixels = im.load()
images = []
blues = get_sorted_blues()  # See func below

for x, y in blues:
     ...:     pixels[x, y] = (255, 0, 0)
     ...:     images.append(im)

images[0].save('result.gif',
     ...:                save_all=True,
     ...:                append_images=images[1:],
     ...:                duration=100,
     ...:                loop=0)

def get_sorted_blues():
    ...:     blues = []
    ...:     for x in range(im.width):
    ...:         for y in range(im.height):
    ...:             if pixels[x, y] == (0, 0, 255):
    ...:                 blues.append([x, y])
    ...:     return sorted(blues)

result.gif 它只是一条红线,没有任何动画

有很多方法可以使蓝色像素变为红色 - 就性能、可读性和可维护性而言,使用for循环在列表中排名靠后。


这是使用“颜色矩阵”来交换红色和蓝色通道的一个:

from PIL import Image

# Open image
im = Image.open('lines.png')

# Define color matrix to swap the red and blue channels
# This says:
# New red   = 0*old red + 0*old green + 1*old blue + 0offset
# New green = 0*old red + 1*old green + 0*old blue + 0offset
# New blue  = 1*old red + 0*old green + 0*old blue + 0offset
Matrix = ( 0, 0, 1, 0, 
           0, 1, 0, 0, 
           1, 0, 0, 0)    

# Apply matrix
result = im.convert("RGB", Matrix)

在此处输入图片说明

这比for循环快 40 倍左右。 在我的机器上需要 1.07 毫秒,而使用for循环需要 40 毫秒。


这是一个使用 Numpy 查找蓝色像素并将它们变为红色的方法:

import numpy as np
from PIL import image

# Open image and make Numpy version
im = Image.open('lines.png')
na = np.array(im)

# Make all blue pixels red
na[ np.all(na[:,:]==[0,0,255], axis=2) ] = [255,0,0] 

# Convert back to PIL Image
result = Image.fromarray(na)

这在 5ms 时快了大约 8 倍。


这是一个使用 Numpy 将 RGB 排序反转为 BGR 的示例:

import numpy as np
from PIL import image

# Open image and make Numpy version
im = Image.open('lines.png')
na = np.array(im)

# Reverse channel ordering i.e. RGB -> BGR
BGR = na[...,::-1] 

# Convert back to PIL Image
result = Image.fromarray(BGR)

这在 4.4 毫秒时快了大约 9 倍。


这是我们使用 PIL 将图像拆分为其组成的 RGB 通道,然后以相反的顺序将它们合并回的一种方式:

from PIL import Image

# Open image
im = Image.open('lines.png')

# Split into R, G, B channels
R, G, B = im.split()

# Recombine in B, G, R order
result = Image.merge('RGB',(B,G,R))

这在 371 微秒时快了大约 100 倍。

所以问题是你没有让它动画?

在你的循环中,你不断更新同一个Image并将同一个Image放入列表中,这意味着最后,列表中的所有条目都指向同一个Image ,它都是红色的。 在 for 循环中,使用images.append(im.copy())而不是images.append(im) images.append(im.copy())

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM