如何检测PNG图像是否具有透明的Alpha通道或不使用PIL?
img = Image.open('example.png', 'r')
has_alpha = img.mode == 'RGBA'
通过上面的代码,我们知道 PNG 图像是否具有 alpha 通道,而不是如何获取 alpha 值?
如PIL 网站所述,我没有在 img.info 字典中找到“透明度”键
我正在使用 Ubuntu 和 zlib1g,zlibc 软件包已经安装。
如何检测PNG图像是否具有透明的Alpha通道或不使用PIL?
img = Image.open('example.png', 'r')
has_alpha = img.mode == 'RGBA'
通过上面的代码,我们知道 PNG 图像是否具有 alpha 通道,而不是如何获取 alpha 值?
如PIL 网站所述,我没有在 img.info 字典中找到“透明度”键
我正在使用 Ubuntu 和 zlib1g,zlibc 软件包已经安装。
要获得 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 中的一个错误。
您可以通过使用“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")
这img.info
是关于整个图像的 - RGBA 图像中的 alpha 值是每个像素的,所以它当然不会在img.info
. 图像对象的getpixel
方法,给定一个坐标作为参数,返回一个元组,其中包含该像素的(四个,在这种情况下)波段的值——元组的最后一个值将是 A,即 alpha 值。
# 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())
我试过这个:
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
函数略有不同。
也许转换改变了一些值?我不确定,但它似乎相对微不足道。