【Laravel】Intervention Imageで画像圧縮!表示方法や保存方法とは

この記事からわかること

  • Intervention ImageLaravel導入する方法
  • 読み込んだ画像表示させる方法
  • 保存する際のパス指定の注意点

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

Intervention Imageのインストール方法

Laravel(というよりphp)の便利なライブラリの1つ「Intervention Image」。画像操作に長けており、圧縮や加工、透かしなどライブラリを読み込むだけで簡単に操作できるようになります。

おすすめ記事:公式:Intervention Image

導入するまでのステップ

まずはcomposerを使ってIntervention Imageをインストールしていきます。

$ composer require intervention/image
Using version ^2.7 for intervention/image
./composer.json has been updated
Running composer update intervention/image
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
> @php artisan vendor:publish --tag=laravel-assets --ansi --force
No publishable resources for tag [laravel-assets].
Publishing complete.

インストールが完了したら「config」>「app.php」providerとaliasの部分に以下のように追記します。

'providers' => [
    Illuminate\Auth\AuthServiceProvider::class,
    〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
    // 追記
    Intervention\Image\ImageServiceProvider::class, 
]
'aliases' => [
    'App' => Illuminate\Support\Facades\App::class,
    〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
    // 追記
    'InterventionImage' => Intervention\Image\Facades\Image::class,
]

次に「GD」と呼ばれる画像を生成、操作するためのphpライブラリを組み込みます。実は画像操作をしているのはこのライブラリでややこしいGDでの操作を簡単に扱えるようにしているのが「Intervention Image」になります。組み込みは以下のコマンドを実行します。

$ php artisan vendor:publish --provider="Intervention\Image\ImageServiceProviderLaravelRecent"

これにより「config」内に使用する画像操作ライブラリ(今回はGD)が記述された「image.php」が作成「されます。

「config」> 「image.php」

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Image Driver
    |--------------------------------------------------------------------------
    |
    | Intervention Image supports "GD Library" and "Imagick" to process images
    | internally. You may choose one of them according to your PHP
    | configuration. By default PHP's "GD Library" implementation is used.
    |
    | Supported: "gd", "imagick"
    |
    */

    'driver' => 'gd'

];

これで導入〜設定まで完了です。configのキャッシュを念のため削除しておき、使用していきます。

$ php artisan config:clear

画像圧縮や表示などの使用方法

フォームデータから読み込む使用例

use InterventionImage;

class ImageController extends Controller
{
  if ($request->file !== null) {
            // 画像データが格納されているなら
            $image = InterventionImage::make($request->file);
            $image->orientate();
            $image->resize(
                600,
                null,
                function ($constraint) {
                    // 縦横比を保持したままにする
                    $constraint->aspectRatio();
                    // 小さい画像は大きくしない
                    $constraint->upsize();
                }
            );
            $filePath = storage_path('app/public/uploads');
            $image->save($filePath . '/user-id' . $user_id . '.png');
            $imagePath = 'storage/uploads/user-id' . $user_id . '.png';
}

コントローラーなどで使う際はuse文で「Intervention Image」を読み込んで使用します。aliasに指定したキー値を読み込めばOKです。

use InterventionImage;

操作するには画像を読み込むImage::make($filePath);の形から始まります。$filePathの部分には外部の画像URLなど様々な形式に対応してくれます。

読み込めるデータ

Intervention Imageに読み込んだ画像をそのまま表示させるにはresponseメソッドを使って以下のようにすればOKです。

$image = Image::make($filePath);
return $image->response('png');
// 画像データが表示される

これでWebページ上に読み込んだ画像を表示させることができます。

続いて画像を圧縮/加工していきます。画像自体の大きさを変更することで容量を軽減させることができます。例えば横幅を500pixel、縦幅を300pixelに変更する場合はresizeメソッドで実現できます。第一引数に横幅、第二引数に縦幅、第三引数にオプションを指定できます。

$image->resize(500, 300);

横幅は設定しつつ縦幅は画像のアスペクト比(横と縦の比率)を変更しない大きさにしたい場合は第二引数にnull値を、オプションで以下のように指定すれば実現できます。指定値より小さい画像は拡大しないようにすることも可能です。

$image->resize(600, null,
  function ($constraint) {
    // アスペクト比は変更させない
    $constraint->aspectRatio();

    // 指定横幅より小さい画像は変更しない
    $constraint->upsize();
  }
);

スマホからアップロードした際に画像の向きが変化しないようにするにはorientateメソッドを使用します。このメソッドはEXIFデータ(写真の撮影日時や絞り具合、加工した情報などを保持している画像データ)の場合にのみ作動します。

// スマホアップ画像に対応
$image->orientate();

Laravel内にアップロードされたファイルを保存する方法

Laravel内にユーザーからアップロードされたファイルを保存していく場合はpublicフォルダの中ではなくstorageフォルダの中に入れていきます。

├── Laravelプロジェクト
│      ├── public
│             ├── css
│             └── image
│
│      ├── storage
│             ├── app
│                  └── public  // この中に保存していく
│             ├── framework
│             └── logs

「storage」>「app」>「public」の中に「uploads」フォルダを作成しておき、そこに保存されるように設定していきます。

Intervention Imageを導入していなければstoreAsメソッドで保存できますが導入した場合はsaveメソッドを使っていきます。使い方は引数に保存先のパスを指定するだけです。パスの中にファイル名まで含めれば指定の名前で保存させることもできます。

// storageまでのパスを取得
$filePath = storage_path('app/public/uploads');
// ファイル名を指定して保存
$image->save($filePath . '/user-id' . $user_id . '.png');

storageへの保存ができたらpublicフォルダ内とstorageフォルダを紐づけるシンボリックリンクを貼ります。これをしないと画像が表示されないので注意してください。シンボリックリンクはartisanコマンドで作成できます。

$ php artisan storage:link

こちらの記事にはIntervention Imageを使わない場合のアップロード方法をまとめていますので参考にしてください。

Intervention Image導入で出たエラー解決

Quality must range from 0 to 100.

このエラーはsaveメソッドの引数違いのために起きていたエラーでした。最初storeAsメソッドで記述していたコードをsaveメソッドに書き換えた際に引数を変更していなかったためエラーが出たようです。

Intervention\Image\Exception\NotWritableException Can't write image data to path().

このエラーは指定している画像パスが正しくない時に発生するエラーです。画像パス指定はややこしいので注意してください。

私がLaravel学習に使用した参考書

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index