画像をアップロードすると複数サムネイルを生成する方法
2024/04/18
フォームで画像をアップロードすると、予め定めておいた大中小のサイズでサムネイル画像を生成する方法のメモ。
ソースコード
<?php
$resizeList = array(
0 => array(
'width' => '500',
'height' => '500',
'title' => 'サイズ大',
),
1 => array(
'width' => '300',
'height' => '300',
'title' => 'サイズ中',
),
2 => array(
'width' => '100',
'height' => '100',
'title' => 'サイズ小',
),
);
define('MAIN_PATH','/var/www/html');
define('IMAGE_PATH', MAIN_PATH.'/test/img_resize/img/');
define('TMP_PATH', MAIN_PATH.'/test/img_resize/tmp/');
/* ランダム英数字作成
* 引数 $length(int)
* 返り値 false or string
*/
function randomStr ($length = 1) {
if( $length < 1 ) return false;
$str = array_merge(range('a', 'z'), range('0', '9'), range('A', 'Z"'));
for ($i = 0; $i < $length; $i++) {
$r_str .= $str[rand(0, count($str)-1)];
}
return $r_str;
}
/* 画像のリサイズ
* 返り値 bool
*/
function smart_resize_image(
$file,
$width = 0,
$height = 0,
$proportional = false,
$output = 'file',
$delete_original = true,
$use_linux_commands = false,
$quality = 100
) {
if ( $height <= 0 && $width <= 0 ) return false;
$info = getimagesize($file);
$image = '';
$final_width = 0;
$final_height = 0;
list($width_old, $height_old) = $info;
if ($proportional) {
if ($width == 0) $factor = $height/$height_old;
elseif ($height == 0) $factor = $width/$width_old;
else $factor = min( $width / $width_old, $height / $height_old );
$final_width = round( $width_old * $factor );
$final_height = round( $height_old * $factor );
}
else {
$final_width = ( $width <= 0 ) ? $width_old : $width;
$final_height = ( $height <= 0 ) ? $height_old : $height;
}
switch ( $info[2] ) {
case IMAGETYPE_GIF: $image = imagecreatefromgif($file); break;
case IMAGETYPE_JPEG: $image = imagecreatefromjpeg($file); break;
case IMAGETYPE_PNG: $image = imagecreatefrompng($file); break;
default: return false;
}
$image_resized = imagecreatetruecolor( $final_width, $final_height );
if ( ($info[2] == IMAGETYPE_GIF) || ($info[2] == IMAGETYPE_PNG) ) {
$transparency = imagecolortransparent($image);
if ($transparency >= 0) {
$transparent_color = imagecolorsforindex($image, $trnprt_indx);
$transparency = imagecolorallocate($image_resized, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']);
imagefill($image_resized, 0, 0, $transparency);
imagecolortransparent($image_resized, $transparency);
}
elseif ($info[2] == IMAGETYPE_PNG) {
imagealphablending($image_resized, false);
$color = imagecolorallocatealpha($image_resized, 0, 0, 0, 127);
imagefill($image_resized, 0, 0, $color);
imagesavealpha($image_resized, true);
}
}
imagecopyresampled($image_resized, $image, 0, 0, 0, 0, $final_width, $final_height, $width_old, $height_old);
if ( $delete_original ) {
if ( $use_linux_commands ) exec('rm '.$file);
else @unlink($file);
}
switch ( strtolower($output) ) {
case 'browser':
$mime = image_type_to_mime_type($info[2]);
header("Content-type: $mime");
$output = NULL;
break;
case 'file':
$output = $file;
break;
case 'return':
return $image_resized;
break;
default:
break;
}
switch ( $info[2] ) {
case IMAGETYPE_GIF: imagegif($image_resized, $output); break;
case IMAGETYPE_JPEG: imagejpeg($image_resized, $output, $quality); break;
case IMAGETYPE_PNG:
$quality = 9 - (int)((0.9*$quality)/10.0);
imagepng($image_resized, $output, $quality);
break;
default: return false;
}
return true;
}
if ( $_FILES && $_POST['mode'] == 'upload' ) { //画像アップロード時
$tmpData = array(); //未登録用に初期化
//拡張子チェック&名前決め
$tmpData['img']['name'] = randomStr(12); //ファイル名は[不動産ID_フォルダID_ランダム英数字]
$image_ext = $_FILES['img']['type'];
if ($image_ext == 'image/jpeg' || $image_ext == 'image/jpg') {
$tmpData['img']['ext'] = '.jpg';
} elseif ($image_ext == 'image/png') {
$tmpData['img']['ext'] = '.png';
} elseif ($image_ext == 'image/gif') {
$tmpData['img']['ext'] = '.gif';
} else {
echo 'For jpg / png / gif other than, it was not possible to upload the extension of the image.<br /><a href="javascript:void(0);" onClick="history.back();">return</a>';
exit();
}
//フォルダにアップ
if ($_FILES['img']['size'] > 0) {
if (!move_uploaded_file($_FILES['img']["tmp_name"], TMP_PATH . $tmpData['img']['name'] . $tmpData['img']['ext'])){
echo 'An error occurred while uploading the image.<br /><a href="javascript:void(0);" onClick="history.back();">return</a>';
exit();
} else {
copy(TMP_PATH . $tmpData['img']['name'] . $tmpData['img']['ext'], IMAGE_PATH . $tmpData['img']['name'] . $tmpData['img']['ext']);//オリジナルサイズの画像をimageフォルダにアップ
for ($i = 0; $i < count($resizeList); $i++) {
$sizeName = '-' . $resizeList[$i]['width'] . 'x' . $resizeList[$i]['height'];
copy(TMP_PATH . $tmpData['img']['name'] . $tmpData['img']['ext'], TMP_PATH . $tmpData['img']['name'] . $sizeName . $tmpData['img']['ext']);//リサイズ用画像をtmpフォルダへコピー
smart_resize_image(
TMP_PATH . $tmpData['img']['name'] . $sizeName . $tmpData['img']['ext'],
$width = $resizeList[$i]['width'],
$height = $resizeList[$i]['height'],
$proportional = false,
$output = 'file',
$delete_original = false,
$use_linux_commands = false,
$quality = 100
);
copy(TMP_PATH . $tmpData['img']['name'] . $sizeName . $tmpData['img']['ext'], IMAGE_PATH . $tmpData['img']['name'] . $sizeName . $tmpData['img']['ext']);//imageフォルダにアップ
unlink(TMP_PATH . $tmpData['img']['name'] . $sizeName . $tmpData['img']['ext']);
}
unlink(TMP_PATH . $tmpData['img']['name'] . $tmpData['img']['ext']); //オリジナルのtmpフォルダ分削除
}
}
} //画像処理ここまで
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transtional//EN" "http://www.w3c.org/TR/html4/loose.dtd">
<html lang="ja">
<head>
<meta charset="utf-8">
</head>
<body>
<form action="<?=$_SERVER['PHP_SELF'];?>" method="post" enctype="multipart/form-data">
<input type="file" name="img">
<input type="submit" name="送信!">
<input type="hidden" name="mode" value="upload">
</form>
<? if( $_POST['mode'] == 'upload' ){ ?>
<? for($i = 0; $i < count($resizeList); $i++){ ?>
<?=$resizeList[$i]['title'];?>(width:<?=$resizeList[$i]['width'];?> / height:<?=$resizeList[$i]['height'];?>)<br />
<img src="./img/<?=$tmpData['img']['name'] . '-' . $resizeList[$i]['width'] . 'x' . $resizeList[$i]['height'] . $tmpData['img']['ext']?>"><br /><br />
<? } ?>
オリジナルサイズ<br />
<img src="./img/<?=$tmpData['img']['name'] . $tmpData['img']['ext']?>"><br /><br />
<? } ?>
</body>
所感
$resizeListに追加していけばどんどんサムネイルサイズを増やせるはず。
複数ってのが初めてだったので少し手間取った。具体的には1つの画像を縮小⇔拡大を繰り返すと画像が劣化というか変になる。当たり前なんだけど。
なので、リサイズ用に画像を生成してリサイズして元画像は破棄って形をとったけど、なんだかまどろっこしい。
関連記事
-
-
CodeIgniter4でフォームからファイルをアップロードし保存する方法
CodeIgniter4.4.4でformから画像等のファイルをアップロードし、 ...
-
-
フォルダにリンク制限をかける
imgというフォルダがあり、直接URLを叩いても 中身を見られないけど、同一サー ...
-
-
PHPにて「ImageHash」ライブラリを使用し画像の類似度を算出する方法
以前にPHPの「image-comparator」ライブラリで画像の類似度を算出 ...
-
-
PHPで画像アップロード、リサイズ、形式変換(jpg->webp等)はclass.upload.phpが便利
今までPHPで画像関連の処理を行う場合、リサイズの時のみsmart_resize ...
-
-
MySQLとPHPの「image-comparator」ライブラリを使用して類似画像検索を実装する方法
先日PHPで画像を比較して類似度を算出する「image-comparator」ラ ...