1

我刚刚找到了一段代码,用于确定图像是否具有透明像素:

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

显然,这是行不通的。我用具有透明像素的开放图标库的图像 user-desktop.png 进行了尝试。支票返回-1。

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

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

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

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

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

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

4

1 回答 1

2

更新的答案

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

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

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 不支持透明,GIF可以PNG 支持透明但它们不一定总是透明的。

所以,假设你有 aPNG或 a GIF,它可能有一个透明层。如果有,每个像素要么完全透明,要么完全不透明,或者介于两者之间。如果您使用 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
于 2014-10-10T18:34:32.380 回答