本文へ移動
Laravel Tips

画像の加工

画像を小さくする・切り取る・形式を変える・保存する、Laravel の画像加工の使い方と、画像の情報の取り出し方、独自のドライバーの作り方を説明します。

アップロードされた写真は、そのまま使うには大きすぎたり、向きがずれていたりすることがあります。Laravel には、画像を小さくしたり、切り取ったり、形式を変えたり、保存したりする機能があります。メソッドをつなげて、順に書いていけます。中では Intervention Image というパッケージが動いていて、PHP の GD と Imagick という2つの画像の拡張(部品)に対応しています。

この機能は、アップロードされたファイル・ファイルのディスクに保存したファイル・自分のパソコンの中のファイル・インターネット上の画像の URL・画像のバイト列(データそのもの)など、いろいろなものに使えます。

php
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 を入れます。

bash
composer require intervention/image:^4.0

使うドライバー(画像を実際に加工する部品)に合わせて、PHP に GD か Imagick の拡張が入っていることも確かめてください。

設定#

画像の設定ファイルは config/images.php です。アプリに images の設定ファイルが無いときは、config:publish という Artisan コマンドで、取り出せます。

bash
php artisan config:publish images

この設定ファイルで、アプリの標準の画像のドライバーを決められます。IMAGE_DRIVER 環境変数(.env に書く設定値)でも決められます。使えるドライバーは gd と imagick です。

ini
IMAGE_DRIVER=imagick
ドライバー 説明
gd PHP の GD 拡張を使う
imagick PHP の Imagick 拡張を使う

画像を読みこむ#

Image ファサード(:: で呼べる窓口)には、画像をいろいろな場所から読みこむメソッドがそろっています。画像の中身は、必要になるまで読みこまれません(遅延読みこみ)。ふつう、画像を加工するとき、またはバイト列を求めたときに、はじめて元が読まれます。

アップロードされたファイル#

届いたリクエストから、アップロードされた画像を取り出すには、image を使います。アップロードされたファイルの Illuminate\Image\Image が返ります。ファイルが無いときは null です。

php
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 で画像を作れます。

php
use Illuminate\Support\Facades\Image;

$image = Image::fromUpload($request->file('avatar'));

アップロードされたファイルから作った画像では、元のアップロードされたファイルを、file で取り出せます。

php
$file = $image->file();

ディスクに保存したファイル#

アプリのファイルのディスクに保存したファイルから、fromStorage で画像を作れます。1つ目の引数はファイルの道すじ、2つ目の引数はディスクの名前です。

php
use Illuminate\Support\Facades\Image;

$image = Image::fromStorage('avatars/photo.jpg', disk: 'public');

ディスクそのものの image でも、画像を作れます。

php
use Illuminate\Support\Facades\Storage;

$image = Storage::disk('public')->image('avatars/photo.jpg');

そのほかの元から読む#

Image ファサードには、バイト列・自分のパソコンの中のファイルの道すじ・インターネット上の画像の URL・Base64(画像のデータを文字で表す形式)の文字列から、画像を作るメソッドもあります。

php
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つ足された、新しい画像のオブジェクトが返ります。そのため、メソッドを、つなげて書けます。

php
$image = $request->image('avatar')
    ->orient()
    ->cover(400, 400)
    ->sharpen(10);

加工は、足した順番どおりに進みます。画像が実際に書き出される(エンコードされる)のは、最後の1回だけです。

大きさを変える#

resize は、画像を、決めた大きさに変えます。幅と高さの両方を渡すこともできます。名前つきの引数を使えば、片方だけも渡せます。

php
$image = $image->resize(800, 600);
$image = $image->resize(width: 800);
$image = $image->resize(height: 600);

scale は、画像を、決めた大きさに収まるように、縦横の比率を保ったまま小さくします。画像を大きくすることは、決してありません。

php
$image = $image->scale(800, 600);
$image = $image->scale(width: 800);
$image = $image->scale(height: 600);

cover は、画像を、決めた大きさを完全に覆うように、大きさを変え、はみ出た部分を切り取ります。

php
$image = $image->cover(400, 400);

