画像の加工
画像を小さくする・切り取る・形式を変える・保存する、Laravel の画像加工の使い方と、画像の情報の取り出し方、独自のドライバーの作り方を説明します。
アップロードされた写真は、そのまま使うには大きすぎたり、向きがずれていたりすることがあります。Laravel には、画像を小さくしたり、切り取ったり、形式を変えたり、保存したりする機能があります。メソッドをつなげて、順に書いていけます。中では Intervention Image というパッケージが動いていて、PHP の GD と Imagick という2つの画像の拡張(部品)に対応しています。
この機能は、アップロードされたファイル・ファイルのディスクに保存したファイル・自分のパソコンの中のファイル・インターネット上の画像の URL・画像のバイト列(データそのもの)など、いろいろなものに使えます。
use Illuminate\Support\Facades\Image;
$path = Image::fromStorage('avatars/photo.jpg', 'public')
->cover(400, 400)
->toWebp()
->quality(80)
->storePublicly('avatars', 'public');
注意
画像の加工は、CPU(パソコンの頭脳)やメモリを大量に使うことがあります。大きな画像の加工は、アップロードを受け取る HTTP リクエストの中ではなく、キューのジョブ(時間のかかる仕事を、順番待ちの列に入れて、あとで動かすしくみ)にまかせることを考えてください。
インストール#
画像の機能を使う前に、Composer(PHP のパッケージを入れる道具)で Intervention Image を入れます。
composer require intervention/image:^4.0
使うドライバー(画像を実際に加工する部品)に合わせて、PHP に GD か Imagick の拡張が入っていることも確かめてください。
設定#
画像の設定ファイルは config/images.php です。アプリに images の設定ファイルが無いときは、config:publish という Artisan コマンドで、取り出せます。
php artisan config:publish images
この設定ファイルで、アプリの標準の画像のドライバーを決められます。IMAGE_DRIVER 環境変数(.env に書く設定値)でも決められます。使えるドライバーは gd と imagick です。
IMAGE_DRIVER=imagick
| ドライバー | 説明 |
|---|---|
gd |
PHP の GD 拡張を使う |
imagick |
PHP の Imagick 拡張を使う |
画像を読みこむ#
Image ファサード(:: で呼べる窓口)には、画像をいろいろな場所から読みこむメソッドがそろっています。画像の中身は、必要になるまで読みこまれません(遅延読みこみ)。ふつう、画像を加工するとき、またはバイト列を求めたときに、はじめて元が読まれます。
アップロードされたファイル#
届いたリクエストから、アップロードされた画像を取り出すには、image を使います。アップロードされたファイルの Illuminate\Image\Image が返ります。ファイルが無いときは null です。
use Illuminate\Http\Request;
Route::post('/avatar', function (Request $request) {
$request->validate(['avatar' => ['required', 'image']]);
$path = $request->image('avatar')
->cover(400, 400)
->toWebp()
->storePublicly('avatars', 'public');
// ...
});
別のやり方として、Illuminate\Http\UploadedFile から、fromUpload で画像を作れます。
use Illuminate\Support\Facades\Image;
$image = Image::fromUpload($request->file('avatar'));
アップロードされたファイルから作った画像では、元のアップロードされたファイルを、file で取り出せます。
$file = $image->file();
ディスクに保存したファイル#
アプリのファイルのディスクに保存したファイルから、fromStorage で画像を作れます。1つ目の引数はファイルの道すじ、2つ目の引数はディスクの名前です。
use Illuminate\Support\Facades\Image;
$image = Image::fromStorage('avatars/photo.jpg', disk: 'public');
ディスクそのものの image でも、画像を作れます。
use Illuminate\Support\Facades\Storage;
$image = Storage::disk('public')->image('avatars/photo.jpg');
そのほかの元から読む#
Image ファサードには、バイト列・自分のパソコンの中のファイルの道すじ・インターネット上の画像の URL・Base64(画像のデータを文字で表す形式)の文字列から、画像を作るメソッドもあります。
use Illuminate\Support\Facades\Image;
$image = Image::fromBytes($contents);
$image = Image::fromBase64($base64);
$image = Image::fromPath(storage_path('app/avatars/photo.jpg'));
$image = Image::fromUrl('https://example.com/photo.jpg');
| メソッド | 説明 |
|---|---|
image(リクエスト) |
アップロードされた画像から作る。無ければ null |
fromUpload |
UploadedFile から作る |
fromStorage |
ディスクに保存したファイルから作る |
image(ディスク) |
ディスクのオブジェクトから作る |
fromBytes |
バイト列から作る |
fromBase64 |
Base64 の文字列から作る |
fromPath |
パソコンの中のファイルの道すじから作る |
fromUrl |
インターネット上の画像の URL から作る |
画像を加工する#
画像のオブジェクトは「変えられない」ものです(イミュータブル)。加工のメソッドを呼ぶたびに、加工の手順が1つ足された、新しい画像のオブジェクトが返ります。そのため、メソッドを、つなげて書けます。
$image = $request->image('avatar')
->orient()
->cover(400, 400)
->sharpen(10);
加工は、足した順番どおりに進みます。画像が実際に書き出される(エンコードされる)のは、最後の1回だけです。
大きさを変える#
resize は、画像を、決めた大きさに変えます。幅と高さの両方を渡すこともできます。名前つきの引数を使えば、片方だけも渡せます。
$image = $image->resize(800, 600);
$image = $image->resize(width: 800);
$image = $image->resize(height: 600);
scale は、画像を、決めた大きさに収まるように、縦横の比率を保ったまま小さくします。画像を大きくすることは、決してありません。
$image = $image->scale(800, 600);
$image = $image->scale(width: 800);
$image = $image->scale(height: 600);
cover は、画像を、決めた大きさを完全に覆うように、大きさを変え、はみ出た部分を切り取ります。
$image = $image->cover(400, 400);
contain は、画像の全体を残したまま、決めた大きさに収まるように変えます。余った空きの部分は、背景の色(付けなくてもよい)で埋めます。
$image = $image->contain(400, 400);
$image = $image->contain(400, 400, '#ffffff');
$image = $image->contain(400, 400, 'dominant');
背景の色に dominant を渡すと、空きの部分が、画像の代表になる色(dominant。平均の色)で埋められます。
crop で、画像を切り取れます。1つ目と2つ目の引数は、ほしい幅と高さです。付けなくてもよい3つ目と4つ目の引数で、切り取る位置の x と y の座標を決められます。
$image = $image->crop(300, 200);
$image = $image->crop(300, 200, x: 50, y: 25);
| メソッド | 説明 |
|---|---|
resize |
決めた大きさに変える。幅と高さの片方だけも渡せる |
scale |
比率を保ったまま、決めた大きさに収まるように小さくする。大きくはしない |
cover |
決めた大きさを覆うように変えて、はみ出た部分を切り取る |
contain |
画像の全体を残して、決めた大きさに収める。余りは背景の色で埋める |
crop |
画像を切り取る。位置の x と y も決められる |
そのほかの加工#
Laravel には、ほかにも、画像を加工するメソッドがあります。
$image = $image->orient();
$image = $image->rotate(90);
$image = $image->rotate(90, '#ffffff');
$image = $image->rotate(90, 'dominant');
$image = $image->blur(5);
$image = $image->grayscale();
$image = $image->sharpen(10);
$image = $image->flipVertically();
$image = $image->flipHorizontally();
| メソッド | 説明 |
|---|---|
orient |
画像の EXIF(撮影のときの向きなどの情報)に合わせて、向きを直す |
rotate |
画像を時計回りに、決めた角度だけ回す。背景の色も渡せる |
blur |
ぼかす。値は 0 から 100 |
grayscale |
白黒(灰色の濃淡)にする |
sharpen |
くっきりさせる。値は 0 から 100 |
flipVertically |
上下を裏返す |
flipHorizontally |
左右を裏返す |
条件つきの加工#
画像のオブジェクトは、Laravel の Conditionable トレイト(クラスに部品を足すしくみ)に対応しています。そのため、when と unless で、条件によって加工を足せます。
$image = $request->image('avatar')
->when($request->boolean('crop'), fn ($image) => $image->cover(400, 400))
->unless($request->boolean('preserve_format'), fn ($image) => $image->toWebp());
| メソッド | 説明 |
|---|---|
when |
条件が真のときだけ、加工を足す |
unless |
条件が偽のときだけ、加工を足す |
画像の形式を変える(エンコード)#
加工した画像は、ふつう、元の形式のまま書き出されます。取り出す前、または保存する前に、ほかの対応した形式へ変えられます。
$image = $image->toWebp();
$image = $image->toJpg();
$image = $image->toJpeg();
$image = $image->toPng();
$image = $image->toGif();
$image = $image->toAvif();
$image = $image->toBmp();
quality で、書き出す画質を決められます。値は 1 から 100 の範囲に収められます。
$image = $image->toWebp()->quality(80);
optimize は、画像を決めた形式に変え、画質も決めるための近道です。ふつう、画像は、画質 70 の WebP に最適化されます。
$image = $image->optimize();
$image = $image->optimize(format: 'jpg', quality: 85);
加工した画像の中身は、バイト列・Base64 の文字列・データ URI(画像のデータを、そのまま URL の形にしたもの)として取り出せます。
$bytes = $image->toBytes();
$base64 = $image->toBase64();
$dataUri = $image->toDataUri();
画像のオブジェクトを文字列に変えても、データ URI が取り出せます。
$dataUri = (string) $image;
| メソッド | 説明 |
|---|---|
toWebp |
WebP 形式にする |
toJpg |
JPG 形式にする |
toJpeg |
JPEG 形式にする |
toPng |
PNG 形式にする |
toGif |
GIF 形式にする |
toAvif |
AVIF 形式にする |
toBmp |
BMP 形式にする |
quality |
画質を決める。値は 1 から 100 |
optimize |
形式と画質を、まとめて決める。ふつうは、画質 70 の WebP |
toBytes |
バイト列として取り出す |
toBase64 |
Base64 の文字列として取り出す |
toDataUri |
データ URI として取り出す |
画像を保存する#
store は、加工した画像を、アプリのファイルのディスクに保存します。アップロードされたファイルと同じように、Laravel は、ほかとかぶらないファイル名を作り、保存した道すじを返します。2つ目の引数で、ディスクを決められます。
$path = $request->image('avatar')
->cover(400, 400)
->store(path: 'avatars');
$path = $request->image('avatar')
->cover(400, 400)
->store(path: 'avatars', disk: 's3');
保存するファイル名を決めたいときは storeAs を使います。
$path = $request->image('avatar')
->cover(400, 400)
->storeAs(path: 'avatars', name: 'avatar.jpg', disk: 'public');
storePublicly と storePubliclyAs は、画像を public(だれでも見られる)の公開の度合いで保存します。
$path = $request->image('avatar')
->cover(400, 400)
->storePublicly(path: 'avatars', disk: 'public');
$path = $request->image('avatar')
->cover(400, 400)
->storePubliclyAs(path: 'avatars', name: 'avatar.webp', disk: 'public');
画像を保存できなかったときは、これらの保存のメソッドは false を返します。
| メソッド | 説明 |
|---|---|
store |
ほかとかぶらない名前で保存する。道すじを返す |
storeAs |
決めた名前で保存する |
storePublicly |
public で、ほかとかぶらない名前で保存する |
storePubliclyAs |
public で、決めた名前で保存する |
画像の情報を調べる#
画像の MIME タイプ(ファイルの種類を表す名前)・拡張子・大きさ・幅・高さ・代表になる色(dominant)は、次のメソッドで取り出せます。
$mimeType = $image->mimeType();
$extension = $image->extension();
[$width, $height] = $image->dimensions();
$width = $image->width();
$height = $image->height();
$dominantColor = $image->dominantColor();
これらのメソッドは、加工したあとの画像について答えます。たとえば、cover(400, 400) のあとに width を呼ぶと、400 が返ります。
| メソッド | 説明 |
|---|---|
mimeType |
画像の MIME タイプを返す |
extension |
画像の拡張子を返す |
dimensions |
幅と高さを配列で返す |
width |
幅を返す |
height |
高さを返す |
dominantColor |
画像の代表になる色(dominant。平均の色)を返す |
画像のドライバー#
独自の画像ドライバー#
Laravel の画像のマネージャー(ドライバーを管理する部分)は、Laravel の基本の Illuminate\Support\Manager クラスを受けついでいます。そのため、画像のマネージャーと Image ファサードの extend で、独自のドライバーを登録できます。
独自の画像ドライバーは、Illuminate\Contracts\Image\Driver インターフェイス(守るべき約束ごと)を実装します。
processは、元の画像の中身と、順番に並んだIlluminate\Image\ImagePipeline(画像にかける加工の手順)を受け取って、加工した画像のバイト列を返しますdimensionsは、画像の幅と高さを返しますdominantColorは、画像の平均の色を、16 進数の文字列で返します
<?php
namespace App\Images;
use Illuminate\Contracts\Image\Driver;
use Illuminate\Image\ImagePipeline;
class VipsDriver implements Driver
{
/**
* Process the given image contents with the specified pipeline.
*/
public function process(string $contents, ImagePipeline $pipeline): string
{
// Apply the pipeline's transformations and output options...
return $contents;
}
/**
* Get the dimensions of the given image contents.
*/
public function dimensions(string $contents): array
{
// Read the image's width and height...
return [0, 0];
}
/**
* Get the dominant (average) color of the image as a hex string.
*/
public function dominantColor(string $contents): string
{
// Calculate the image's average color...
return '#000000';
}
/**
* Register a transformation handler.
*/
public function transformUsing(string $transformation, callable $callback): static
{
// Store the handler so it may be applied while processing the pipeline...
return $this;
}
}
補足
独自の画像ドライバーの作り方をよく知るには、フレームワークに入っている Illuminate\Image\Drivers\InterventionDriver クラスを見ると参考になります。
独自のドライバーを作ったら、Image ファサードの extend で登録します。ふつうは、サービスプロバイダ(アプリの起動のときに、道具を登録する場所)の boot メソッドに書きます。
use App\Images\VipsDriver;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\Facades\Image;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Image::extend('vips', function (Application $app) {
return new VipsDriver;
});
}
ドライバーを登録したら、using で、決めた画像だけに、そのドライバーを使えます。
$image = $request->image('avatar')
->using('vips')
->cover(400, 400);
アプリの config/images.php の default や、IMAGE_DRIVER 環境変数で、独自のドライバーを標準にすることもできます。
IMAGE_DRIVER=vips
| メソッド | 説明 |
|---|---|
process |
元の画像と加工の手順を受け取り、加工した画像のバイト列を返す |
dimensions |
画像の幅と高さを返す |
dominantColor |
画像の平均の色を、16 進数の文字列で返す |
transformUsing |
加工の処理を登録する |
独自の加工#
アプリやパッケージは、独自の加工を作れます。Illuminate\Contracts\Image\Transformation コントラクト(約束ごと)を実装したクラスを作ります。作った加工は、transform で、画像の加工の手順に足せます。
<?php
namespace App\Images\Transformations;
use Illuminate\Contracts\Image\Transformation;
class Pixelate implements Transformation
{
public function __construct(
public readonly int $size,
) {
//
}
}
次に、Image ファサードの transformUsing で、その加工とドライバーの組に、処理を登録します。ふつうは、サービスプロバイダの boot メソッドに書きます。
use App\Images\Transformations\Pixelate;
use Illuminate\Support\Facades\Image;
use Intervention\Image\Interfaces\ImageInterface;
Image::transformUsing('gd', Pixelate::class, function (ImageInterface $image, Pixelate $transformation) {
return $image->pixelate($transformation->size);
});
加工の処理を登録したら、画像に、その加工をかけられます。
use App\Images\Transformations\Pixelate;
$image = $request->image('avatar')
->transform(new Pixelate(12))
->store('avatars');
関連するページ#
公式ドキュメント(英語)
2026年10月5日時点の内容をもとに、日本語でまとめています。