이미지 조작
업데이트됨번역일: 2026년 8월 2일
이 페이지는 원문이 업데이트되어 번역이 갱신되었습니다.
- 원문 수정
- 2026년 8월 2일
- 번역 갱신
- 2026년 8월 2일
이미지 조작
소개
Laravel은 이미지 크기 조정, 크롭, 인코딩, 저장을 간결하게 처리할 수 있는 유창한(fluent) 이미지 조작 API를 제공합니다. 이 기능은 Intervention Image 패키지를 기반으로 하며, GD 및 Imagick PHP 확장을 모두 지원합니다.
이미지 API는 업로드된 파일, Laravel 파일시스템 디스크에 저장된 파일, 로컬 파일, 원격 URL, 또는 원시 이미지 바이트 등 다양한 소스를 지원합니다.
use Illuminate\Support\Facades\Image;
$path = Image::fromStorage('avatars/photo.jpg', 'public')
->cover(400, 400)
->toWebp()
->quality(80)
->storePublicly('avatars', 'public');WARNING
이미지 처리는 CPU와 메모리를 상당히 소모하는 작업입니다. 용량이 큰 이미지를 처리할 때는 업로드 요청을 처리하는 HTTP 요청 중에 직접 처리하기보다, 큐 Job으로 분리하는 것을 권장합니다.
설치
이미지 조작 기능을 사용하기 전에, Composer를 통해 Intervention Image 패키지를 설치합니다.
composer require intervention/image:^4.0또한, 사용하려는 드라이버에 따라 PHP에 GD 또는 Imagick 확장이 설치되어 있는지 확인하세요.
설정
이미지 설정 파일은 config/images.php에 위치합니다. 해당 파일이 없다면 아래 Artisan 명령으로 게시할 수 있습니다.
php artisan config:publish images설정 파일에서 애플리케이션이 사용할 기본 이미지 드라이버를 지정할 수 있습니다. IMAGE_DRIVER 환경 변수로도 설정할 수 있으며, 지원되는 드라이버는 gd와 imagick입니다.
IMAGE_DRIVER=imagick이미지 읽기
Image 파사드는 다양한 소스에서 이미지를 불러오는 메서드를 제공합니다. 이미지 내용은 지연(lazy) 방식으로 로드되므로, 실제로 이미지를 처리하거나 바이트를 요청하기 전까지는 소스가 읽히지 않습니다.
업로드된 파일
요청에서 업로드된 이미지를 가져오려면 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 메서드를 사용합니다. 첫 번째 인수는 파일 경로, 두 번째 인수는 디스크 이름입니다.
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');이미지 조작하기
이미지 인스턴스는 불변(immutable)입니다. 각 조작 메서드는 변환이 파이프라인에 추가된 새로운 이미지 인스턴스를 반환하므로, 메서드를 체인 방식으로 연결할 수 있습니다.
$image = $request->image('avatar')
->orient()
->cover(400, 400)
->sharpen(10);변환은 파이프라인에 추가된 순서대로 처리되며, 이미지 인코딩은 마지막 단계에서 한 번만 수행됩니다.
이미지 크기 조정
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 메서드는 이미지 전체가 보이도록 지정한 크기 안에 맞추며, 남은 공간은 배경색으로 채웁니다. 배경색으로 'dominant'를 지정하면 이미지의 주요 색상을 자동으로 사용합니다.
$image = $image->contain(400, 400);
$image = $image->contain(400, 400, '#ffffff');
$image = $image->contain(400, 400, 'dominant');crop 메서드로 이미지를 원하는 크기로 자를 수 있습니다. 첫 두 인수는 너비와 높이이며, 세 번째와 네 번째 인수로 크롭 시작 좌표(x, y)를 선택적으로 지정할 수 있습니다.
$image = $image->crop(300, 200);
$image = $image->crop(300, 200, x: 50, y: 25);기타 변환
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,sharpen:0에서100사이의 값을 받습니다.
조건부 변환
이미지 인스턴스는 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());이미지 인코딩
기본적으로 처리된 이미지는 원본 포맷으로 인코딩됩니다. 그러나 저장하거나 가져오기 전에 다른 포맷으로 변환할 수 있습니다.
$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 메서드는 포맷 변환과 품질 설정을 한 번에 처리하는 편의 메서드입니다. 기본값은 WebP 포맷, 품질 70입니다.
$image = $image->optimize();
$image = $image->optimize(format: 'jpg', quality: 85);처리된 이미지 내용을 바이트 문자열, Base64 인코딩 문자열, 또는 데이터 URI 형태로 가져올 수도 있습니다.
$bytes = $image->toBytes();
$base64 = $image->toBase64();
$dataUri = $image->toDataUri();이미지 인스턴스를 문자열로 캐스팅하면 처리된 바이트를 가져올 수 있습니다.
$bytes = (string) $image;이미지 저장
store 메서드는 처리된 이미지를 애플리케이션의 파일시스템 디스크에 저장합니다. 업로드된 파일과 마찬가지로 고유한 파일명이 자동 생성되며, 저장된 경로가 반환됩니다. 두 번째 인수로 디스크를 지정할 수 있습니다.
$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를 반환합니다.
이미지 정보 조회
다음 메서드를 통해 이미지의 MIME 타입, 확장자, 크기, 너비, 높이, 주요 색상을 조회할 수 있습니다.
$mimeType = $image->mimeType();
$extension = $image->extension();
[$width, $height] = $image->dimensions();
$width = $image->width();
$height = $image->height();
$dominantColor = $image->dominantColor();이 메서드들은 처리가 완료된 이미지를 기준으로 동작합니다. 예를 들어 cover(400, 400) 이후에 width()를 호출하면 400이 반환됩니다.
이미지 드라이버
커스텀 이미지 드라이버
Laravel의 이미지 매니저는 Illuminate\Support\Manager 클래스를 상속하므로, Image 파사드의 extend 메서드를 통해 커스텀 드라이버를 등록할 수 있습니다.
커스텀 이미지 드라이버는 Illuminate\Contracts\Image\Driver 인터페이스를 구현해야 합니다. process 메서드는 원본 이미지 내용과 적용해야 할 Illuminate\Image\ImagePipeline을 인수로 받아 처리된 이미지 바이트를 반환해야 합니다.
<?php
namespace App\Images;
use Illuminate\Contracts\Image\Driver;
use Illuminate\Image\ImagePipeline;
class VipsDriver implements Driver
{
/**
* 지정된 파이프라인으로 이미지를 처리합니다.
*/
public function process(string $contents, ImagePipeline $pipeline): string
{
// 파이프라인의 변환과 출력 옵션을 적용합니다...
return $contents;
}
/**
* 변환 핸들러를 등록합니다.
*/
public function transformUsing(string $transformation, callable $callback): static
{
// 파이프라인 처리 시 적용될 수 있도록 핸들러를 저장합니다...
return $this;
}
}NOTE
커스텀 이미지 드라이버 구현 방법을 더 잘 이해하려면, 프레임워크에 내장된 Illuminate\Image\Drivers\InterventionDriver 클래스를 참고하세요.
커스텀 드라이버를 구현한 후에는 Image 파사드의 extend 메서드로 등록합니다. 일반적으로 서비스 프로바이더의 boot 메서드에서 수행합니다.
use App\Images\VipsDriver;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\Facades\Image;
/**
* 애플리케이션 서비스를 부트스트랩합니다.
*/
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커스텀 변환
애플리케이션이나 패키지에서 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');