ImageMagick 사용법: 터미널에서 이미지 편집하기
개발을 하다 보면 이미지를 가공해야 하는 일이 참 많죠. 포맷을 변환하거나, 크기를 줄이거나, 여러 이미지를 합성하거나, 워터마크를 넣거나… 이런 작업을 매번 포토샵 같은 GUI 프로그램을 열어서 하기엔 너무 번거로운데요.
ImageMagick은 바로 그런 상황에서 빛나는 도구입니다. 1990년에 첫 릴리스된 이후 30년이 넘도록 꾸준히 개발되어 왔고, 200개 이상의 이미지 포맷을 지원하는 사실상의 표준 CLI 이미지 도구라고 할 수 있어요. PNG, JPEG, WebP, TIFF, GIF, SVG, PDF까지 거의 모든 포맷을 다룰 수 있고, 리사이징부터 색상 조정, 텍스트 삽입, 이미지 합성까지 정말 방대한 기능을 제공합니다.
참고로 ImageMagick 7 버전부터는 기존의 convert, mogrify 같은 개별 명령어 대신 magick이라는 통합 명령어를 사용합니다.
이 글에서는 v7 기준으로 magick 명령어를 사용해서 설명하겠습니다.
설치
운영체제별로 패키지 매니저를 사용해서 설치할 수 있습니다.
macOS에서는 Homebrew로 설치하면 됩니다.
brew install imagemagick
Ubuntu/Debian에서는 apt로 설치합니다.
sudo apt install imagemagick
설치가 완료되면 버전을 확인해볼까요?
magick --version
Version: ImageMagick 7.1.1-41 Q16-HDRI x86_64
Copyright: (C) 1999 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI Modules OpenMP(5.0)
Delegates (built-in): bzlib fontconfig freetype heic jng jp2 jpeg lcms lqr ltdl lzma openexr png tiff webp xml zlib
Delegates 항목에 표시된 것들이 현재 설치에서 지원하는 이미지 포맷 라이브러리입니다.
webp가 보이면 WebP 변환이 가능하고, heic가 보이면 iPhone 사진의 HEIC 포맷도 다룰 수 있다는 뜻이에요.
이미지 정보 확인
이미지를 처리하기 전에 먼저 원본 파일의 정보를 파악하는 게 좋겠죠.
magick identify 명령어를 사용하면 이미지의 기본 정보를 빠르게 확인할 수 있습니다.
magick identify photo.jpg
photo.jpg JPEG 4032x3024 4032x3024+0+0 8-bit sRGB 3.2MB 0.010u 0:00.010
이 출력을 보면 4032x3024 크기의 8비트 sRGB JPEG 이미지이고 파일 크기가 3.2MB라는 것을 한눈에 알 수 있습니다.
더 자세한 정보가 필요하면 -verbose 옵션을 추가합니다.
magick identify -verbose photo.jpg
Image:
Filename: photo.jpg
Format: JPEG (Joint Photographic Experts Group JFIF format)
Mime type: image/jpeg
Class: DirectClass
Geometry: 4032x3024+0+0
Resolution: 72x72
Print size: 56x42
Units: PixelsPerInch
Colorspace: sRGB
Type: TrueColor
Depth: 8-bit
Channel depth:
red: 8-bit
green: 8-bit
blue: 8-bit
...
색공간, 해상도, 비트 깊이, 채널 정보 등 이미지에 대한 거의 모든 메타데이터를 확인할 수 있어요.
여러 파일의 정보를 한꺼번에 확인하는 것도 가능합니다.
magick identify *.jpg
포맷 변환
ImageMagick으로 가장 많이 하는 작업이 포맷 변환입니다. 사용법이 아주 직관적인데, 입력 파일과 출력 파일의 확장자만 다르게 지정하면 자동으로 변환해줍니다.
# PNG를 JPEG으로 변환
magick input.png output.jpg
# JPEG을 WebP로 변환
magick input.jpg output.webp
# BMP를 PNG으로 변환
magick input.bmp output.png
JPEG이나 WebP처럼 손실 압축 포맷으로 변환할 때는 -quality 옵션으로 품질을 지정할 수 있습니다.
값은 0에서 100 사이인데, JPEG의 경우 85 정도면 파일 크기와 화질 사이에서 좋은 균형을 잡을 수 있어요.
# 품질 85의 JPEG으로 변환
magick input.png -quality 85 output.jpg
# 품질 80의 WebP로 변환
magick input.png -quality 80 output.webp
투명 배경이 있는 PNG를 JPEG으로 변환할 때는 주의가 필요합니다.
JPEG은 투명도를 지원하지 않기 때문에 투명 영역이 검은색으로 채워지는데요.
-background 옵션으로 배경색을 지정하고 -flatten으로 레이어를 합치면 이 문제를 해결할 수 있습니다.
magick input.png -background white -flatten output.jpg
리사이징
-resize 옵션으로 이미지 크기를 변경할 수 있습니다.
가로와 세로를 모두 지정하면 비율을 유지하면서 해당 크기 안에 맞춰줍니다.
# 800x600 안에 맞추기 (비율 유지)
magick input.jpg -resize 800x600 output.jpg
원본 이미지가 4:3 비율이 아니라면 800x600에 정확히 맞추지 않고, 가로나 세로 중 하나가 먼저 제한에 도달하면 거기서 멈춥니다. 가로만 지정하거나 세로만 지정하는 것도 가능해요.
# 가로 800px로 축소 (세로는 비율에 맞춰 자동)
magick input.jpg -resize 800 output.jpg
# 세로 600px로 축소 (가로는 비율에 맞춰 자동)
magick input.jpg -resize x600 output.jpg
크기 뒤에 특수 문자를 붙여서 리사이징 동작을 세밀하게 제어할 수 있는데요. ImageMagick에서는 이것을 geometry 연산자라고 부릅니다.
>— 원본이 지정 크기보다 큰 경우에만 축소 (확대하지 않음)<— 원본이 지정 크기보다 작은 경우에만 확대 (축소하지 않음)!— 비율을 무시하고 정확히 지정 크기로 맞춤^— 지정 크기를 최소 영역으로 채움 (크롭 전처리에 유용)%— 크기를 퍼센트로 지정
# 원본보다 클 때만 축소 (웹용 이미지 최적화에 유용)
magick input.jpg -resize '1920x1080>' output.jpg
# 50%로 축소
magick input.jpg -resize '50%' output.jpg
# 비율 무시하고 정확히 800x600으로
magick input.jpg -resize '800x600!' output.jpg
쉘에서 >나 ! 같은 특수 문자가 해석되지 않도록 따옴표로 감싸는 것이 좋습니다.
크롭과 자르기
이미지에서 특정 영역만 잘라내고 싶을 때는 -crop 옵션을 사용합니다.
WxH+X+Y 형식으로 잘라낼 크기와 시작 좌표를 지정하는데요.
# 왼쪽 위 (100, 50) 지점에서 500x400 영역을 잘라내기
magick input.jpg -crop 500x400+100+50 output.jpg
좌표를 직접 계산하는 게 번거로울 때는 -gravity 옵션이 유용합니다.
-gravity는 기준점을 지정하는 옵션으로, 이미지의 중앙이나 특정 모서리를 기준으로 크롭할 수 있게 해줍니다.
# 이미지 중앙에서 500x500 영역을 잘라내기
magick input.jpg -gravity center -crop 500x500+0+0 output.jpg
# 오른쪽 아래 모서리에서 300x200 영역을 잘라내기
magick input.jpg -gravity southeast -crop 300x200+0+0 output.jpg
-gravity에 사용할 수 있는 위치는 center, north, south, east, west, northeast, northwest, southeast, southwest 이렇게 9가지입니다.
리사이징과 크롭을 조합하면 원하는 크기에 정확히 맞는 썸네일을 만들 수 있어요.
먼저 ^ 연산자로 영역을 채운 뒤 중앙에서 크롭하는 방식입니다.
# 정확히 400x400 정사각형 썸네일 만들기
magick input.jpg -resize '400x400^' -gravity center -crop 400x400+0+0 +repage output.jpg
여기서 +repage는 크롭 후 이미지의 캔버스 정보를 초기화하는 옵션입니다.
이걸 빼먹으면 일부 포맷에서 잘린 이미지의 위치 정보가 남아 있어서 의도치 않은 결과가 나올 수 있어요.
회전과 뒤집기
-rotate 옵션으로 이미지를 회전시킬 수 있습니다.
양수 값은 시계 방향, 음수 값은 반시계 방향으로 회전합니다.
# 시계 방향 90도 회전
magick input.jpg -rotate 90 output.jpg
# 반시계 방향 90도 회전
magick input.jpg -rotate -90 output.jpg
# 180도 회전 (상하좌우 반전)
magick input.jpg -rotate 180 output.jpg
90도 단위가 아닌 임의의 각도로 회전하면 빈 영역이 생기는데, 기본적으로 배경색으로 채워집니다.
# 45도 회전, 빈 영역은 흰색으로 채우기
magick input.jpg -background white -rotate 45 output.jpg
뒤집기도 간단합니다.
-flip은 상하 반전(수직 뒤집기), -flop은 좌우 반전(수평 뒤집기)입니다.
# 상하 반전
magick input.jpg -flip output.jpg
# 좌우 반전
magick input.jpg -flop output.jpg
스마트폰으로 찍은 사진의 EXIF 회전 정보를 실제 픽셀에 반영하고 싶다면 -auto-orient를 사용합니다.
웹에 이미지를 업로드하기 전에 이 옵션을 적용해두면 브라우저에서 사진이 눕혀 보이는 문제를 방지할 수 있어요.
magick input.jpg -auto-orient output.jpg
색상과 필터
색상 조정이나 필터 효과도 터미널에서 바로 적용할 수 있습니다.
-colorspace 옵션으로 색공간을 변환할 수 있는데, 가장 자주 쓰이는 것은 컬러 이미지를 흑백으로 바꾸는 것입니다.
# 흑백으로 변환
magick input.jpg -colorspace Gray output.jpg
-modulate 옵션을 쓰면 밝기, 채도, 색조를 한 번에 조정할 수 있습니다.
값은 밝기,채도,색조 순서로 100이 원본 그대로, 그보다 크면 증가, 작으면 감소입니다.
# 밝기 120%, 채도 150%, 색조 변경 없음
magick input.jpg -modulate 120,150,100 output.jpg
# 채도만 0으로 낮추기 (흑백 효과)
magick input.jpg -modulate 100,0,100 output.jpg
블러와 샤프닝 필터도 간단하게 적용됩니다.
-blur 옵션은 반지름x시그마 형식으로 가우시안 블러를 적용하고, -sharpen은 같은 형식으로 샤프닝을 적용합니다.
# 가우시안 블러 적용
magick input.jpg -blur 0x3 output.jpg
# 샤프닝 적용
magick input.jpg -sharpen 0x1 output.jpg
블러에서 반지름은 보통 0으로 설정하면 시그마 값에 따라 자동으로 결정됩니다. 시그마 값이 클수록 더 강한 블러가 적용되는데, 3 정도면 부드러운 블러 효과를, 10 이상이면 강한 블러 효과를 얻을 수 있어요.
색상 밝기와 대비를 조정하는 옵션도 있어요.
# 밝기 +20, 대비 +10
magick input.jpg -brightness-contrast 20x10 output.jpg
# 히스토그램 평활화로 자동 대비 보정
magick input.jpg -normalize output.jpg
텍스트와 워터마크
이미지에 텍스트를 삽입하는 것도 자주 쓰이는 기능입니다.
-annotate 옵션을 사용하면 원하는 위치에 텍스트를 넣을 수 있어요.
magick input.jpg \
-gravity southeast \
-fill white \
-pointsize 36 \
-annotate +20+20 '© 2022 My Photo' \
output.jpg
이 명령은 이미지의 오른쪽 아래 모서리에서 가로 20px, 세로 20px 안쪽에 흰색 36pt 텍스트를 삽입합니다.
-fill은 텍스트 색상, -pointsize는 글자 크기, -gravity는 기준 위치를 지정합니다.
폰트를 지정하고 싶다면 -font 옵션을 추가합니다.
magick input.jpg \
-gravity south \
-font Arial \
-fill yellow \
-pointsize 48 \
-annotate +0+30 'Hello World' \
output.jpg
텍스트에 그림자나 외곽선을 넣어서 가독성을 높이고 싶다면 -stroke 옵션으로 외곽선 색상을 지정하고 -strokewidth로 두께를 설정합니다.
magick input.jpg \
-gravity center \
-font Arial-Bold \
-fill white \
-stroke black \
-strokewidth 2 \
-pointsize 72 \
-annotate +0+0 'SAMPLE' \
output.jpg
이미지를 워터마크로 합성하려면 composite 명령을 사용합니다.
반투명 PNG 로고를 원본 이미지 위에 겹치는 방식인데요.
# 오른쪽 아래에 워터마크 합성 (30% 불투명도)
magick composite -gravity southeast -geometry +10+10 \
-dissolve 30 watermark.png input.jpg output.jpg
-dissolve 30은 워터마크의 불투명도를 30%로 설정하는 옵션입니다.
값을 낮출수록 워터마크가 더 투명해져서 원본 이미지를 덜 가리게 됩니다.
이미지 합성
여러 이미지를 하나로 합치는 작업도 ImageMagick으로 할 수 있습니다.
montage 명령은 여러 이미지를 격자 형태의 콜라주로 만들어줍니다.
# 4개 이미지를 2x2 격자로 합치기
magick montage img1.jpg img2.jpg img3.jpg img4.jpg \
-geometry 400x300+5+5 -tile 2x2 collage.jpg
-geometry 400x300+5+5는 각 이미지를 400x300 크기로 맞추고 이미지 사이에 5px 간격을 두겠다는 뜻입니다.
-tile 2x2는 2행 2열 격자 배치를 의미하고요.
composite 명령은 두 이미지를 겹쳐서 합성하는 데 사용합니다.
앞서 워터마크에서 봤던 것처럼 한 이미지를 다른 이미지 위에 올리는 방식이에요.
# 배경 이미지 위에 로고를 왼쪽 위에 합성
magick composite -gravity northwest -geometry +20+20 \
logo.png background.jpg result.jpg
이미지를 가로나 세로로 이어붙이는 것도 가능합니다.
# 가로로 이어붙이기
magick input1.jpg input2.jpg +append horizontal.jpg
# 세로로 이어붙이기
magick input1.jpg input2.jpg -append vertical.jpg
+append는 가로 방향, -append는 세로 방향으로 이미지를 연결합니다.
스크린샷을 이어붙이거나 비교 이미지를 만들 때 유용하죠.
일괄 처리
여러 이미지를 한꺼번에 처리해야 할 때는 magick mogrify를 사용합니다.
magick 명령이 새 파일을 만드는 반면, mogrify는 원본 파일을 직접 수정하는 것이 가장 큰 차이점입니다.
# 현재 디렉토리의 모든 JPEG 파일을 800px 너비로 축소
magick mogrify -resize 800 *.jpg
# 품질 85로 모든 JPEG 재압축
magick mogrify -quality 85 *.jpg
원본을 보존하면서 일괄 변환하고 싶다면 -path 옵션으로 출력 디렉토리를 지정합니다.
# thumbnails 디렉토리에 300px 썸네일 일괄 생성
mkdir -p thumbnails
magick mogrify -resize 300 -path thumbnails *.jpg
포맷을 일괄 변환하는 것도 가능합니다.
-format 옵션으로 출력 포맷을 지정하면 파일 확장자가 자동으로 바뀝니다.
# 모든 PNG를 JPEG으로 일괄 변환
magick mogrify -format jpg -quality 85 *.png
# 모든 JPEG을 WebP로 일괄 변환
magick mogrify -format webp -quality 80 *.jpg
여러 옵션을 조합해서 한 번에 적용할 수도 있어요.
# 1920px 이하로 축소 + 품질 85 + EXIF 반영 + 메타데이터 제거
magick mogrify -auto-orient -resize '1920x1920>' -strip -quality 85 *.jpg
-strip은 EXIF, IPTC, ICC 프로파일 등 모든 메타데이터를 제거하는 옵션입니다.
웹용 이미지를 준비할 때 파일 크기를 줄이고 개인 정보(GPS 좌표 등)를 제거하는 용도로 유용합니다.
쉘 스크립트와 조합하면 더 복잡한 일괄 처리도 가능합니다.
# 하위 디렉토리 포함 모든 JPEG을 WebP로 변환
find . -name "*.jpg" -exec sh -c '
magick "$1" -quality 80 "${1%.jpg}.webp"
' _ {} \;
마치며
ImageMagick은 30년 넘게 개발되어 온 만큼 이미지 처리에 필요한 거의 모든 기능을 갖추고 있습니다. 포맷 변환, 리사이징, 크롭, 회전, 색상 조정, 텍스트 삽입, 이미지 합성, 일괄 처리까지 터미널에서 한 줄이면 처리할 수 있으니까요. 200개 이상의 포맷 지원과 방대한 옵션은 다른 도구에서 쉽게 찾아보기 어려운 ImageMagick만의 강점입니다.
다만 대량의 이미지를 처리해야 하는 상황에서는 성능을 고려할 필요가 있습니다. ImageMagick은 이미지를 통째로 메모리에 올려서 처리하는 방식이기 때문에, 큰 이미지나 많은 파일을 다룰 때 속도가 느리고 메모리를 많이 잡아먹을 수 있어요. 이런 경우에는 파이프라인 방식으로 처리해서 훨씬 빠르고 메모리 효율적인 libvips를 대안으로 검토해보시길 추천합니다.
더 자세한 내용은 ImageMagick 공식 문서를 참고하시면 좋겠습니다.
This work is licensed under
CC BY 4.0