使用ImageMagick检测Alpha通道

35

场景

我希望把带有alpha透明度的图片保存为.png格式,不带alpha透明度的图片则保存为.jpg格式,即使它们的原始格式是.png.gif。如何使用ImageMagick检测一张图片是否具有alpha透明度?

6个回答

38

检查图像是否具有Alpha通道

使用-format %A,如serhiy.h的答案所述。从文档中得知:

%A    图像透明度通道。值包括未定义(无透明度通道)、混合、复制或更新。

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

使用-format %[opaque]。从文档中得知:

%[opaque]    计算:图像是否完全不透明?


示例

为了演示,让我们创建一个带有 alpha 通道但完全不透明的图像 a.png,以及一个相同但只有一个半透明像素的图像 b.png

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

正如预期的那样,%A 转义字符对于两个图像都生成了 Blend,因为它们都有一个 alpha 通道:

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

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

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

3
谢谢!输出如此优秀,甚至让人想要这样做:if $(identify -format '%[opaque]' "$file"); then ...; fi - Camilo Martin
1
我已经花了整整一天的时间寻找%[opaque],谢谢! - forresthopkinsa
完整的CLI命令 magick identify -format '%[opaque]' file.png - undefined

37

ImageMagick的命令:

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

如果有alpha通道,则会打印rgba,如果没有alpha通道,则会打印rgb

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


2
有alpha通道但没有数据是常见的吗?如果是这样,我能找到吗? - brad
4
根据我的经验,人们只有在希望alpha通道非空时才会创建它们,但通常发生的情况与可能发生的情况有所不同。如果你没有发现它出现的情况,就不用担心。我只是想完整地指出一个alpha通道的存在并不一定意味着存在透明度。 - msw
1
啊,是的。永远不要低估用户。谢谢! - brad
3
这确实是一个很古老的问题,但是没有α通道并不意味着没有α像素。有可能会有一个索引RGB PNG文件,其中一些索引条目完全透明。请参阅PNG文档中的tRNS。 - OmnipotentEntity

32

如果您想要确认一张图片是否真正透明...(而不仅仅是可能未使用的 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 也很低。似乎图像的很大一部分使用了透明度。

根据所需检查的类型(完全不透明、"几乎不透明"等),您应该检查 minmean 和可能的 standard deviation(标准偏差),如果您的请求有点棘手。

注意:您可能会想检查整数值的 minmean 和其他值,就像我一开始所做的那样。毕竟,处理 95 比处理 0.372549 更容易。如果你选择这个方法,请注意 alpha 通道深度。如果它是 8 位,则 255 是最大值,表示 "不透明"。如果它是 16 位,则最大值现在是 65535,而 255 表示 "几乎透明"。最好检查括号中的小数,它们始终从 0 到 1 范围内。

如果您怀疑将要处理的许多图片根本没有 alpha 通道,可以先运行:

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

如果它(指某物)倾倒:

rgba

存在一个alpha通道(输出中的a),应使用convert来检查min等。但如果不存在,则无需运行convert。虽然我没有对这两个命令进行基准测试,但identify应该比convert快得多。


1
对于许多用户来说,只是想查看 alpha 通道是否必要的人,获取 alpha 最小行并检查其是否以“(1)”结尾应该就足够了。 - dash-tom-bang
1
感谢您提供详细的答案。这实际上为访问图像属性提供了更深入的见解,不仅回答了OP的问题,而且还对其进行了扩展。 - Denialos

7
identify -format %A some_pic.png

如果图片包含透明通道,则返回True


2
这里有几个bash函数,使用ImageMagick来检查png文件是否具有透明度。快速检查只是检查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?//'
}

2

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接