簡體   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