contain は、画像の全体を残したまま、決めた大きさに収まるように変えます。余った空きの部分は、背景の色(付けなくてもよい)で埋めます。

php
$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 の座標を決められます。

php
$image = $image->crop(300, 200);
$image = $image->crop(300, 200, x: 50, y: 25);
メソッド 説明
resize 決めた大きさに変える。幅と高さの片方だけも渡せる
scale 比率を保ったまま、決めた大きさに収まるように小さくする。大きくはしない
cover 決めた大きさを覆うように変えて、はみ出た部分を切り取る
contain 画像の全体を残して、決めた大きさに収める。余りは背景の色で埋める
crop 画像を切り取る。位置の x と y も決められる

そのほかの加工#

Laravel には、ほかにも、画像を加工するメソッドがあります。

php
$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 で、条件によって加工を足せます。

php
$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 条件が偽のときだけ、加工を足す

画像の形式を変える(エンコード)#

加工した画像は、ふつう、元の形式のまま書き出されます。取り出す前、または保存する前に、ほかの対応した形式へ変えられます。

php
$image = $image->toWebp();
$image = $image->toJpg();
$image = $image->toJpeg();
$image = $image->toPng();
$image = $image->toGif();
$image = $image->toAvif();
$image = $image->toBmp();

quality で、書き出す画質を決められます。値は 1 から 100 の範囲に収められます。

php
$image = $image->toWebp()->quality(80);

optimize は、画像を決めた形式に変え、画質も決めるための近道です。ふつう、画像は、画質 70 の WebP に最適化されます。

php
$image = $image->optimize();
$image = $image->optimize(format: 'jpg', quality: 85);

加工した画像の中身は、バイト列・Base64 の文字列・データ URI(画像のデータを、そのまま URL の形にしたもの)として取り出せます。

php
$bytes = $image->toBytes();
$base64 = $image->toBase64();
$dataUri = $image->toDataUri();

画像のオブジェクトを文字列に変えても、データ URI が取り出せます。

php
$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つ目の引数で、ディスクを決められます。

php
$path = $request->image('avatar')
    ->cover(400, 400)
    ->store(path: 'avatars');

$path = $request->image('avatar')
    ->cover(400, 400)
    ->store(path: 'avatars', disk: 's3');

保存するファイル名を決めたいときは storeAs を使います。

php
$path = $request->image('avatar')
    ->cover(400, 400)
    ->storeAs(path: 'avatars', name: 'avatar.jpg', disk: 'public');

storePublicly と storePubliclyAs は、画像を public(だれでも見られる)の公開の度合いで保存します。

php
$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)は、次のメソッドで取り出せます。

php
$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
<?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 メソッドに書きます。

php
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 で、決めた画像だけに、そのドライバーを使えます。

php
$image = $request->image('avatar')
    ->using('vips')
    ->cover(400, 400);

アプリの config/images.php の default や、IMAGE_DRIVER 環境変数で、独自のドライバーを標準にすることもできます。

ini
IMAGE_DRIVER=vips
メソッド 説明
process 元の画像と加工の手順を受け取り、加工した画像のバイト列を返す
dimensions 画像の幅と高さを返す
dominantColor 画像の平均の色を、16 進数の文字列で返す
transformUsing 加工の処理を登録する

独自の加工#

アプリやパッケージは、独自の加工を作れます。Illuminate\Contracts\Image\Transformation コントラクト(約束ごと)を実装したクラスを作ります。作った加工は、transform で、画像の加工の手順に足せます。

php
<?php

namespace App\Images\Transformations;

use Illuminate\Contracts\Image\Transformation;

class Pixelate implements Transformation
{
    public function __construct(
        public readonly int $size,
    ) {
        //
    }
}

次に、Image ファサードの transformUsing で、その加工とドライバーの組に、処理を登録します。ふつうは、サービスプロバイダの boot メソッドに書きます。

php
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);
});

加工の処理を登録したら、画像に、その加工をかけられます。

php
use App\Images\Transformations\Pixelate;

$image = $request->image('avatar')
    ->transform(new Pixelate(12))
    ->store('avatars');

関連するページ#

公式ドキュメント(英語)

2026年10月5日時点の内容をもとに、日本語でまとめています。

ページの一覧