سؤال

كيفية اكتشاف ما إذا كانت صورة PNG تحتوي على قناة ألفا شفافة أم لا تستخدم PIL؟

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

باستخدام الكود أعلاه، نعرف ما إذا كانت صورة PNG تحتوي على قناة ألفا أم لا، ولكن كيف يمكن الحصول على قيمة ألفا؟

لم أجد مفتاح "الشفافية" في قاموس img.info كما هو موضح في موقع PIL

أنا أستخدم Ubuntu وzlib1g، وحزم zlibc مثبتة بالفعل.

هل كانت مفيدة؟

المحلول

للحصول على طبقة ألفا لصورة RGBA ، كل ما عليك فعله هو:

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

أو

alpha = img.split()[-1]

وهناك طريقة لتعيين طبقة ألفا:

img.putalpha(alpha)

يتم استخدام مفتاح الشفافية فقط لتحديد فهرس الشفافية في وضع اللوحة (P). إذا كنت ترغب في تغطية حالة شفافية وضع اللوحة أيضًا وتغطية جميع الحالات ، يمكنك القيام بذلك

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

ملاحظة: هناك حاجة إلى طريقة التحويل عندما تكون الصورة. الوضع LA ، بسبب وجود خطأ في PIL.

نصائح أخرى

يمكنك الحصول على بيانات Alpha من الصورة بأكملها في واحدة من خلال تحويل الصورة إلى سلسلة مع وضع "A" على سبيل المثال ، هذا المثال يحصل على بيانات alpha من الصورة وحفظها كصورة مقياس رمادي :)

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")
# 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())

ال img.info تدور حول الصورة ككل-القيمة ألفا في صورة RGBA هي لكل بكسل ، لذلك بالطبع لن تكون في img.info. ال getpixel تقوم طريقة كائن الصورة ، بالنظر إلى إحداثي كوسيطة ، بإرجاع tuple مع قيم النطاقات (الأربعة ، في هذه الحالة) لتلك البكسل - ستكون القيمة الأخيرة لـ Tuple ، قيمة ألفا.

حاولت هذا:

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())

أعاد هذا النتيجة التي كنت أتوقعها.ومع ذلك، قمت ببعض العمليات الحسابية لتحديد المتوسط ​​والانحراف المعياري، وكانت النتائج مختلفة قليلاً عن نتائج imagemagick fx:mean وظيفة.

ربما تغير التحويل بعض القيم؟لست متأكدًا، لكنه يبدو تافهًا نسبيًا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top