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 に縛られていないので、他の画像モジュールも同様に機能する可能性があります (ただし、私は Windows を使用しています - そこでは機能するはずです)。

4

1 に答える 1

2

更新された回答

@ikegami (ありがとう) が指摘したように、GIF のパレットには、各ピクセルが通常 0 ~ 255 の間の独自の透明度値を持つアルファ/透明度レイヤーではなく、指定された透明な「色」ピクセルがあります。

透明ピクセル 1 つ、赤 1 つ、緑 1 つ、青 1 つを含む 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 らしい方法で:

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

元の回答

透明性について少し混乱しているかもしれません。画像には、レイヤー全体である透過性があるか、ないかのいずれかです。一般に、単一のピクセルが透明かどうかの問題ではありません。最初から、 はJPEG透過性をサポートしておらず、透過性GIFをサポートPNG できますが、必ずしも常に透過的であるとは限りません。

PNGしたがって、またはがあると仮定するとGIF、透明レイヤーを持つことができます。ある場合、各ピクセルは完全に透明、完全に不透明、またはその中間のいずれかになります。ImageMagick を使用する場合は、コマンド ラインまたは PHP、Perl、およびその他のバインディングで使用できます。

コマンド ラインから、次のコマンドを使用して、画像に透過レイヤーがあるかどうかを確認できます。

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

を返すtrueか、またはfalse.

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 に答える