使用ImageMagick检测Alpha通道

时间:2010-04-05 22:05:33

标签: image png imagemagick jpeg alpha

方案

我希望将带有Alpha透明度的图片保存为.png,将没有Alpha透明度的图片保存为.jpg(即使其原始格式为.png.gif)。如何使用ImageMagick检测图像是否具有Alpha透明度?

6 个答案:

答案 0 :(得分:27)

ImageMagik命令:

identify -format '%[channels]' foo.png 
如果存在或不存在Alpha通道,

将分别打印rgbargb

可能存在一个没有数据的alpha通道,它实际上没有任何透明度,但这有点复杂。

答案 1 :(得分:22)

如果您想检查图片是否实际透明...(不仅是可能未使用的Alpha通道)

使用此命令:

convert some_pic.png -verbose info:

(是的,命令末尾有:

这是非常冗长的。寻找频道列表:

(...)
Channel depth:
  red: 16-bit
  green: 16-bit
  blue: 16-bit
Channel statistics:
(...)

在此示例中,有三个通道,每个通道对应一种原色。但不是阿尔法。所以这张图片不透明。

但你也可以得到这种输出:

(...)
Channel depth:
  red: 16-bit
  green: 16-bit
  blue: 16-bit
  alpha: 1-bit
Channel statistics:
(...)

这里有一个alpha通道。但是,这并不能证明图像是透明的。它只是说可能。在命令的输出中,查找有关alpha通道的信息:

(...)
  Alpha:
    min: 255 (1)
    max: 255 (1)
    mean: 255 (1)
    standard deviation: 0 (0)
    kurtosis: 0
    skewness: 0
(...)

在此示例中,alpha表示图片不透明:min = max = 1(1 =不透明,0 =透明)。因此,即使图像具有Alpha通道,用户也会看到不透明的图片。

你也可以这样:

(...)
  Alpha:
    min: 95 (0.372549)
    max: 212 (0.831373)
    mean: 111.187 (0.436028)
    standard deviation: 19.5635 (0.0767196)
    kurtosis: 7.52139
    skewness: -2.80445
(...)

这一次,min = 0.372549。这意味着一些像素部分透明。 mean也很低。似乎图像的很大一部分使用透明度。

根据您要实现的支票类型(完全不透明,“几乎不透明”等),如果您的要求,您应该检查minmeanstandard deviation有点棘手。

注意:您可能会像我在第一时间那样检查minmean和其他人的整数值。毕竟,处理950.372549更容易。如果选择此路线,请注意Alpha通道深度。如果它是8位,那么255是最大值并且意味着“不透明”。如果是16位,则最大值现在为65535,255表示“几乎透明”。更好地检查括号中的浮点数,它总是从0到1。

如果您怀疑要处理的大量图片根本没有Alpha通道,那么首次运行可能会有用:

identify -format '%[channels]' some_pic.png

如果它转储:

rgba

有一个Alpha通道(输出中为a),convert应该用于检查min等。但如果没有,则没有必要运行convert。虽然我没有对这两个命令进行基准测试,但identify应该比convert快得多。

答案 2 :(得分:19)

检查图像是否具有Alpha通道

根据serhiy.h's answer使用 -format %A 。来自documentation

  

%启用图像透明度通道(true / false)

检查图像是否没有透明或半透明像素

使用 -format %[opaque] 。来自documentation

  

%[opaque] CALCULATED:图像完全不透明吗?

实施例

为了演示,让我们创建一个具有Alpha通道但完全不透明的图像a.png,以及除一个半透明像素外的图像b.png

$ convert rose: PNG32:a.png
$ convert rose: -fill '#0008' -draw "matte 10,10 point" PNG32:b.png

正如预期的那样,%A转义为两个图片生成True,因为它们都有alpha通道:

$ identify -format '%A' a.png
True
$ identify -format '%A' b.png  
True

%[opaque]转义在一种情况下产生true,而在另一种情况下产生false由于一个透明像素:

$ identify -format '%[opaque]' a.png
true
$ identify -format '%[opaque]' b.png
false

答案 3 :(得分:7)

identify -format %A some_pic.png

如果图片包含Alpha通道,则会返回True

答案 4 :(得分:2)

如果你想确保真正使用alpha透明度,我认为唯一的解决办法是迭代所有像素并获取颜色信息以检查它是否透明。对于大图像,这将非常慢,因此,作为优化,您可以首先制作图像的缩略图(假设为20x20),然后检查缩略图像素。这对我来说是一个很好的解决方案。

答案 5 :(得分:1)

这里有几个bash函数,用于检查png是否具有透明度,使用ImageMagick。

快速检查,只检查Alpha通道的状态

checkAlphaFast() {
    test $(identify -format %A "$1") == True
}

慢速检查,验证像素本身(即使存在alpha通道):

checkAlphaSlow() {
    test $(identify -format '%[opaque]' "$1") == false
}

如果您经常这么做,您应该只考虑使用快速检查,因为它的速度非常快。感谢其他回答的人,我从中做了这些功能:)

作为奖励:我没有进行任何基准测试,但这可能几乎与快速模式一样快,并且与慢速模式一样准确:

checkAlpha() {
    checkAlphaFast "$1" && checkAlphaSlow "$1"
}

使用以下这些功能:

if checkAlpha "$myPNG"; then
    # is transparent
else
    # is opaque
fi

这将为您提供图像的不透明度,其中0表示完全透明,1表示完全不透明:

checkOpaqueness() {
    if checkAlphaFast "$1"; then
        convert "$1" -verbose info: | grep -A3 Alpha: | tail +4 | head -n1 | sed -r 's/.*\(|\)//g'
    else
        echo 1
    fi
}

这个以圆整百分比输出,因为整数对于bash来说更加自然:

checkPercentage() {
    printf %3.2f $(checkOpaqueness "$1") | tr -d . | sed -r 's/^0?0?//'
}