【问题标题】:How to determine if an image has a transparent pixel如何确定图像是否具有透明像素
【发布时间】:2014-12-05 22:31:24
【问题描述】:

我刚刚找到一段代码,用来判断一张图片是否有透明像素:

my $alpha  = $gd->transparent;
if ($alpha < 0) {
    die("The image you uploaded has no transparent pixels. (alpha = $alpha)");
}

显然,这不起作用。我使用具有透明像素的open icon library 的图像 user-desktop.png 进行了尝试。支票返回 -1。

我只能猜测为什么使用这个命令。 GD 的手册页说:

如果不带任何参数调用该方法[transparent],它将返回透明颜色的当前索引,如果没有则返回-1。

所以,作为一个附带问题:透明像素根本没有颜色索引 - 对吧?

然后我找到了线程Perl GD check if pixel is transparent。但是对于这个解决方案,我必须遍历图像的所有像素(至少在麦芽汁的情况下,当唯一的透明像素是最后一个时)。

难道没有一种简单的方法来检查这些信息吗?也许像 $image_object->has_transparent_pixels 这样的方法?

注意:我没有绑定到 GD,所以其他 Image 模块也可以工作(但是,我在 Windows 上 - 它应该在那里工作)。

【问题讨论】:

    标签: image perl transparency gd perlmagick


    【解决方案1】:

    更新答案

    正如@ikegami 所指出的(谢谢),GIF 在其调色板中有一个指定的透明“颜色”像素,而不是每个像素都有自己的透明度值的 alpha/透明层,通常在 0-255 之间。

    我生成了一个 2x2 像素的 GIF,其中一个透明像素、一个红色、一个绿色和一个蓝色 - 然后针对它运行 ImageMagick 的 identify 命令并得到以下结果。我已经用箭头标记了透明像素部分。

    Image: a.gif
      Format: GIF (CompuServe graphics interchange format)
      Mime type: image/gif
      Class: PseudoClass
      Geometry: 4x4+0+0
      Units: Undefined
      Type: PaletteAlpha
      Endianess: Undefined
      Colorspace: sRGB
      Depth: 8/1-bit
      Channel depth:
        red: 1-bit
        green: 1-bit
        blue: 1-bit
        alpha: 1-bit
      Channel statistics:
        Pixels: 16
        Red:
          min: 0 (0)
          max: 255 (1)
          mean: 127.5 (0.5)
          standard deviation: 127.5 (0.5)
          kurtosis: -2
          skewness: 0
        Green:
          min: 0 (0)
          max: 255 (1)
          mean: 127.5 (0.5)
          standard deviation: 127.5 (0.5)
          kurtosis: -2
          skewness: 0
        Blue:
          min: 0 (0)
          max: 255 (1)
          mean: 127.5 (0.5)
          standard deviation: 127.5 (0.5)
          kurtosis: -2
          skewness: 0
        Alpha:
          min: 0 (0)
          max: 255 (1)
          mean: 191.25 (0.75)
          standard deviation: 110.418 (0.433013)
          kurtosis: -0.666667
          skewness: 1.1547
      Image statistics:
        Overall:
          min: 0 (0)
          max: 255 (1)
          mean: 111.562 (0.4375)
          standard deviation: 123.451 (0.484123)
          kurtosis: -1.8275
          skewness: 0.271109
      Alpha: srgba(255,255,255,0)   #FFFFFF00
      Colors: 4
      Histogram:
             4: (  0,  0,255,255) #0000FF blue
             4: (  0,255,  0,255) #00FF00 lime
             4: (255,  0,  0,255) #FF0000 red
             4: (255,255,255,  0) #FFFFFF00 srgba(255,255,255,0)
      Colormap entries: 4
      Colormap:
             0: (255,  0,  0,255) #FF0000 red
             1: (  0,255,  0,255) #00FF00 lime
             2: (  0,  0,255,255) #0000FF blue
             3: (255,255,255,  0) #FFFFFF00 srgba(255,255,255,0)      <---------
      Rendering intent: Perceptual
      Gamma: 0.454545
      Chromaticity:
        red primary: (0.64,0.33)
        green primary: (0.3,0.6)
        blue primary: (0.15,0.06)
        white point: (0.3127,0.329)
      Background color: srgba(255,255,255,0)
      Border color: srgba(223,223,223,1)
      Matte color: grey74
      Transparent color: srgba(255,255,255,0)    <---------------
      Interlace: None
      Intensity: Undefined
      Compose: Over
      Page geometry: 4x4+0+0
      Dispose: Undefined
      Compression: LZW
      Orientation: Undefined
      Properties:
        date:create: 2014-10-11T10:40:09+01:00
        date:modify: 2014-10-11T10:40:08+01:00
        signature: 1c82b4c2e772fb075994516cc5661e9dec35b8142f89c651253d07fc3c4642bb
      Profiles:
        Profile-gif:xmp dataxmp: 1031 bytes
      Artifacts:
        filename: a.gif
        verbose: true
      Tainted: False
      Filesize: 1.11KB
      Number pixels: 16
      Pixels per second: 16PB
      User time: 0.000u
      Elapsed time: 0:01.000
      Version: ImageMagick 6.8.9-7 Q16 x86_64 2014-09-10 http://www.imagemagick.org
    

    所以,IM 确实知道 GIF 透明像素 - 我会进一步挖掘,看看是否可以在 Perl 中找到它 - 不过现在,您可以在 Perl 的反引号中运行以下命令。

    my $output = `identify -verbose a.gif | grep -i transparent`;   # or maybe with FINDSTR on Windows
    

    作为一种替代方法,并且跨平台问题较少,%A 转义会告诉您图像是否启用了透明度:

    convert a.gif -print "%A" null:
    True
    
    convert a.jpg -print "%A" null:
    False
    

    或者,以更 Perl-y 的方式:

    #!/usr/bin/perl
    use warnings;
    use strict;
    use Image::Magick;
    my $image = Image::Magick->new();
    $image->Read($ARGV[0]);
    my $a = $image->Get('%A');
    print $a;
    
    perl ./script.pl a.gif
    True
    
    perl ./script.pl a.jpg
    False
    

    原答案

    我认为您可能对透明度有些困惑。图像要么具有透明度,即整个图层,要么没有。一般来说,这不是单个像素是否透明的问题。从一开始,JPEGs 不支持透明,GIFPNG 可以支持透明,但它们不一定总是透明。

    所以,假设您有一个PNGGIF,它可能有一个透明层。如果有,每个像素要么完全透明,要么完全不透明,或者介于两者之间。如果您使用 ImageMagick,它可以在命令行或 PHP、Perl 和其他绑定中使用。

    在命令行中,您可以使用以下命令判断图像是否具有透明层:

    convert InputImage.png -format "%[opaque]" info:
    

    它会返回truefalse

    在 Perl 中你可以这样做:

    #!/usr/bin/perl
    use warnings;
    use strict;
    use Image::Magick;
    my $image = Image::Magick->new();
    $image->Read($ARGV[0]);
    my $a = $image->Get('%[opaque]');
    print $a;
    

    然后运行为:

    perl ./script.pl ImageName.png
    

    【讨论】:

    • 为什么所有 .NET 都在谈论 Perl 问题?
    • @ThisSuitIsBlackNot 糟糕,我看到了 Windows,可能太早开始周五晚上的一杯葡萄酒 - 现在将更新...
    • Re "如果有,每个像素要么完全透明,要么完全不透明,或者介于两者之间。"这不是真的。您和 OP 一样对透明度感到困惑。有两种透明机制。 OP 只知道其中一个,而您只知道另一个。 GIF 使用 OP 和 $gd-&gt;transparent 所指的机制。 GIF 使用(最多)256 种颜色的调色板。这 256 个索引之一可以指定为透明色。该颜色的像素是 100% 透明的。其他颜色的像素是 100% 不透明的。
    • @ikegami 谢谢你的解释 - 我确实不知道 GIF 格式有一个指定的透明像素“颜色”。
    猜你喜欢
    • 2014-07-07
    • 2012-02-03
    • 2011-12-23
    • 2021-08-07
    • 2012-04-30
    • 2017-12-20
    • 1970-01-01
    • 2014-04-05
    • 2012-04-27
    相关资源
    最近更新 更多