본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성하였습니다.
Ch 14. 심화 : 이미지 편집 라이브러리 활용으로 스킬업
1. Pillow 라이브러리의 개요
Pillow는 파이썬 환경에서 이미지 데이터를 효율적으로 다루기 위해 설계된 견고하고 사용자 친화적인 라이브러리입니다. JPEG, PNG, GIF, BMP 등 주요 이미지 파일 형식을 광범위하게 지원하며, 이미지 파일을 읽고, 쓰고, 다양한 방식으로 조작하는 데 필요한 포괄적인 기능을 제공합니다.
Pillow의 주요 특징:
- 다양한 파일 형식 지원: 현존하는 대부분의 이미지 형식을 원활하게 처리할 수 있는 호환성을 자랑합니다.
- 직관적인 API: 간결하고 명확한 API 설계를 통해 이미지 처리 작업을 용이하게 수행할 수 있습니다.
- 강력한 기능성: 이미지 로딩, 저장, 크기 조정, 회전, 자르기, 색상 변환, 다양한 필터 적용, 텍스트 및 도형 추가 등 다채로운 이미지 조작 기능을 내장하고 있습니다.
- 활발한 개발 및 지원: 지속적인 업데이트와 방대한 문서, 활성화된 커뮤니티를 통해 안정적인 개발 환경을 보장합니다.
Pillow 설치 절차
Pillow는 파이썬 표준 라이브러리에 포함되어 있지 않으므로, pip를 이용하여 개별적으로 설치해야 합니다.
pip install Pillow
2. Pillow 시작: 이미지 로딩 및 저장
이미지 처리의 기본은 파일을 열어 데이터를 로딩하고, 처리된 이미지를 새로운 파일로 저장하는 것입니다. Pillow에서는 Image 모듈이 이 핵심적인 기능을 담당합니다.
from PIL import Image
# 1. 이미지 로딩 (열기)
try:
img = Image.open("example.jpg") # 현재 스크립트와 동일 경로의 'example.jpg' 파일을 로드합니다.
print(f"이미지 형식: {img.format}")
print(f"이미지 모드: {img.mode}") # RGB, L(흑백) 등 색상 모드를 나타냅니다.
print(f"이미지 크기: {img.size} (가로 x 세로)")
except FileNotFoundError:
print("example.jpg 파일을 찾을 수 없습니다. 테스트를 위해 더미 파일을 생성합니다.")
# 파일 부재 시 예시를 위한 더미 이미지 생성
img = Image.new('RGB', (600, 400), color = 'red')
img.save("example.jpg")
print("example.jpg 더미 파일이 생성되었습니다. 스크립트를 다시 실행하여 주십시오.")
exit()
# 2. 이미지 정보 확인 (코드 상단에서 이미 출력됨)
# 3. 이미지 저장 (다양한 형식으로 저장 가능)
# 저장 시 파일 형식은 지정된 확장자에 따라 자동 결정됩니다.
img.save("example_copy.png") # PNG 형식으로 저장
img.save("example_copy.bmp") # BMP 형식으로 저장
print("\n이미지 로딩 및 저장이 성공적으로 완료되었습니다.")
print("example_copy.png 및 example_copy.bmp 파일이 생성되었습니다.")
코드 분석:
- from PIL import Image: Pillow 라이브러리의 핵심 Image 모듈을 임포트합니다.
- Image.open("example.jpg"): 지정된 경로의 이미지 파일을 엽니다. 파일이 존재하지 않을 경우 FileNotFoundError가 발생하므로, 예외 처리를 통해 더미 이미지를 생성하도록 구성하였습니다.
- img.format, img.mode, img.size: 로드된 이미지의 파일 형식, 색상 모드, 해상도(픽셀 단위의 가로, 세로 크기)를 확인할 수 있습니다.
- img.save("example_copy.png"): 로드된 이미지를 새로운 이름과 지정된 형식으로 저장합니다.
3. 이미지 크기 조정 (Resizing)
웹 콘텐츠 게시나 썸네일 생성 등 다양한 시나리오에서 이미지 크기 조정은 필수적인 작업입니다. Pillow는 resize() 메서드를 통해 이를 지원합니다.
from PIL import Image
try:
img = Image.open("example.jpg")
except FileNotFoundError:
print("example.jpg 파일을 찾을 수 없습니다. '이미지 로딩 및 저장' 섹션의 코드를 먼저 실행하여 파일을 생성해 주십시오.")
exit()
# 1. 새로운 크기 정의 (가로, 세로)
new_width = 300
new_height = 200
# 2. 이미지 크기 조정 수행
resized_img = img.resize((new_width, new_height))
# 3. 조정된 이미지 저장
resized_img.save("example_resized.jpg")
print(f"원본 이미지 크기: {img.size}")
print(f"조정된 이미지 크기: {resized_img.size}")
print("이미지 크기 조정 및 저장이 완료되었습니다: example_resized.jpg")
# 이미지 비율을 유지하며 크기 조정 (일반적으로 권장되는 방식)
# 이미지의 가로세로 비율을 유지한 채 긴 변을 기준으로 크기를 조절합니다.
original_width, original_height = img.size
max_size = 128 # 썸네일의 최대 변 길이 설정
if original_width > original_height:
new_width_ratio = max_size
new_height_ratio = int(original_height * (max_size / original_width))
else:
new_height_ratio = max_size
new_width_ratio = int(original_width * (max_size / original_height))
thumbnail_img = img.resize((new_width_ratio, new_height_ratio))
thumbnail_img.save("example_thumbnail.jpg")
print(f"썸네일 이미지 크기 (비율 유지): {thumbnail_img.size}")
print("썸네일 이미지 조정 및 저장이 완료되었습니다: example_thumbnail.jpg")
코드 설명:
- img.resize((new_width, new_height)): 지정된 너비와 높이로 이미지를 강제 조정합니다. 이 방식은 원본 이미지의 종횡비가 손상될 수 있음에 유의해야 합니다.
- 비율 유지 크기 조정: 원본 이미지의 종횡비를 계산하고, 특정 최대 크기를 초과하지 않으면서 비율을 유지하도록 새로운 가로세로 값을 산출하는 로직입니다. 썸네일 생성 시 매우 실용적입니다.
4. 이미지 회전 (Rotation) 및 반전 (Flipping)
이미지를 특정 각도로 회전시키거나, 좌우 또는 상하로 반전시키는 기능은 이미지 처리에서 빈번히 사용됩니다.
from PIL import Image
try:
img = Image.open("example.jpg")
except FileNotFoundError:
print("example.jpg 파일을 찾을 수 없습니다. '이미지 로딩 및 저장' 섹션의 코드를 먼저 실행하여 파일을 생성해 주십시오.")
exit()
# 1. 90도 회전
rotated_img = img.rotate(90, expand=True) # expand=True: 회전 후 이미지 전체를 포함하도록 캔버스 크기를 자동 조절
rotated_img.save("example_rotated_90.jpg")
print("이미지 90도 회전 및 저장 완료: example_rotated_90.jpg")
# 2. 180도 회전
rotated_180_img = img.rotate(180)
rotated_180_img.save("example_rotated_180.jpg")
print("이미지 180도 회전 및 저장 완료: example_rotated_180.jpg")
# 3. 좌우 반전 (FLIP_LEFT_RIGHT)
flipped_lr_img = img.transpose(Image.FLIP_LEFT_RIGHT)
flipped_lr_img.save("example_flipped_lr.jpg")
print("이미지 좌우 반전 및 저장 완료: example_flipped_lr.jpg")
# 4. 상하 반전 (FLIP_TOP_BOTTOM)
flipped_tb_img = img.transpose(Image.FLIP_TOP_BOTTOM)
flipped_tb_img.save("example_flipped_tb.jpg")
print("이미지 상하 반전 및 저장 완료: example_flipped_tb.jpg")
코드 설명:
- img.rotate(각도, expand=True): 이미지를 지정된 각도(반시계 방향)로 회전시킵니다. expand=True는 회전으로 인해 이미지 내용이 잘리지 않도록 캔버스 크기를 동적으로 확장합니다.
- img.transpose(Image.FLIP_LEFT_RIGHT): 이미지를 좌우 대칭으로 반전시킵니다.
- img.transpose(Image.FLIP_TOP_BOTTOM): 이미지를 상하 대칭으로 반전시킵니다.
5. 이미지 필터 적용 (Filters)
Pillow는 이미지에 다양한 시각적 효과를 부여할 수 있는 필터 기능을 제공합니다. 이는 ImageFilter 모듈을 통해 접근 가능합니다.
from PIL import Image, ImageFilter
try:
img = Image.open("example.jpg")
except FileNotFoundError:
print("example.jpg 파일을 찾을 수 없습니다. '이미지 로딩 및 저장' 섹션의 코드를 먼저 실행하여 파일을 생성해 주십시오.")
exit()
# 1. 블러(Blur) 필터 적용
blurred_img = img.filter(ImageFilter.BLUR)
blurred_img.save("example_blurred.jpg")
print("블러 필터 적용 및 저장 완료: example_blurred.jpg")
# 2. 샤프니스(Sharpen) 필터 적용
sharpened_img = img.filter(ImageFilter.SHARPEN)
sharpened_img.save("example_sharpened.jpg")
print("샤프니스 필터 적용 및 저장 완료: example_sharpened.jpg")
# 3. 엠보스(Emboss) 필터 적용
embossed_img = img.filter(ImageFilter.EMBOSS)
embossed_img.save("example_embossed.jpg")
print("엠보스 필터 적용 및 저장 완료: example_embossed.jpg")
# 4. 가장자리 찾기(FIND_EDGES) 필터 적용
edges_img = img.filter(ImageFilter.FIND_EDGES)
edges_img.save("example_edges.jpg")
print("가장자리 찾기 필터 적용 및 저장 완료: example_edges.jpg")
코드 설명:
- from PIL import Image, ImageFilter: ImageFilter 모듈을 추가로 임포트합니다.
- img.filter(ImageFilter.필터명): filter() 메서드에 ImageFilter 모듈이 제공하는 다양한 필터 상수(예: BLUR, SHARPEN, EMBOSS, FIND_EDGES 등)를 인자로 전달하여 적용합니다.
6. 이미지에 텍스트 삽입 (Drawing Text)
이미지에 워터마크를 추가하거나 특정 정보를 시각적으로 표현할 때 텍스트 삽입 기능은 필수적입니다. 이 기능은 ImageDraw 및 ImageFont 모듈을 통해 구현됩니다.
from PIL import Image, ImageDraw, ImageFont
try:
img = Image.open("example.jpg")
except FileNotFoundError:
print("example.jpg 파일을 찾을 수 없습니다. '이미지 로딩 및 저장' 섹션의 코드를 먼저 실행하여 파일을 생성해 주십시오.")
exit()
# 이미지에 그리기 작업을 수행할 Draw 객체 생성
draw = ImageDraw.Draw(img)
# 1. 폰트 로드 (시스템 폰트 또는 ttf 파일 경로 지정)
try:
# macOS/Linux 시스템 폰트 예시:
font = ImageFont.truetype("Arial.ttf", 40) # 폰트 파일명과 크기 지정
except IOError:
# 폰트를 찾을 수 없을 경우를 대비하여 기본 폰트 사용
print("Arial.ttf 폰트를 찾을 수 없습니다. 기본 폰트를 사용합니다.")
font = ImageFont.load_default() # Pillow가 제공하는 기본 비트맵 폰트 로드
# 2. 이미지 위에 텍스트 그리기
# draw.text((x, y), 텍스트 내용, fill=색상, font=폰트 객체)
draw.text((50, 50), "Hello, Pillow!", fill=(255, 255, 0), font=font) # 노란색 텍스트 삽입
# 3. 이미지 저장
img.save("example_with_text.jpg")
print("이미지에 텍스트 삽입 및 저장 완료: example_with_text.jpg")
코드 설명:
- from PIL import Image, ImageDraw, ImageFont: ImageDraw와 ImageFont 모듈을 임포트합니다.
- draw = ImageDraw.Draw(img): 이미지 위에 그림을 그리거나 텍스트를 추가할 수 있는 ImageDraw 객체를 생성합니다.
- ImageFont.truetype("Arial.ttf", 40): 사용할 폰트 파일(.ttf)의 경로와 폰트 크기를 지정하여 폰트를 로드합니다. 시스템에 해당 폰트가 없을 경우 IOError가 발생하므로, 예외 처리를 통해 기본 폰트를 사용하도록 구성하였습니다.
- 팁: Windows 운영체제에서는 C:\Windows\Fonts 경로에서, macOS에서는 /Library/Fonts 또는 ~/Library/Fonts 경로에서 폰트 파일을 찾을 수 있습니다.
- draw.text((x, y), "텍스트", fill=(R,G,B), font=폰트): text() 메서드를 활용하여 이미지에 텍스트를 그립니다. (x, y)는 텍스트가 시작될 좌상단 좌표, fill은 텍스트의 색상(RGB 튜플), font는 로드한 폰트 객체를 나타냅니다.
오늘의 실습
https://fastcampus.info/4n8ztzq
(~6/20) 50일의 기적 AI 환급반💫 | 패스트캠퍼스
초간단 미션! 하루 20분 공부하고 수강료 전액 환급에 AI 스킬 장착까지!
fastcampus.co.kr
'개발공부 > python' 카테고리의 다른 글
패스트캠퍼스 환급챌린지 15일차 : 한 번에 끝내는 컴퓨터 공학 & 인공지능 복수전공 초격차 패키지 강의 후기 (1) | 2025.07.15 |
---|---|
패스트캠퍼스 환급챌린지 13일차 : 한 번에 끝내는 컴퓨터 공학 & 인공지능 복수전공 초격차 패키지 강의 후기 (0) | 2025.07.13 |
패스트캠퍼스 환급챌린지 12일차 : 한 번에 끝내는 컴퓨터 공학 & 인공지능 복수전공 초격차 패키지 강의 후기 (0) | 2025.07.12 |
패스트캠퍼스 환급챌린지 11일차 : 한 번에 끝내는 컴퓨터 공학 & 인공지능 복수전공 초격차 패키지 강의 후기 (0) | 2025.07.11 |
패스트캠퍼스 환급챌린지 10일차 : 한 번에 끝내는 컴퓨터 공학 & 인공지능 복수전공 초격차 패키지 강의 후기 (0) | 2025.07.10 |