概要
PHPの画像処理ライブラリであるIntervention Imageのバージョン3をLaravelで使う方法について解説します。
先日、Qiitaの質問で「Intervention Imageがエラーで使えない」というものがありました。私も使ったことがあるので調べてみたのですが、どうやら2023年12月にバージョン2から3へアップデートされたようです。そして、それによって「Laravel Intervention Image」といったキーワード検索でヒットする記事の情報では導入できなくなってしまったので、この記事を執筆することにしました。
Intervention Imageのバージョンアップについて
上記のアップグレードガイドを参照すると、次のように記載されています。
Intervention Image 3 は、以前のバージョンから引き継がれたコードがほとんどなく、根本から書き直されました。これは、PHP 8 以降の最新の機能を活用した、より現代的で洗練されたアーキテクチャと API を意味します。(機械翻訳)
このようにバージョン2から3へアップデートされるにあたって大幅に変更されたようです。さらにLaravelのサポートについては次のように記載されています。
Laravel のサービスプロバイダーは、フレームワークへの依存を回避し、以前からそうであったフレームワークに依存しない介入イメージを強調するために削除されました。(機械翻訳)
このように、バージョン2に同梱されていたLaravelのサービスプロバイダーはバージョン3では削除されました。既存の記事ではこのサービスプロバイダーを用いた方法が説明されていたので、それをバージョン3で記事のとおりにやってみてもうまくいかないというわけですね。
その他にもさまざまな変更があるので、古いバージョンの情報を参照されている場合はアップグレードガイドを一読されることをお勧めします。
バージョン2のLaravelサービスプロバイダーについて
バージョン2の「Laravel のサービスプロバイダー」についてもう少し触れておきましょう。既存の記事には次のような記載が見られます。
'providers' => [
Intervention\Image\ImageServiceProvider::class
],
'aliases' => [
'Image' => Intervention\Image\Facades\Image::class
]
ここにあるIntervention\Image\ImageServiceProvider
やIntervention\Image\Facades\Image
が「フレームワークへの依存を回避する」という理由から削除されました。これらの設定を追加しても、残念ながらnot foundエラーが発生して動くことはありません。
それではIntervention Imageのバージョン3をLaravelで使う方法を見ていきましょう。
バージョン3をLaravelで使う方法
まずはドキュメントを参照して、Composerを介してインストールするところまで進めてください。そしてインストールが完了したらcomposer.json
ファイルやcomposer.lock
ファイルを見てintervention/image
のバージョン3がインストールされていることを確認してください。
方法1 サービスプロバイダーを使わない
LaravelでIntervention Imageを使うにあたり、サービスプロバイダー使う方法は必須ではありません。例えば下記のコードはLaravelのコントローラーで使用する例ですが、ほとんどドキュメントと同じであることに気がつくでしょう。
<?php
namespace App\Http\Controllers;
use Intervention\Image\ImageManager;
use Intervention\Image\Drivers\Gd\Driver;
class ImageController extends Controller
{
public function index()
{
// 希望するドライバーで新しいマネージャー インスタンスを作成する
$manager = new ImageManager(new Driver());
// 画像を垂直に反転し、別名で保存する例
$imgPath = storage_path('app/public/hoge.png');
$img = $manager->read($imgPath);
$img->flop();
$img->save(storage_path('app/public/hoge-flip.png'));
}
}
ただし、複数の箇所でIntervention Imageを使う場合、この方法ではマネージャー インスタンスを作成することが冗長に感じるかもしれません。次の例を見てください。
use Intervention\Image\ImageManager;
use Intervention\Image\Drivers\Gd\Driver;
class HogeController extends Controller
{
public function index()
{
$manager = new ImageManager(new Driver());
// ...
}
}
use Intervention\Image\ImageManager;
use Intervention\Image\Drivers\Gd\Driver;
class FugaController extends Controller
{
public function index()
{
$manager = new ImageManager(new Driver());
// ...
}
}
このように複数の場所で利用する場合、同じような処理を書くことになります。このような状態で、例えばドライバーをGDからImagickに変更したい時は複数の箇所を漏れなく変更する必要があります。こういった状況になる場合は、Laravelのサービスプロバイダーを使う方法が選択肢としてあがるかもしれません。
方法2 サービスプロバイダーを使う
まず最初に目指すところを確認しましょう。
use Intervention\Image\ImageManager;
class ImageController extends Controller
{
public function index(ImageManager $manager)
{
$img = $manager->read(
storage_path('app/public/hoge.png')
);
}
}
このようにサービスを注入する形にすることによって、ImageManager
のインスタンス生成を省きたと思います。そのために、サービスプロバイダー1を利用してImageManager
をサービスとして登録しましょう。
まずはmake:provider
Artisanコマンドでプロバイダーを生成します。そして、サービスコンテナ2に結合していきます。
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Intervention\Image\Drivers\Gd\Driver;
use Intervention\Image\ImageManager;
class ImageServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton(ImageManager::class, function () {
return new ImageManager(new Driver());
});
}
}
サービスプロバイダーを作成した後はconfig/app.php
で登録します。
'providers' => ServiceProvider::defaultProviders()->merge([
// ...
App\Providers\ImageServiceProvider::class,
])->toArray(),
これでサービスプロバイダーがアプリケーションにロードされ、コントローラーにサービスとして注入されるようになりました。
さて改めて「ドライバーをGDからImagickに変更したい場合」を考えてみましょう。サービスプロバイダーを利用することによって、ImageManager
のインスタンス生成はおこなわれているので、一箇所を変更するだけで済みます。
まとめ
2023年12月にIntervention Imageがバージョン3にアップデートされたことにより、大幅な変更がありました。そのため、Laravelでの使い方を紹介した記事の情報が古いものになってしまいました。
これからLaravelでIntervention Imageを使う方にとって、この記事の情報が参考になれば幸いです。
おまけ
Intervention Imageを使うためのサービスプロバイダをパッケージとして公開してみました。