1

I just found a piece of code that was used to determine if an image has transparent pixels:

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

Obviously, this does not work. I tried it with the image user-desktop.png of the open icon library which has transparent pixels. The check returned -1.

I can only guess why this command was used. GD's manpage says:

If you call this method [transparent] without any parameters, it will return the current index of the transparent color, or -1 if none.

So, as a side question: the transparent pixels can have no color index at all - right?

Then I found the thread Perl GD check if pixel is transparent. But for this solution, I have to iterate over all pixels of an image (at least in the wort case, when the only transparent pixel would be the last one).

Isn't there an easy way of checking for this information? Maybe a method like $image_object->has_transparent_pixels ?

NB: I'm not bound to GD, so other Image modules might work as well (however, I'm on Windows - it should work there).

Community
  • 1
  • 1
capfan
  • 817
  • 10
  • 26

1 Answers1

2

Updated Answer

As pointed out by @ikegami (thank you), GIFs have a designated transparent "colour" pixel in their palette rather than a alpha/transparency layer in which each pixel has its own transparency value, normally between 0-255.

I have generated a 2x2 pixel GIF with one transparent pixel, one red, one green and one blue - then ran ImageMagick's identify command against it and got the following. I have marked the transparent pixel parts with an arrow.

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

So, IM does know about the GIF transparent pixel - I will dig some more and see if it can be found sensibly in Perl - for now though, you could just run the following in Perl's backticks.

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

As an alternatvie, and less problematic across platforms, the %A escape tells you if an image has transparency enabled:

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

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

Or, in a more Perl-y way:

#!/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

Original Answer

I think you may be a little confused about transparency. Images either have transparency, which is an entire layer, or they do not. In general, it is not a question of a single pixel being transparent or not. From the outset, JPEGs do not support transparency, GIF and PNG can support transparency but they are not necessarily always transparent.

So, assuming you have a PNG or a GIF, it could have a transparency layer. If it has, each pixel could either be totally transparent, totally opaque or somewhere in between. If you use ImageMagick, it is available at the command line or with PHP, Perl and other bindings.

From the command line, you can tell if an image has a transparency layer using this command:

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

and it will either return true or false.

In Perl you can do this:

#!/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;

then run as:

perl ./script.pl ImageName.png
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • 1
    Why all the .NET talk on a Perl question? – ThisSuitIsBlackNot Oct 10 '14 at 18:42
  • 1
    @ThisSuitIsBlackNot Ooops, I saw Windows and may have started a Friday evening glass of wine too early - will update now... – Mark Setchell Oct 10 '14 at 18:50
  • 1
    Re "If it has, each pixel could either be totally transparent, totally opaque or somewhere in between." That's not true. You are as equally confused as the OP about transparency. There are two transparency mechanisms. The OP only knows about one of them, and you only know of the other one. The mechanims to which the OP and `$gd->transparent` refer is used by GIFs. GIFs use a palette of (up to) 256 colors. One of those 256 indexes can be designated the transparent color. Pixels of that color are 100% transparent. Pixels of the other colors are 100% opaque. – ikegami Oct 11 '14 at 09:16
  • @ikegami Thank you for the explanation - I was indeed unaware that the GIF format had a single designated transparent pixel "colour". – Mark Setchell Oct 11 '14 at 09:35