【Laravel / Intervention Image】 画像をリサイズして圧縮する (横向き問題も解消)

えびさん

大きい画像などをサムネイルでたくさん表示するとページ遅延の原因になる
そこで、アップロードする時に圧縮処理も追加したときのメモ

Intervention Imageを入れる

  • composerで入れる
composer require intervention/image

サイトはこちら

Laravel5.5以降の場合は Package Auto Discoveryが導入されているので、
上記のコマンドを実行するだけですぐに使用可能になる

※ Laravel5.4以前の場合は、下記作業も必要↓↓

  • app/config.phpの変更
'providers' => [
    // ... (省略)
    Intervention\Image\ImageServiceProvider::class,  // ⭐️ 追記
],

'aliases' => [ 
   // ... (省略)
   'Image' => Intervention\Image\Facades\Image::class, // ⭐️ 追記
],
Package Auto Discoveryとは

Laravel5.5から導入された、Composerのパッケージを自動で検出する仕組み

composer requirecomposer install/update をした時に
自動で読み込んでくれるので、config/app.phpへの追記作業が不要になる ( 便利!)
composer removeした際は読み込みを解除してくれるので至れり尽くせり

(参考) https://laravel-news.com/package-auto-discovery

使い方

  • \Image::make('***')で対象のファイルを読み込んでresizeでサイズ変更する
// 画像を読み込む
$image = \Image::make($filePath);
// EXIFのOrientationによって回転させる
$image->orientate();
// リサイズする
$image->resize(600, null,
  function ($constraint) {
    // 縦横比を保持したままにする
    $constraint->aspectRatio();
    // 小さい画像は大きくしない
    $constraint->upsize();
  }
);
// 保存する
$image->save(storage_path('***/*****.png'));

\Image::make()について

\Image::make()の引数には、
ファイルURLやパス、UploadedFileなど様々な形式で指定ができる

例えばフォームでアップロードされたファイルは、下記のように読み込む

\Image::make($request->file('file'));
$image->orientate()について

これをしとかないと、
スマホでアップされた画像が勝手に横向きになったりするので要注意

$image->resize()について

第1引数に$width, 第2引数に$heightを指定する(指定なしの場合はnull)
第3引数では、$callbackでリサイズする対象のClosureオブジェクトを使用できるので、ここでリサイズ時のオプション設定ができる
(参考) http://image.intervention.io/api/resize

下記の例だと、横幅は600pxで縦幅は指定なしの設定

$image->resize(
  600, // 横幅
  null, // 縦幅
  function ($constraint) { // コールバック関数でオプション設定
    // 縦横比を保持したままにする
    $constraint->aspectRatio();
    // 小さい画像は大きくしない
    $constraint->upsize();
  }
);

Controllerで使う場合

  • フォームでアップロードされたファイルを圧縮してみる
function upload(Request $request) {
  // 一意のファイル名を作成
  $filename = now()->format('YmdHis').uniqid('', true). "." . $img->extension();
  // アップロードファイルを取得
  $file = $request->file('file');
  $file = \Image::make($file)->setFileInfoFromPath($file);
  // 圧縮
  $file->orientate()->resize(
    600,
    null,
    function ($constraint) {
      $constraint->aspectRatio();
      $constraint->upsize();
    }
  );
  //  保存
  $file->save(storage_path(). "/app/public/{ディレクトリ名}/resized-{$filename}");
}

\ 案件のご依頼・ご相談はこちらから /