我有图像和蓝色像素列表。我想遍历蓝色像素,将它们更改为红色,并由此生成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它只是一条红线,没有任何动画
答案 0 :(得分:1)
有很多方法可以使蓝色像素变成红色-并且在性能,可读性,可维护性方面,使用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)
这大约是5毫秒,快了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倍。
答案 1 :(得分:1)
所以问题是您没有使其动画化吗?
在循环中,您不断更新相同的Image
并将相同的Image
放入列表,这意味着最后,列表中的所有条目都指向相同的{{1} },全为红色。在for循环中,执行Image
而不是images.append(im)
。