In this article
Introduction
There may be times when you're building a form in your Laravel applications that allows users to upload images. It's something I've had to do in almost every project I've ever worked on.
When you're allowing users to upload images, you may want to enforce that the images are square in shape. This can be useful for things like profile pictures, where you want the image to be displayed in a square container without being stretched or squashed. Of course, you could crop and resize the image - either through a front-end library that lets the user crop the image or through an automated back-end process. Or, you may want to just use some CSS when the image is being displayed to display it inside a square container. But enforcing the image size is something that can give you peace of mind that you're working with an image in the correct dimensions.
In the past, I've written a custom validation rule that reads the dimensions of the file and then compares them. But, when I was recently writing the Ultimate Guide to Laravel Validation for Laravel News, I found a much easier way to do this!
In this Quickfire article, we're going to take a quick look at how to validate that an image is square in shape when it's uploaded in a Laravel application.
Validating Square Images
Laravel provides a handy ratio
method that's available on the Illuminate\Validation\Rules\Dimensions
class. We can get access to this method when building our validation rules by using the Rule::dimensions()
method:
1File::image()->dimensions(2 Rule::dimensions()->ratio(1.0)3);
The ratio
method accepts a single float argument, which is the dimension ratio (of the width to height) that we want to enforce. So in this case, we can use 1.0
to ensure that for every 1 pixel in width, there is 1 pixel in height. This will enforce that the image is square in shape.
Here's an example of how you might use this in a form request:
app/Http/Requests/UploadProfilePictureRequest.php
1declare(strict_types=1);23namespace App\Http\Requests;45use Illuminate\Foundation\Http\FormRequest;6use Illuminate\Validation\Rules\File;7use Illuminate\Validation\Rule;89final class UploadProfilePictureRequest extends FormRequest10{11 public function rules(): array12 {13 return [14 'profile_picture' => [File::image()->dimensions(15 Rule::dimensions()->ratio(1.0)16 )],17 ];18 }19}
If the validation for this file were to fail, the following error message would be returned:
1The profile picture field has invalid image dimensions.
As you can see, the error message is pretty generic, so you might want to customise it to let the user know that the image must be square in shape. To do this, you can override the message like you would with any other validation rule (as shown here in the Laravel docs).
Here's an example of how you could update the error message in the form request class:
app/Http/Requests/UploadProfilePictureRequest.php
1declare(strict_types=1);23namespace App\Http\Requests;45use Illuminate\Foundation\Http\FormRequest;6use Illuminate\Validation\Rules\File;7use Illuminate\Validation\Rule;89final class UploadProfilePictureRequest extends FormRequest10{11 public function rules(): array12 {13 return [14 'profile_picture' => [File::image()->dimensions(15 Rule::dimensions()->ratio(1.0)16 )],17 ];18 }1920 public function messages(): array21 {22 return [23 'profile_picture.dimensions' => 'The profile picture must be square in shape.',24 ];25 }26}
Now when the validation fails, the following error message will be returned:
1The profile picture must be square in shape.
As you can see this is a really easy way to validate that an image is square in shape when it's uploaded in a Laravel application.
Other Handy Image Ratios
As we've mentioned, the ratio
method accepts a single float argument. This means that you can enforce other ratios too by passing in different values like so:
1Rule::dimensions()->ratio(16 / 9) // 16:9 ratio
The above example would enforce a 16:9 aspect ratio on the image.
Here's a list of some common aspect ratios that you might want to enforce:
- 4:3 -
Rule::dimensions()->ratio(4 / 3)
- 16:9 -
Rule::dimensions()->ratio(16 / 9)
- 3:2 -
Rule::dimensions()->ratio(3 / 2)
- 9:16 -
Rule::dimensions()->ratio(9 / 16)
Further Reading
If you know me, you'll know that I love validating as much as possible! I've seen noticeable reductions in bugs in projects I've worked on after improving the validation rules being used.
If you're interested in finding out more about validation, you might want to check out the following:
๐ Review: Mastering Laravel Validation Rules
๐ Validate Data Types in Laravel Collections Using the ensure()
Method
๐ How to Validate Your Laravel App's Config
๐ Mass Assignment Vulnerabilities and Validation in Laravel