画像処理

【PHP】imagecolortransparent()で透明色を指定してもpng画像に反映されない件

更新日:2023/09/25

PHPのmagecolortransparent()は、画像の透明色を定義する関数です。
この関数を使って透明色を指定後にPNG画像を出力したのに、透明になりませんでした。
どうしてなのか、調べてみました。

 

現象の確認

次のコードは画像全体を赤で塗りつぶした後、黒色をimagecolortransparent()で透明色指定して四角形を描画しています。
最後にPNGでファイル出力しています。

  // TrueColorイメージを新規作成
$image = imagecreatetruecolor(300, 150);
  // アルファチャネル情報を保存フラグオン
imagesavealpha($image,true);
  // 赤色で塗りつぶし
$red = imagecolorallocate($image, 255, 0, 0);
imagefill($image, 0, 0, $red);
  // 黒透明色指定後四角形を描画
$black = imagecolorallocate($image, 0, 0, 0);
imagecolortransparent($image,$bgColor);
imagefilledrectangle($image, 50, 50, 250, 100, $black);
  // ファイル出力
imagepng($image,'image.png');

これにより、次のような画像が生成されます。

imagecolortransparent()で透明色を指定

コードでは黒を透明色として指定しましたが、生成された画像は透明になっていません。
どうしてこうなるんでしょうか。

 

imagesavealpha()が原因

imagesavealpha()はアルファチャンネルを、画像出力時に書き込むどうかのフラグをセットする関数です。
デフォルトはfalseです。

PNGで出力するときはtrueにするという認識だったので、コピペ的に記述していました。
とりあえず色々検証してみようと思って、trueからfalseに変更しました。

imagesavealpha($image,true);
imagesavealpha($image,false);

すると、透明色が反映されました。

imagesavealpha()をコメントアウト

しかし新たなる問題発生。
imagecolorallocate()をimagecolorallocatealpha()に変更して、赤色を不透明にしてみます。

$red = imagecolorallocate($image, 255, 0, 0);
$red = imagecolorallocatealpha($image, 255, 0, 0,50);

生成された画像は、不透明になっていません。

赤色を不透明に

アルファチャンネルが出力されないので、当たり前の結果ですね。

 

imagecolortransparent()とimagesavealpha()の挙動

imagecolortransparent()とimagesavealpha()の使い方によって、出力されるpngファイルがどのように変化するか確認してみました。

imagesavealpha()imagecolortransparent()ピクセルデータ透明色フィールド
false指定ありRGB値出力される
指定なしRGB値出力されない
true指定ありRGB+アルファ値出力されない
指定なしRGB+アルファ値出力されない

imagesavealpha()がflaseの時

imagesavealpha()がflaseの時は、アルファ値が書き込まれません。

具体的には、各ピクセル毎にRGB値が書き込まれます。
imagecolortransparent()で作成した不透明色もRGB値のみが書き込まれれます。
そのため、不透明情報(アルファ値)が失われます。

またimagecolortransparent()で不透明色が指定されているとき、完全に透明とみなすRGB値フィールドがファイルに書き込まれます。

imagesavealpha()がtrueの時

imagesavealpha()がtrueの時は、各ピクセル毎にRGBとアルファ値が書き込まれます。

またimagecolortransparent()で不透明色が指定されていても、完全に透明とみなすRGB値は書き込まれません。

 

使い分け

imagecolortransparent()は不透明色を使用できないという欠点があります。
また、ImageTTFText()で文字列を描画すると、ギザギザになったり透明指定した色が文字の縁に表示されたりすることがあります。

意図した結果にならないことが多いので、imagecolorallocatealpha()で完全な透明色を作成する方がよさそうです。

ただし、imagecopymerge()で透過率を変更して貼り付けを行うときは、imagecolortransparent()で指定します。
imagecolorallocatealpha()で透明にした色は透過率が変更さえてしまい、目に見えるようになるからです。

更新日:2023/09/25

書いた人(管理人):けーちゃん

スポンサーリンク

記事の内容について

null

こんにちはけーちゃんです。
説明するのって難しいですね。

「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。

裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。

掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。

ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php

 

このサイトは、リンクフリーです。大歓迎です。