PHPのimagecopyresampled
で
- ユーザがフォームから画像を投稿
- 縦横どちらも規定サイズ以下ならそのまま保存
- 縦横比が規定サイズと等しければ縮小して保存
- 縦横どちらも規定サイズより大きければ差の小さいほうに合わせて一旦縦横比を維持して縮小→はみ出した部分を中心を合わせてカット→保存
という作業をしました。
4のパターンの場合、imagecopyresampled
1回でやろうとすると先にカットして縮小するため画像に黒い余白ができてしまったのでいったん縮小だけして保存→改めてカットという工程です
// 画像のデータを取得
$data = @getimagesize($_FILES['upfile']['tmp_name']);
// 画像処理に使う関数名を決定する
$create = str_replace('/', 'createfrom', $data['mime']);
$output = str_replace('/', '', $data['mime']);
// 元画像リソースを生成する
$src = @$create($_FILES['upfile']['tmp_name']);
// 画像の縦横,拡張子を取得
$w = $data[0];
$h = $data[1];
$type = image_type_to_extension($data[2]);
// 保存する画像のサイズ
$dst_w = 600;
$dst_h = 900;
// 初期化
$sttX = 0;
$sttY = 0;
$src_w = $w;
$src_h = $h;
// 保存する画像に対する元画像の比率
$per_w = $w/$dst_w;
$per_h = $h/$dst_h;
$per_dif = $per_w - $per_h;
if ( $w <= $dst_w && $h <= $dst_h){ // どちらも規定以下ならそのまま保存
$dst_w = $w;
$dst_h = $h;
} elseif ($per_w === $per_h) { // 縦横比が規定と等しければそのまま縮小
// 何もしない
} else {
// 縦横どちらも大きければいったん縮小して保存
if ($per_w > 1 && $per_h > 1) {
if ($per_dif > 0) {
// 縦に合わせて縮小
$src_w = $w / $per_h;
$src_h = $dst_h;
} else {
// 横に合わせて縮小
$src_w = $dst_w;
$src_h = $h / $per_w;
}
// リサンプリング先画像リソースを生成する
$dst = imagecreatetruecolor($src_w, $src_h);
// getimagesize関数で得られた情報も利用してリサンプリングを行う
imagecopyresampled($dst, $src, 0, 0, 0, 0, $src_w, $src_h, $w, $h);
// 一旦tmpとして保存
$output($dst,'upload_img/temp'.$type);
// tempを元画像としてリソースを再生成
$src = @$create('upload_img/temp'.$type);
}
// 横が$dst_wより大きければ中心点から始点を計算
if ($src_w > $dst_w) {
$sttX = ($src_w - $dst_w)/2;
$src_w = $dst_w;
} else {
$dst_w = $src_w;
}
// 縦が$dst_hより大きければ中心点から始点を計算
if ($src_h > $dst_h) {
$sttY = ($src_h - $dst_h)/2;
$src_h = $dst_h;
} else {
$dst_h = $src_h;
}
}
// リサンプリング先画像リソースを生成する
$dst = imagecreatetruecolor($dst_w, $dst_h);
// getimagesize関数で得られた情報も利用してリサンプリングを行う
imagecopyresampled($dst, $src, 0, 0, $sttX, $sttY, $dst_w, $dst_h, $src_w, $src_h);
// ファイル名を設定して保存する
$fname = "filename";
$photo = $fname.$type;
$output($dst,'upload_img/'.$photo);
// リソースを解放
if (isset($src) && is_resource($src)) {
imagedestroy($src);
}
if (isset($dst) && is_resource($dst)) {
imagedestroy($dst);
}