dimensions — 画像の幅・高さ・比率を検証するルール

validation
  • カテゴリ: validation
  • 掲載バージョン: Laravel 12・PHP 8.4
  • 名前空間 / FQCN / コマンド: dimensions(バリデーションルール), Illuminate\Validation\Rules\Dimensions (Readouble)
  • 関連: image / Illuminate\Validation\Rules\File::image() / size / between
  • 変更履歴: Laravel 5.2 で追加、5.4 以降で Rule::dimensions() によるオブジェクト記法が利用可能。Laravel 10〜12 で挙動差分ほぼなし。(Qiita)

要点(TL;DR)

  • 何に使うか:アップロード画像の「幅・高さ・アスペクト比(縦横比)」が条件を満たしているかをチェックする。
  • 最低限の使い方'avatar' => 'image|dimensions:min_width=400,min_height=400'
  • よくある罠
    • dimensions画像用imageFile::image() を付け忘れると想定外のエラーになる。(Readouble)
    • パラメータ名(min_width / max_height など)のスペルミスでルールが効いていない。(Qiita)
    • ratio は「幅/高さ」なので、 "3/2"1.5 では表現が違うことに注意。

概要

dimensions ルールは、アップロードされた画像ファイルのピクセル単位の幅・高さ・比率を検証するためのルールです。
「サムネイルは 16:9 固定」「アイコンは 512×512 ちょうど」「横 1200px 以上のOG画像だけ許可」など、フロント設計に合わせた画像制約をサーバー側で担保できます。Laravel では文字列ルールと Rule::dimensions()流暢インターフェイスの両方が提供されています。(Readouble)

構文 / シグネチャ

文字列ルールとして

// 幅 800px 以上、高さ 400px 以上
'photo' => 'image|dimensions:min_width=800,min_height=400';

// ちょうど 1200x630(OGP など)
'og_image' => 'image|dimensions:width=1200,height=630';

// 16:9 の比率であればOK(サイズは問わない)
'thumbnail' => 'image|dimensions:ratio=16/9';

Rule オブジェクトとして(推奨)

use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\File;

Validator::validate($input, [
    'photo' => [
        'required',
        File::image()->dimensions(
            Rule::dimensions()
                ->minWidth(800)
                ->minHeight(400)
                ->maxWidth(2000)
                ->maxHeight(1200)
                ->ratio(16 / 9)
        ),
    ],
]);

(Readouble)

引数(パラメータ)

文字列ルールで指定できるパラメータ一覧:

引数必須既定値説明
widthintいいえなし幅が ちょうど この値(px)であること
heightintいいえなし高さが ちょうど この値(px)であること
min_widthintいいえなし幅がこの値以上
max_widthintいいえなし幅がこの値以下
min_heightintいいえなし高さがこの値以上
max_heightintいいえなし高さがこの値以下
ratiofloat|stringいいえなしアスペクト比(幅/高さ)。例: 3/2, 16/9

これらは組み合わせ可能で、「サイズ範囲 + 比率」を同時に指定できます。(Qiita)

戻り値

  • バリデーションルールとしては true(通過)/false(失敗)
  • 実際には Validator によって判定され、失敗時にはエラーコレクションにメッセージが追加されます。

例外 / 副作用

  • Request::validate()FormRequest を通して利用する場合、失敗すると Illuminate\Validation\ValidationException が投げられ、Webリクエストでは自動リダイレクト+エラーメッセージがセッションへ保存されます。(laravel.com)
  • ファイル自体の削除・変換などの副作用はありません(あくまで検証のみ)。

使用例

最小例

<?php

use Illuminate\Support\Facades\Validator;

$data = [
    'avatar' => request()->file('avatar'),
];

$validator = Validator::make($data, [
    // 正方形 400x400 ぴったりのアイコンだけ許可
    'avatar' => 'required|image|dimensions:width=400,height=400',
]);

if ($validator->fails()) {
    dd($validator->errors()->all());
}

echo "OK\n";

実務例:サムネイル用 16:9 画像のアップロード

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\File;

class ArticleController extends Controller
{
    public function store(Request $request)
    {
        $validated = $request->validate([
            // OGP 用サムネイル
            'thumbnail' => [
                'required',
                // 画像かどうか(jpg/png/webpなど)
                File::image()
                    ->dimensions(
                        Rule::dimensions()
                            ->minWidth(1200)
                            ->minHeight(675)
                            ->ratio(16 / 9)
                    ),
            ],
        ]);

        // 画像保存などの処理...
    }
}

通過 / 失敗ケース表

ルール: image|dimensions:min_width=800,min_height=400,ratio=16/9

幅x高さ結果説明
800×450通過幅800以上・高さ400以上・16:9
1600×900通過条件をすべて満たす
799×450失敗幅が 800 未満
1200×399失敗高さが 400 未満
1200×630失敗比率が 16:9 ではない(ほぼ 1.9:1)
800×800失敗正方形のため比率が 1:1
1200×675(非画像ファイル)失敗File::image() で画像でないと判定される

