この記事は一人PHP総復習 Advent Calendar 20164日目の記事です。
いきなり内容が飛びますが、進捗がやばいので一旦書きます汗
PHPで画像をリサイズ&圧縮する際、どのライブラリを使うのがよいのか迷っていくつか調べたのでまとめておきます。
Laravelの記法などを大いに含むので、How toは参考程度にしてください。
サンプルでは保存をjpgにしてますが、元ファイルの拡張子を取得などしてください。あと本来必要なエラー処理とかも省いています。
試した環境
- PHP7
- Laravel5.3
php-gd
PHP拡張モジュールのGDを使う方法です。
導入はこちらの記事などを参考に。
How to
$h = 200; // リサイズしたい大きさを指定
$w = 200;
$file = $request->file; // 加工したいファイルを指定
// 加工前の画像の情報を取得
list($original_w, $original_h, $type) = getimagesize($file);
// 加工前のファイルをフォーマット別に読み出す(この他にも対応可能なフォーマット有り)
switch ($type) {
case IMAGETYPE_JPEG:
$original_image = imagecreatefromjpeg($file);
break;
case IMAGETYPE_PNG:
$original_image = imagecreatefrompng($file);
break;
case IMAGETYPE_GIF:
$original_image = imagecreatefromgif($file);
break;
default:
throw new RuntimeException('対応していないファイル形式です。: ', $type);
}
// 新しく描画するキャンバスを作成
$canvas = imagecreatetruecolor($w, $h);
imagecopyresampled($canvas, $original_image, 0,0,0,0, $w, $h, $original_w, $original_h);
$resize_path = public_path('image/new.jpg'); // 保存先を指定
switch ($type) {
case IMAGETYPE_JPEG:
imagejpeg($canvas, $resize_path);
break;
case IMAGETYPE_PNG:
imagepng($canvas, $resize_path, 9);
break;
case IMAGETYPE_GIF:
imagegif($canvas, $resize_path);
break;
}
// 読み出したファイルは消去
imagedestroy($original_image);
imagedestroy($canvas);
特徴
- フォーマット別に処理を分けなくてはいけない
- フォーマット別に圧縮率を分けやすい
- 元画像の情報を取得しなくてはいけない
- 基本の処理だけなら十分
Imagick
画像処理ツールImageMagickをPHPから使う拡張モジュールです。
導入はこちらの記事などを参考に。
CentOS6 上のPHPでImageMagickを動かす
How to
$w = 200; // リサイズしたい大きさを指定
$h = 200;
$file = $request->file; // 加工したいファイルを指定
$resize_path = public_path('image/new.jpg'); // 保存先を指定
// 加工するファイルを読み出し
$original_image = new Imagick($file);
$original_image->resizeImage($w, $h, Imagick::FILTER_LANCZOS, 1);
$original_image->writeImage($resize_path);
// 読み出したイメージは消去
$original_image->destroy();
特徴
- 対応フォーマット、できる処理はかなり多い
- 加工後のファイルサイズが大きくなる
- リサイズ・圧縮だけならオーバースペック感
Intervention/Image
LaravelプラグインのIntervention/Imageを使う方法です。
GDとImagickをラップしています。
導入、設定などはこちらの記事などを参考に。
Laravel5 Intervention Image 2.xを利用した画像加工
How to
$h = 200; // リサイズしたい大きさを指定
$w = 200;
$resize_path = public_path('image/new.jpg'); // 保存先を指定
$original_image = Image::make($file->path);
$original_image->resize($w, $h);
$original_image->save($resize_path);
サイズが片方だけ指定されているときは元画像の縦横比に合わせてリサイズしてくれます。
$image->resize(200, null, function ($constraint) {
$constraint->aspectRatio();
});
特徴
- 簡潔に記述できる
- 圧縮率は一括指定できるが、PNG、GIFなどは未対応
- 基本的にこれで良さそう
まとめ
Intervention/ImageはGDもImagickもラップしてくれているので、基本的にこれを選択するので良さそうです。(他にユースケースがあれば教えてください)
あとIntervention/Imageでもpngとか圧縮したい場合はどうするのがベストなのでしょう・・。場合分けしてベタの関数書くしかないのかな。