PHPで透過画像をリサイズすると透過が消える件の対応方法

  • 2020.02.20
  • PHP
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);

参考サイト

https://qiita.com/ms2sato/items/a70fbe1843181032f807