2009-12-26 42 views
18

Cách phát hiện xem hình ảnh PNG có kênh alpha trong suốt hay không sử dụng PIL?Làm cách nào để nhận giá trị alpha của hình ảnh PNG có PIL?

img = Image.open('example.png', 'r') 
has_alpha = img.mode == 'RGBA' 

Với mã ở trên, chúng tôi biết liệu hình ảnh PNG có kênh alpha không phải không nhưng cách lấy giá trị alpha?

tôi không tìm thấy một chìa khóa 'minh bạch' trong từ điển img.info như đã mô tả ở PIL's website

Tôi đang sử dụng Ubuntu và zlib1g, gói zlibc đã được cài đặt.

Trả lời

42

Để có được lớp alpha của một hình ảnh RGBA tất cả các bạn cần làm là:

red, green, blue, alpha = img.split() 

hoặc

alpha = img.split()[-1] 

Và có một phương pháp để thiết lập các lớp alpha:

img.putalpha(alpha) 

Khóa minh bạch chỉ được sử dụng để xác định e chỉ số độ trong suốt trong chế độ bảng màu (P). Nếu bạn muốn để trang trải các trường hợp minh bạch chế độ bảng như tốt và bao gồm tất cả trường hợp, bạn có thể làm điều này

if img.mode in ('RGBA', 'LA') or (img.mode == 'P' and 'transparency' in img.info): 
    alpha = img.convert('RGBA').split()[-1] 

Lưu ý: Phương pháp chuyển đổi là cần thiết khi image.mode là LA, vì một lỗi trong PIL.

2

img.info về toàn bộ hình ảnh - giá trị alpha trong hình ảnh RGBA là trên mỗi pixel, do đó, tất nhiên nó sẽ không nằm trong img.info. Phương thức getpixel của đối tượng hình ảnh, đưa ra tọa độ làm đối số, trả về một bộ tuple với giá trị của (bốn, trong trường hợp này) cho pixel đó - giá trị cuối cùng của giá trị sẽ là A, giá trị alpha.

+0

@ Alex, cảm ơn câu trả lời của bạn, có cách nào để xác định xem hình ảnh PNG có nền trong suốt không? – jack

+2

Trừ khi bạn hiếm khi làm điều này, 'getpixel' sẽ rất chậm. Bạn nên sử dụng 'getdata' hoặc' load' để truy cập hiệu năng cao. – carl

3
# python 2.6+ 

import operator, itertools 

def get_alpha_channel(image): 
    "Return the alpha channel as a sequence of values" 

    # first, which band is the alpha channel? 
    try: 
     alpha_index= image.getbands().index('A') 
    except ValueError: 
     return None # no alpha channel, presumably 

    alpha_getter= operator.itemgetter(alpha_index) 
    return itertools.imap(alpha_getter, image.getdata()) 
4

Bạn có thể lấy dữ liệu alpha ra khỏi toàn bộ hình ảnh trong một đi bằng cách chuyển đổi hình ảnh để chuỗi với 'A' chế độ ví dụ như ví dụ này có được dữ liệu alpha ra khỏi hình ảnh và lưu nó ảnh quy mô như màu xám :)

from PIL import Image 

imFile="white-arrow.png" 
im = Image.open(imFile, 'r') 
print im.mode == 'RGBA' 

rgbData = im.tostring("raw", "RGB") 
print len(rgbData) 
alphaData = im.tostring("raw", "A") 
print len(alphaData) 

alphaImage = Image.fromstring("L", im.size, alphaData) 
alphaImage.save(imFile+".alpha.png") 
1

tôi cố gắng này:

from PIL import Image 
import operator, itertools 

def get_alpha_channel(image): 
    try: 
     alpha_index = image.getbands().index('A') 
    except ValueError: 
     # no alpha channel, so convert to RGBA 
     image = image.convert('RGBA') 
     alpha_index = image.getbands().index('A') 
    alpha_getter = operator.itemgetter(alpha_index) 
    return itertools.imap(alpha_getter, image.getdata()) 

này trả lại kết quả mà tôi đã mong đợi. Tuy nhiên, tôi đã làm một số tính toán để xác định độ lệch trung bình và tiêu chuẩn, và kết quả xuất hiện hơi khác với chức năng fx:mean của imagemagick.

Có lẽ chuyển đổi đã thay đổi một số giá trị? Tôi không chắc chắn, nhưng nó có vẻ tương đối tầm thường.

+0

Bạn đã thử cách này để trả lời câu hỏi hoặc bạn gặp sự cố tương tự nhưng mã này không hoạt động như mong đợi? Trong trường hợp thứ hai, đây sẽ là một câu hỏi mới. Trong trường hợp trước đây, có thể cần chỉnh sửa ít gây nhầm lẫn hơn? – rene

+0

Oh cảm ơn vì đã làm rõ. Tôi đã thử điều này, và thêm một cái gì đó vào để có được những gì tôi cần.Nó là một cái gì đó của một trường hợp tương tự, và sau này là một câu hỏi mới, nhưng tôi đang đi với một cách tiếp cận khác nhau bây giờ bởi vì nó có vẻ như PIL có một vấn đề với hình ảnh trong chế độ 'P'. –

Các vấn đề liên quan