Python Pillow crop(이미지 자르기) 방법 2가지

Python Pillow crop(이미지 자르기) 방법을 함께 살펴보도록 하겠습니다.

Python Pillow crop(이미지 자르기) 사용 방법

Pillow를 이용하여 이미지의 일부를 잘라내는 crop 기능에는 이미지 객체의 crop() 메서드를 사용하면 됩니다. 사용법을 함께 확인해 보도록 하겠습니다. 그리고 직접 crop 기능을 구현해 보기도 하겠습니다.

원본 이미지

불러와서 작업할 원본 이미지 파일 test.png는 그림 1과 같습니다. 원본 이미지의 크기는 120px x 90px입니다.

그림 1. Python Pillow crop을 위한 이미지 원본
그림 1. Python Pillow crop을 위한 이미지 원본

잘라낼 영역

그림 2에는 잘라낼 영역을 간략히 표시해 보았습니다. 영역은 (10, 10)부터 (80, 30)에 해당합니다.

그림 2. crop 할 영역
그림 2. crop 할 영역

crop() 메서드 사용법

그럼 이제 Python 코드를 이용해서 이미지 crop을 수행해 보도록 하겠습니다. 잘라내기 기능은 이미지 객체의 crop 메서드를 바로 사용하면 가능합니다. crop 메서드는 이미지 객체를 돌려주므로 해당 객체를 전달 받아서 이용해야 합니다.

crop 메서드는 box 값을 받도록 되어있는데 튜플 형태로 4개의 정수값을 전달하면 됩니다. Crop 영역의 시작점 x1, y1과 끝점 x2, y2를 연달아서 4개 값의 튜플로 전달하면 됩니다. 4개의 값은 각각 (left, upper, right, lower)에 해당합니다. 즉, 아래의 코드에서는 (10, 10)에서 (80, 30)까지의 영역을 crop하게 됩니다.

from PIL import Image

img = Image.open("test.png")
dat = img.load()

box = (10, 10, 80, 30)
img_cropped = img.crop(box)
img_cropped.save("test_cropped.png")
Python

잘라낸 결과

위의 코드를 사용해서 잘라낸 결과 이미지는 그림 3과 같습니다.

그림 3. crop 한 결과 이미지
그림 3. crop 한 결과 이미지

for loop 사용하여 픽셀 단위로 crop

이번에는 재미 삼아서 원시적인 방법으로 crop 기능을 직접 구현해 보면 어떨까요?

from PIL import Image

img = Image.open("test.png")
dat = img.load()

target_img = Image.new("RGB", size=(70, 20), color=(255, 255, 255))
target_dat = target_img.load()

box = (10, 10, 80, 30)

x2 = 0
y2 = 0
for x in range(10, 80):
  for y in range(10, 30):
    target_dat[x2, y2] = dat[x, y]
    y2 += 1
  x2 += 1
  y2 = 0
target_img.save("output.png")
Python

for loop을 이용해서 crop을 실행한 경우는 그림 4와 같습니다. 그림 4는 Pillow crop 메서드를 사용한 그림 3과 동일한 것을 확인할 수 있습니다.

그림 4. for loop을 이용해서 crop 한 이미지 = Pillow crop 메서드 이용시와 동일함
그림 4. for loop을 이용해서 crop 한 이미지 = Pillow crop 메서드 이용시와 동일함

리팩터링

날 것 그대로의 코드는 가독성도 떨어지고 파라미터들도 직접 다 코드를 고쳐가며 써야 하니 좋은 코드라고 할 수 없겠죠? 이해하기도 어려우니, 리팩터링을 해 보도록 하겠습니다. 물론 아래의 리팩터링이 최선이라고는 못하겠지만, 최소한 위에 작성한 코드보다는 한 발짝 나아갔다고 할 수 있습니다.

from PIL import Image

def crop(img, box):
  dat = img.load()
  width = box[2] - box[0]
  height = box[3] - box[1]

  target_img = Image.new("RGB", size=(width, height), color=(255, 255, 255))
  target_dat = target_img.load()

  x2 = 0
  y2 = 0
  for x in range(box[0], box[2]):
    for y in range(box[1], box[3]):
      target_dat[x2, y2] = dat[x, y]
      y2 += 1
    x2 += 1
    y2 = 0
  return target_img

img = Image.open("test.png")
t_img = crop(dat, (10, 10, 80, 30))
t_img.save("output.png")
Python

이 코드는 학습차원에서 단순히 재미를 위해서 작성해 본 것입니다. 실전에서는 이런 코드를 작성할 시간 없이 Pillow에서 제공하는 crop 메서드를 바로 사용해야겠죠. 여러분의 시간은 소중하니까요.

관련 자료

Pillow의 Image Module 문서에서 crop 메서드를 참고했습니다.

같이 읽으면 좋은 글

Leave a Comment