【问题标题】:How to get alpha value of a PNG image with PIL?如何使用 PIL 获取 PNG 图像的 alpha 值?
【发布时间】:2010-12-30 02:04:22
【问题描述】:

如何使用 PIL 检测 PNG 图像是否具有透明的 alpha 通道?

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

通过上面的代码,我们知道一个PNG图像是否有alpha通道不是不知道,而是如何获取alpha值?

我没有在 img.info 字典中找到 PIL's website 中所述的“透明度”键

我正在使用 Ubuntu 和 zlib1g,zlibc 包已经安装。

【问题讨论】:

    标签: python image png python-imaging-library transparent


    【解决方案1】:

    要获得 RGBA 图像的 alpha 层,您需要做的就是:

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

    alpha = img.split()[-1]
    

    还有一种设置alpha层的方法:

    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]
    

    注意:当image.mode为LA时需要convert方法,因为PIL中的一个bug。

    【讨论】:

      【解决方案2】:

      您可以通过使用“A”模式将图像转换为字符串来一次性从整个图像中获取 alpha 数据,例如,此示例从图像中获取 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")
      

      【讨论】:

      • 至少从 PIL 1.1.7 版开始,此答案会产生错误“NotImplementedError: tostring() 已被删除。请改为调用 tobytes()。”
      【解决方案3】:

      img.info 是关于整个图像的——RGBA 图像中的 alpha 值是每个像素的,所以它当然不会在img.info 中。图像对象的getpixel 方法,给定一个坐标作为参数,返回一个元组,其中包含该像素的(在本例中为四个)波段的值——元组的最后一个值将是 A,即 alpha 值。

      【讨论】:

      • @Alex,感谢您的回答,有没有办法确定 PNG 图像是否具有透明背景?
      • 除非你很少这样做,否则getpixel 会很慢。您应该使用getdataload 进行高性能访问。
      【解决方案4】:
      # 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())
      

      【讨论】:

        【解决方案5】:

        我试过这个:

        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 函数略有不同。

        也许转换改变了一些值?我不确定,但它似乎相对微不足道。

        【讨论】:

        • 您尝试了这个,所以它回答了问题,或者您有类似的问题,但此代码没有按预期工作?在后一种情况下,这应该是一个新问题。在前一种情况下,可能需要进行编辑以减少混乱?
        • 哦,感谢您的澄清。我尝试了这个,并添加了一些东西来获得我需要的东西。这是一个类似的案例,后者是一个新问题,但我现在采用不同的方法,因为 PIL 似乎对处于“P”模式的图像存在问题。
        猜你喜欢
        • 2014-07-16
        • 2018-06-30
        • 1970-01-01
        • 2015-12-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-07
        • 2015-12-18
        相关资源
        最近更新 更多