アップロードした画像をリサイズしてサムネイル用に真四角にする

2018-02-26

画像アップロードで複数サイズを生成する際に、そういえば真四角にトリミングする方法を知らなかったなぁと思いまして、考えてみました。

サンプルはこちら

縦長でも横長でもだいたい中央でトリミングされているかと思います。画像のドラッグドロップに関してはこちらに書いていますので省きます。

phpでアップロードした画像をリサイズする

	$upload_Dir = 'upload/';
//アップロードされた画像の情報
$ufile_oname    = $_FILES['image']['name'];
$ufile_mine     = $_FILES['image']['type'];
$ufile_size     = $_FILES['image']['size'];
$ufile_tmp      = $_FILES['image']['tmp_name'];
$ufile_errcode  = $_FILES['image']['error'];
$size           = getimagesize("$ufile_tmp");
$img_w          = $size[0];
$img_h          = $size[1];
$ext            = substr($ufile_oname,-3);
$ext            = strtolower($ext);
$return = false;
if($ext!='jpg' && $ext!='png'){ //拡張子確認
$return = 'err/imgtype_error';
}
else if($ufile_size > upmax){ //サイズ確認
$return = 'err/size_error';
}
else{
$file_name = date('YmdHis'); //ファイル名はユニークにする
$new_upload_file  = $upload_Dir . $file_name . "." . $ext;
if(move_uploaded_file($ufile_tmp,$new_upload_file) && $return === false){
if( $ext == 'jpg'):
$imagecreatefrom = imagecreatefromjpeg($new_upload_file);
elseif($ext == 'png'):
$imagecreatefrom = imagecreatefrompng($new_upload_file);
endif;
$thm_size = 300; //作成するサムネイルの幅(縦)
//横長画像の場合 ------------
if($size[0] > $size[1]){
$hiritu = $img_w / $img_h;       //比率
$m_width  = $thm_size * $hiritu; //リサイズする幅
$m_height = $thm_size;           //リサイズする縦
//リサイズした画像を作成
$newimage        = imagecreatetruecolor($m_width, $m_height);
$resize_image    = imagecopyresampled($newimage, $imagecreatefrom, 0, 0, 0, 0, $m_width, $m_height, $img_w, $img_h);
$x = ($m_width-$thm_size) / 2; //x軸の位置をセンターに
$y = 0;
}
//縦長画像の場合 ------------
else if($size[0] < $size[1]){
$hiritu = $img_h / $img_w;       //比率
$m_width  = $thm_size;           //リサイズする幅
$m_height = $thm_size * $hiritu; //リサイズする縦
$newimage        = imagecreatetruecolor($m_width, $m_height);
$resize_image    = imagecopyresampled($newimage, $imagecreatefrom, 0, 0, 0, 0, $m_width, $m_height, $img_w, $img_h);
$x = 0;
$y = ($m_height-$thm_size) / 2; //y軸の位置をセンターに
}
//サムネイルサイズで白紙の画像を作成
$created_image = imagecreatetruecolor($thm_size, $thm_size);
imagefill($created_image , 0 , 0 , 0xFFFFFF);
//リサイズした画像をx,y軸を指定して貼り付ける
imagecopyresampled($created_image,$newimage,
0, // レイヤー画像 x 座標
0, // レイヤー画像 y 座標
$x, // 元の x 座標
$y, // 元の y 座標
$thm_size, //レイヤー画像 幅
$thm_size, //レイヤー画像 高
$thm_size, //元画像ファイル 幅
$thm_size  //元画像ファイル 高
);
if( $ext == 'jpg'):
imagejpeg($created_image, $new_upload_file);
elseif($ext == 'png'):
imagepng($created_image, $new_upload_file);
endif;
$return = $new_upload_file;
}else{
$return = 'err/move_error';
}
}
echo $return;

画像のアップロード方法は色々なサイトで紹介されているので省きますが、簡単に言えばアップロードされた画像を、作成したい縦横サイズを指定してリサイズすることになります。当然、縦横の比率に応じて計算し、新しい縦横サイズを決めてあげないとぴったりと収まりません。

横長画像の例
$hiritu = $img_w / $img_h;       //比率
$m_width  = 300 * $hiritu; //リサイズする幅
$m_height = 300;           //リサイズする縦
//リサイズした画像を作成
$newimage        = imagecreatetruecolor($m_width, $m_height);
$resize_image    = imagecopyresampled($newimage, $imagecreatefrom, 0, 0, 0, 0, $m_width, $m_height, $img_w, $img_h);
$x = ($m_width-300) / 2; //x軸の位置をセンターに
$y = 0;

横÷縦で比率を求め、サムネイルサイズ(300pxと仮定)で縮小した画像サイズを決めます。縦はそのまま300px、横は300pxに比率を掛けたものになります。そのサイズで画像を作成しておきます。ここで中央に寄せる位置を決めるのですが、縦は300pxそのままなので0、横はリサイズした幅から300pxを引き、その半分の位置を左端にする事で中央に寄る事になります。

縦長画像は縦に対してこの計算を行います。

 

サイズが決まったらサムネイル画像を作成
//サムネイルサイズで白紙の画像を作成
$created_image = imagecreatetruecolor($thm_size, $thm_size);
imagefill($created_image , 0 , 0 , 0xFFFFFF);
//リサイズした画像をx,y軸を指定して貼り付ける
imagecopyresampled($created_image,$newimage,
0, // レイヤー画像 x 座標
0, // レイヤー画像 y 座標
$x, // 元の x 座標
$y, // 元の y 座標
$thm_size, //レイヤー画像 幅
$thm_size, //レイヤー画像 高
$thm_size, //元画像ファイル 幅
$thm_size  //元画像ファイル 高
);

あとは300px * 300px で白紙の画像を作成し、決めた座標を指定して貼り付けるだけですね。

おそらくこの手の処理を簡単に出来るプラグインとか有ると思うんですが、自分で出来ればコントロールし易いかと思います。今はもう、WordPress等のCMSが主流ですので、あえてこういったものを作る案件って少ないのですが、HTMLのみで作成したサイトにお知らせを掲載したいといったことも多少は有りますので、エディターなんかに組み込むと良いかもしれません。