본문 바로가기

이미지 조작

업데이트됨

번역일: 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');

이 문서는 Laravel 공식 문서(MIT)를 한국 개발자를 위해 번역·재구성한 것입니다.

번역일: 2026년 9월 29일