PHPで透過画像をリサイズすると透過が消える件の対応方法
PHPでPNGなどの透過画像をリサイズした時に透過画像が消えて、背景が黒色になる現象が発生していたので、調査をしました。
対応方法
ネット調べたところ、透過画像の処理を入れる必要があることが解りました。
PNG画像とGIF画像で異なる処理が必要みたいです。
とりあえず、下記の処理を追加すると出来ました。
if($image_mime=='image/png' || $image_mime=='image/x-png'){ // PNGの場合 imagealphablending($canvas, false); // 合成を指定しない $color = imagecolorallocatealpha($canvas, 0, 0, 0, 127); // 透過度を指定 127は完全に透明な状態 imagefill($canvas, 0, 0, $color); // 塗りつぶす imagesavealpha($canvas, true); // アルファチャネルを保存 } elseif($image_mime=='image/gif'){ // GIFの場合 $trnprt_indx = imagecolortransparent($image); // 透過を取得 if ($trnprt_indx >= 0) { $trnprt_color = imagecolorsforindex($image, $trnprt_indx); // カラーを取得 $trnprt_indx = imagecolorallocate($canvas, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']); // 色を作成 imagefill($canvas, 0, 0, $trnprt_indx); // 塗りつぶす imagecolortransparent($canvas, $trnprt_indx); // 透明色を設定 } }
<完全版のソース>
// 縮小する基準サイズ $width = 200; $height = 200; // 元の画像 $moto_image = "./data/sample.png"; // リサイズ画像 $resize_image = "./data/sample_resize.png"; // 画像タイプを取得 $image_mime = mime_content_type($moto_image); // 画像を開く switch ($image_mime) { case 'image/jpeg': case 'image/jpg': case 'image/pjpeg': $image = imagecreatefromjpeg($moto_image); break; case 'image/png': case 'image/x-png': $image = imagecreatefrompng($moto_image); break; case 'image/gif': $image = imagecreatefromgif($moto_image); break; default: return -1; break; } // 画像サイズを取得 list($image_w, $image_h) = getimagesize($moto_image); // 縮小する画像サイズを取得 if($width>$image_w){ $width = $image_w; $height = $image_h; } else{ $hiritu = $width / $image_w; $height = $image_h * $hiritu; } // 新しく画像を作成 $canvas = imagecreatetruecolor($width, $height); // 透過対応をする if($image_mime=='image/png' || $image_mime=='image/x-png'){ // PNGの場合 imagealphablending($canvas, false); // ブレンドモードを指定しない $color = imagecolorallocatealpha($canvas, 0, 0, 0, 127); // 透過度を指定 127は完全に透明な状態 imagefill($canvas, 0, 0, $color); // 塗りつぶす imagesavealpha($canvas, true); // アルファチャネルを保存 } elseif($image_mime=='image/gif'){ // GIFの場合 $trnprt_indx = imagecolortransparent($image); // 透過を取得 if ($trnprt_indx >= 0) { $trnprt_color = imagecolorsforindex($image, $trnprt_indx); // カラーを取得 $trnprt_indx = imagecolorallocate($canvas, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']); // 色を作成 imagefill($canvas, 0, 0, $trnprt_indx); // 塗りつぶす imagecolortransparent($canvas, $trnprt_indx); // 透明色を設定 } } // 画像をリサイズする imagecopyresampled($canvas, $image, 0, 0, 0, 0, $width, $height, $image_w, $image_h); // 画像を出力 switch ($image_mime) { case 'image/jpeg': case 'image/jpg': case 'image/pjpeg': imagejpeg($canvas, $resize_image, 100); break; case 'image/png': case 'image/x-png': imagepng($canvas, $resize_image); break; case 'image/gif': imagegif($canvas, $resize_image); break; default: return -1; break; } // 削除 imagedestroy($canvas);