이미지 조작
업데이트됨번역일: 2026년 9월 29일
이 페이지는 원문이 업데이트되어 번역이 갱신되었습니다.
- 원문 수정
- 2026년 9월 29일
- 번역 갱신
- 2026년 9월 29일
이미지 조작
소개
라라벨은 이미지의 크기 조절, 자르기(crop), 인코딩, 저장을 위한 플루언트(fluent) API를 제공합니다. 라라벨의 다른 기능들과 마찬가지로 표현력이 풍부한 문법을 그대로 이어받아 사용할 수 있죠. 이 이미지 기능은 Intervention Image 라이브러리를 기반으로 동작하며, GD와 Imagick PHP 확장 모듈을 모두 지원합니다.
이 이미지 API는 업로드된 파일, 라라벨 파일시스템 디스크에 저장된 파일, 로컬 파일, 원격 URL, 원시(raw) 이미지 바이트 등 다양한 소스를 다룰 때 유용합니다:
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에 위치합니다. 만약 애플리케이션에 images 설정 파일이 없다면, config:publish Artisan 명령어로 퍼블리시할 수 있습니다:
php artisan config:publish images이미지 설정 파일에서는 애플리케이션이 기본으로 사용할 이미지 드라이버를 지정할 수 있습니다. IMAGE_DRIVER 환경 변수를 통해서도 기본 드라이버를 지정할 수 있습니다. 지원되는 드라이버는 gd와 imagick입니다:
IMAGE_DRIVER=imagick이미지 읽기
Image 파사드는 다양한 소스에서 이미지를 읽어올 수 있는 여러 메서드를 제공합니다. 이미지 내용은 지연 로딩(lazy loading) 방식으로 처리되므로, 실제로 이미지를 가공하거나 바이트 데이터를 요청하기 전까지는 원본 소스를 읽지 않습니다.
업로드된 파일
들어오는 요청(request)에서 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');
// ...
});또는 fromUpload 메서드를 사용해 Illuminate\Http\UploadedFile 인스턴스로부터 이미지 인스턴스를 생성할 수도 있습니다:
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 메서드는 이미지 전체가 보이도록 유지하면서 지정한 크기 안에 맞춥니다. 필요한 경우 남는 공간은 배경색으로 채울 수 있습니다:
$image = $image->contain(400, 400);
$image = $image->contain(400, 400, '#ffffff');
$image = $image->contain(400, 400, 'dominant');배경색으로 dominant를 지정하면 이미지의 주요 색상(대표색)으로 빈 공간을 채웁니다.
crop 메서드로 이미지를 자를 수 있습니다. 처음 두 개의 인자는 원하는 가로/세로 크기이며, 세 번째와 네 번째 인자(선택 사항)로 자를 위치의 x, y 좌표를 지정할 수 있습니다:
$image = $image->crop(300, 200);
$image = $image->crop(300, 200, x: 50, y: 25);기타 변환
라라벨은 이 외에도 다양한 이미지 변환 메서드를 제공합니다:
$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 사이의 값을 받습니다.
조건에 따른 변환
이미지 인스턴스는 라라벨의 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 메서드는 이미지를 지정한 포맷으로 변환하면서 품질까지 함께 설정해주는 편리한 단축 메서드입니다. 기본적으로는 품질 70의 WebP 이미지로 최적화됩니다:
$image = $image->optimize();
$image = $image->optimize(format: 'jpg', quality: 85);처리된 이미지의 결과물은 바이트 문자열, Base64 인코딩 문자열, 데이터 URI 형태로 가져올 수 있습니다:
$bytes = $image->toBytes();
$base64 = $image->toBase64();
$dataUri = $image->toDataUri();이미지 인스턴스를 문자열로 캐스팅하면 데이터 URI를 얻을 수도 있습니다:
$dataUri = (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 가시성(visibility)으로 이미지를 저장합니다:
$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이 반환됩니다.
이미지 드라이버
커스텀 이미지 드라이버
라라벨의 이미지 매니저는 라라벨의 기본 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
{
/**
* 지정된 파이프라인으로 이미지 내용을 처리합니다.
*/
public function process(string $contents, ImagePipeline $pipeline): string
{
// 파이프라인의 변환 및 출력 옵션을 적용합니다...
return $contents;
}
/**
* 주어진 이미지 내용의 크기(dimensions)를 가져옵니다.
*/
public function dimensions(string $contents): array
{
// 이미지의 가로/세로 크기를 읽어옵니다...
return [0, 0];
}
/**
* 이미지의 대표(평균) 색상을 16진수 문자열로 가져옵니다.
*/
public function dominantColor(string $contents): string
{
// 이미지의 평균 색상을 계산합니다...
return '#000000';
}
/**
* 변환 핸들러를 등록합니다.
*/
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 계약(contract)을 구현하는 클래스를 만들어 커스텀 변환을 정의할 수 있습니다. 정의한 커스텀 변환은 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');