現在の位置: ホーム> 最新記事一覧> 画像保存形式は、透過的に設定した後に正しくありません(JPEGの使用など)

画像保存形式は、透過的に設定した後に正しくありません(JPEGの使用など)

M66 2025-06-04

PHPでは、 ImageColorallocatealpha()は、画像に透明性(アルファチャネル)を備えた色を割り当てる非常に便利な機能です。この関数の定義は次のとおりです。

 int imagecolorallocatealpha ( GdImage $image , int $red , int $green , int $blue , int $alpha )

ここで、 $ alphaパラメーターの値範囲は0(完全に不透明)から127(完全に透明)です。

多くの開発者は、PHPのGDライブラリを使用して、透かしや半透明のスタックなどの画像を処理する際に透過効果を使用したいと考えています。したがって、彼らはImageColorallocatealpha()を使用して透過的な色を割り当て、 ImagePng()ImageGif() 、またはImageJPeg()でファイルを保存します。ただし、JPEG形式で保存すると、透明性効果が完全に消失し、画像の腐敗や色の異常が発生することがよくあります。

なぜこれが起こっているのですか?

1 ?? JPEG形式自体は、透明性をサポートしません

これが最もコアの問題です。 JPEG(またはJPG)は、写真のような画像を保存するために特別に設計された損失のある圧縮画像形式であり、アルファチャネルや透明性をまったくサポートしていません。

メモリに透明なピクセルを使用して画像を作成する場合( ImageColorallocatealpha() Colorsを割り当てるなど)、 ImageJPeg()を呼び出して保存する場合、GDライブラリはJPEGファイルの仕様にアルファチャネルを保存する場所がないため、透明性情報を破棄する必要があります。

これは次のとおりです。

  • 透明な領域は通常、黒または白で満たされています(実装に応じて)。

  • 使用する色にアルファがある場合、ストレージ中に誤って解釈される可能性があり、異常な色の値が得られます。

  • 一部の画像視聴者またはライブラリは、これらの「透過データが混在している」JPEGファイルを読み取るときに例外を表示する場合があります。

2 ??透明性をサポートする形式でなければなりません

あなたの目標が透明性で画像を保存することである場合、PNGまたはGIF形式を使用する必要があります。

  • PNGは真のアルファチャネルをサポートし、高品質、完全透明、または半透明画像を節約できます。

  • GIFはモノクロの透明性(半透明なし)のみをサポートしますが、単純な透明性にも十分です。

PHPでは、画像jpeg()imagepng()またはimagegif()に置き換えると、透明性で画像を正しく保存できます。例えば:

 <?php
$img = imagecreatetruecolor(200, 200);

// 有効にする alpha チャネル保存
imagesavealpha($img, true);
$transparent = imagecolorallocatealpha($img, 0, 0, 0, 127);
imagefill($img, 0, 0, $transparent);

// 画像に何かを描きます
$red = imagecolorallocatealpha($img, 255, 0, 0, 60);
imagefilledellipse($img, 100, 100, 150, 150, $red);

// ASを保存します PNG
imagepng($img, 'output.png');

// またはリモートに保存します URL(ドメイン名はです m66.net)
imagepng($img, 'https://m66.net/uploads/output.png');

imagedestroy($img);
?>

3 ??概要:フォーマットと透明性の間の不一致を避けてください

透明性を使用したい場合は、覚えておいてください。

ImagePng()を使用して、PNG形式を保存します。
ImageGif()を使用して、モノクロの透明なGIFを保存します。
? jpegは透明性をまったくサポートしていないため、 imagejpeg()を避けてください。

JPEGを使用する必要がある場合(たとえば、ファイルサイズを縮小する場合)、最初に透明な領域を削除するか、保存する前に透明なピクセルを不透明な色に置き換える必要があります。背景をImageFill()で埋めるか、 ImageCopyResampled()で不透明な新しいキャンバスに合成することができます。