カスタムメッセージ・属性名

resources/lang/ja/validation.php の例(日本語メッセージ):

return [
    'dimensions' => ':attribute の画像サイズが指定された条件を満たしていません。',
];

個別フィールドだけ変えたい場合:

$request->validate(
    [
        'thumbnail' => 'required|image|dimensions:min_width=1200,min_height=675,ratio=16/9',
    ],
    [
        'thumbnail.dimensions' => 'サムネイル画像は、16:9 の比率で横1200px以上にしてください。',
    ]
);

条件付き(sometimes / FormRequest)例

任意アップロードだが、送られてきたら制約したい

use Illuminate\Support\Facades\Validator;

$validator = Validator::make($request->all(), [
    'banner' => 'sometimes|image|dimensions:min_width=1920,min_height=1080',
]);

if ($validator->fails()) {
    // エラー処理
}

FormRequest での例

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class UpdateProfileRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'avatar' => 'nullable|image|dimensions:min_width=400,min_height=400,ratio=1/1',
        ];
    }
}

よくある落とし穴・注意

  • image / File::image() を付け忘れる
    • dimensions は画像のメタ情報を読む前提なので、画像でないファイルでは想定外のエラーになり得ます。実務では File::image()->dimensions(...) または 'image|dimensions:...' のセットで使うことがほぼ必須です。(Readouble)
  • パラメータ名のスペルミス
    • min_widthminwidth と書いてもエラーにならず、検証されないだけ…という怖い状態になります。コピペベースで統一するのがおすすめです。(Qiita)
  • 比率 ratio の扱い
    • ratio=3/2 と指定すると「横3 : 縦2」として扱われます。
    • Rule オブジェクトの ratio(3 / 2) は float を渡すので、丸め誤差が気になる場合は文字列形式を使う選択肢もあります。(Qiita)
  • 複数パターンのサイズを許可したい
    • 「アイコンなら 512×512、バナーなら 1200×630」など、複数候補を OR 条件で許可したい場合は、カスタムルールを作るか、別フィールド/別エンドポイントに分ける必要があります(標準 dimensions ルールは AND 条件)。(Stack Overflow)

代替・関連APIとの比較

  • image / File::image()
    • ファイルが画像かどうかだけを判定したいならこれだけで十分。サイズや比率を見たいなら dimensions を組み合わせる。(Readouble)
  • size / min / max(file)
    • ファイル容量(KB) を制限するルール。ピクセル数ではないので、「軽さ」が目的のときに利用。
  • mimes / mimetypes
    • 拡張子や MIME タイプを制限するためのルール。dimensions とは別軸の制約。(Readouble)

選定基準の目安

  • 「画像であること」 → image / File::image()
  • 「容量(KB)を絞りたい」 → size / min / max(file)
  • 「ピクセル幅・高さ・比率を制御したい」 → dimensions
  • 「拡張子・形式を限定したい」 → mimes / mimetypes

テスト例(Pest)

<?php

use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Validator;

it('validates thumbnail dimensions', function () {
    // 疑似的な 1600x900 の画像ファイルを用意(実プロジェクトではファクトリや実ファイルを利用)
    $file = UploadedFile::fake()->image('thumb.jpg', 1600, 900);

    $validator = Validator::make(['thumbnail' => $file], [
        'thumbnail' => 'required|image|dimensions:min_width=1200,min_height=675,ratio=16/9',
    ]);

    expect($validator->passes())->toBeTrue();
});

トラブルシュート(エラー別)

症状/エラー原因対処
「The thumbnail has invalid image dimensions.」など英語ロケールが en、もしくは dimensions メッセージ未定義config/app.phplocaleja にし、日本語ファイルを追加
画像をアップしているのに常に dimensions で失敗するパラメータの指定ミス、想定と違う比率指定パラメータのスペル・数値・比率計算を確認する
意図しないファイルで dimensions が走り例外が出るimage / File::image() を付けておらず非画像が通過画像専用フィールドには必ず画像ルールを組み合わせる
一部の端末からのアップロードだけ失敗する実画像サイズが端末側で自動補正されており条件を満たさない実際に送信される画像のピクセルサイズを開発者ツール等で確認

参考リンク

レン (Wren)

こんにちは。レンです。

Laravelのコードの森に住んでいる、小さな案内役です。
ルーティングの枝やクラスの影を歩きながら、コードの流れや仕組みを眺めています。

このサイトでは、Laravelの基本から実装のコツまで、開発で役立つポイントを静かに整理しています。
難しいことを増やすのではなく、コードの見通しが少し良くなるヒントを届けるのが役目です。

「この処理はどこに書くのがいいのか」
「Laravelではどう考えると整理できるのか」

そんな疑問に、小さなメモを残すような気持ちで記事を書いています。

コードを書いている途中で迷ったとき、
このサイトが少し立ち止まって整理できる場所になればうれしいです。

レン (Wren)をフォローする