2010-12-31 62 views
24

Tôi có 4 thư mục với hình ảnh cho hoạt ảnh. Tôi muốn lấy bộ ảnh và tạo ra một ảnh với 4 ảnh được sắp xếp thành một lưới 2x2 cho mỗi khung hình của hoạt ảnh.Thư viện hình ảnh Python: Cách kết hợp 4 hình ảnh vào lưới 2 x 2?

Mã của tôi cho đến nay là:

import Image 

fluid64 = "Fluid64_half_size/00" 
fluid128 = "Fluid128_half_size/00" 
fluid512 = "Fluid512_half_size/00" 
fluid1024 = "Fluid1024_half_size/00" 

out_image = "Fluid_all/00" 

for pic in range(1, 26): 
    blank_image = Image.open("blank.jpg") 

    if pic < 10: 
     image_num = "0"+str(pic) 
    else: 
     image_num = str(pic) 

    image64 = Image.open(fluid64+image_num+".jpg") 
    image128 = Image.open(fluid128+image_num+".jpg") 
    image512 = Image.open(fluid512+image_num+".jpg") 
    image1024 = Image.open(fluid1024+image_num+".jpg") 
    out = out_image + image_num + ".jpg" 

    blank_image.paste(image64, (0,0)).paste(fluid128, (400,0)).paste(fluid512, (0,300)).paste(fluid1024, (400,300)).save(out) 

Không chắc lý do tại sao nó không làm việc. Tôi gặp lỗi:

Traceback (most recent call last): 
    File "C:\Users\Casey\Desktop\Image_composite.py", line 24, in <module> 
    blank_image.paste(image64, (0,0)).paste(fluid128, (400,0)).paste(fluid512, (
ste(fluid1024, (400,300)).save(out) 
AttributeError: 'NoneType' object has no attribute 'paste' 
shell returned 1 

Mọi trợ giúp đều tuyệt vời. Cảm ơn!

Trả lời

37

Vấn đề duy nhất là "dán" không trả về đối tượng hình ảnh - nó thay đổi hình ảnh "trống" tại chỗ.

Vì vậy, khi dán thứ hai được gọi (hình ảnh sử dụng hình ảnh fuild128), nó sẽ cố gắng được áp dụng trên "Không" - đó là giá trị trả về của hình ảnh đầu tiên.

Nếu đó là vấn đề duy nhất mà bạn đang có, chỉ cần thực hiện một cuộc gọi dán trên mỗi dòng, như thế này:

blank_image.paste(image64, (0,0)) 
blank_image.paste(fluid128, (400,0)) 
blank_image.paste(fluid512, (0,300)) 
blank_image.paste(fluid1024, (400,300)) 
blank_image.save(out) 

Mặc dù có vẻ khả năng bạn sẽ cần phải mở rộng quy mô mỗi hình ảnh để phù hợp với định dạng của họ như tốt. Và mã của bạn cho biến "image_num" là không cần thiết. Python là thực sự tốt với chuỗi - chỉ cần làm một cái gì đó như thế này:

image64 = Image.open(fluid64 + "%02d.jpg" % pic) 
10

Bạn có thể muốn sử dụng một cái gì đó dọc theo dòng:

blank_image = Image.new("RGB", (800, 600)) 

này sẽ tạo ra một lĩnh vực mới trong bộ nhớ mà bạn có thể tạo hình ảnh của bạn. Sau đó, bạn có thể dán hình ảnh vào đó.

Sau đó, bạn sẽ cần phải lưu nó ra một lần nữa sau này với:

blank_image.save("blank.jpg") 
+1

Đây không phải là những gì là " sai "trong mã - mặc dù ông woudl cũng được hưởng lợi từ nó. – jsbueno

+0

Vâng, tôi nhận thấy điều gì đã thực sự "sai" sau đó. Tôi nhìn vào dấu vết và có vẻ như blank_image đã không được định nghĩa đúng cách. Vì vậy, tôi vừa đưa ra giả định. Nó khá muộn ở đây sau khi tất cả :) –

+0

Trường hợp sử dụng của tôi là tạo một hình ảnh mới với kích thước động, ghép các phân đoạn với nhau thành hình ảnh trống mới, vì vậy điều này rất hữu ích. +1 –

4

đọc được thông báo lỗi:

AttributeError: 'NoneType' object has no attribute 'paste' 

Điều này có nghĩa bạn đã cố gắng để gọi .paste vào cái gì đó là loại NoneType, tức là đối tượng None.

Image.paste trả về Không có. Bạn không thể "chuỗi" các cuộc gọi cùng nhau như vậy trừ khi các chức năng được thiết kế đặc biệt để hỗ trợ nó và Image.paste thì không. Bạn nhận được một lỗi nói về NoneType vì hàm được viết không trả về bất kỳ thứ gì và mọi thứ trong Python trả lại None theo mặc định nếu không có gì khác được trả về một cách rõ ràng.) được coi là Pythonic: phương thức trả về giá trị mới hoặc sửa đổi self và trả lại None. Vì vậy, cái gọi là "giao diện thông thạo" không được sử dụng khi các chức năng có tác dụng phụ - Pythonistas xem xét rằng có hại. Trả lại None là một cảnh báo rằng hàm có các tác dụng phụ. :)

Chỉ cần thực hiện bốn cuộc gọi .paste riêng biệt.

1

Không giống như PIL API copy, crop, resize hoặc rotate mà trả về một đối tượng Image, paste lợi nhuận None, giúp ngăn chặn các cuộc gọi phương pháp xích. Thiết kế API không thuận tiện.

0

con số Lát trong một lưới 2-by-2 có thể dễ dàng đạt được với các append_images chức năng quy định tại trả lời https://stackoverflow.com/a/46623632/8738113

này Ví dụ:

img1 = append_images([image64, image128], direction='horizontal') 
img2 = append_images([image512, image1024], direction='horizontal') 
final = append_images([img1, img2], direction='vertical') 
final.save("Fluid_all/00.jpg") 
Các vấn đề liên quan