Skip to main content Link Search Menu Expand Document (external link)

pillow(PIL)

Table of contents

  1. 주요기능
  2. Download and Documentation
  3. 설치
  4. 사용 예
  5. Image 모듈 사용
    1. 이미지 불러오기 및 이미지 보기
    2. 이미지 속성 확인
    3. 이미지 크기 변경하기 : resoze((w,h), option)
    4. 이미지 자르기 : crop((left, upper, right, lower))
    5. 이미지 회전 : rotate(회전각도)
    6. 이미지 상하, 좌우 대칭 : transpose(옵션)
    7. 이미지 합치기 : new(mode,size,color)
    8. 이미지 저장
    9. thumbnail 만들기
  6. ImageFilter 모듈 사용
    1. Blur 처리
  7. 이미지 처리
    1. 현재 디렉토리의 모든 png 이미지를 썸네일로 만들기
    2. 이미지를 바이트배열(bytearray)로 변환
    3. 이미지를 넘파이 배열로 변환
    4. 넘파이(numpy) 배열을 이미지로 변환
    5. 이미지를 픽셀 값으로 변환
    6. 이미지의 특정 픽셀의 RGB 색상 구하기
  8. 이미지 관리 프로그램

Alt text

from PIL import Image
from io import BytesIO


def source_to_pil(source:str)->Image:
    """image source -> pil_img"""
    pil = Image.open(source)
    print(pil,pil.format)
    return pil  
    
def source_to_bytesio(source:str)->BytesIO:
    """image source -> BytesIO"""
    f = open(source,'rb')
    b_data = f.read()
    io_data = BytesIO(b_data)
    print(io_data)
    return io_data  
          
def bytesio_to_pil(bytesio:BytesIO)->Image:
    """BytesIO -> pil image"""
    pil = Image.open(bytesio)
    print(pil,pil.format)
    return pil
    
def pil_to_io(p_img:Image,format:str=None)->BytesIO:
    """pil image -> BytesIO(메모리)"""
    io_data = BytesIO()
    if not format:
        format = p_img.format
    p_img.save(io_data,format)
    print(io_data)
    return io_data 
    
def bytesio_to_bytes_data(bytesio:BytesIO)->bytes:
    """BytesIO -> bytes data"""
    b_data = bytesio.getvalue()
    print(b_data)
    return b_data  

def bytes_data_to_img_file(b_data:bytes,file_name:str)->None:
    """byte data -> image file"""
    f = open(file_name,'wb')
    f.write(b_data) 
    

def p_img_to_img(p_img:Image, file_name:str,format:str)->None:
    """pil image -> imgage file"""
    p_img.save(file_name,format)    

if __name__ =='__main__':
        
    p_img = source_to_pil('아이유.png')

    io = source_to_bytesio('아이유.png')
    p_img2 = bytesio_to_pil(io)

    io2 = pil_to_io(p_img2,format='gif')
    b_data = bytesio_to_bytes_data(io2)
    bytes_data_to_img_file(b_data,'아이유_복사.gif')

    p_img_to_img(p_img2,'아이유_복사본.gif' ,'gif')

이미지 분석 및 처리를 쉽게 할 수 있는 라이브러리(Python Imaging Library : PIL)가 있습니다. 바로 pillow모듈입니다. 다양한 이미지 파일 형식을 지원하며, 강력한 이미지 처리와 그래픽 기능을 제공하는 이미지프로세싱 라이브러리의 한 종류입니다.

주요기능

PIL 이미지 작업을 위한 표준 절차를 제공하고 있으며, 다음과 같은 것이있다.(출처 :위키백과)

  • 픽셀 단위의 조작
  • 마스킹 및 투명도 제어
  • 흐림, 윤곽 보정 다듬어 윤곽 검출 등의 이미지 필터
  • 선명하게, 밝기 보정, 명암 보정, 색 보정 등의 화상 조정
  • 이미지에 텍스트 추가
  • 기타 여러가지

Download and Documentation

  • https://github.com/python-pillow
  • https://pillow.readthedocs.io/en/stable/index.html

설치

pip install pillow

사용 예

Alt text 아이유 사진 출처 : twitter.com/IUsFairyTale

from PIL import Image, ImageFilter  # 라이브러리를  임포트 한다.

original = Image.open("아이유.png")           # 하드 드라이브에서 이미지를 읽어 들인다.
blurred = original.filter(ImageFilter.BLUR) # 이미지를 흐리게 한다.
print(type(original)) # <class 'PIL.PngImagePlugin.PngImageFile'>
print(type(blurred))  # <class 'PIL.Image.Image'>

original.show() # 두 이미지를 디스플레이 한다.
blurred.show()

Image 모듈 사용

from PIL import Image

이미지 불러오기 및 이미지 보기

img_obj = Image.open("아이유.png")  # 이미지 파일 불러오기
img_obj.show() # 이미지 보이기
  • 이미지 파일관 호환 문제로 원본과 다른 파일 형식으로 저장 시 에러 발생
    [해결책] 이미지 불러들일 때 형식을 변환하여 읽기 img = Image.open(“아이유.png”).convert(‘RGB’)
convert('RGB') 함수 사용을 통해 이미지 모드를 통일하여 사용하자.

from PIL import Image

# 2. 이미지 파일 변환(정상) #
try:
    im = Image.open("anchors.png").convert('RGB')
    im.save("anchors.webp", 'webp')

    change_im = Image.open("anchors.webp")
    img_width, img_height = change_im.size
    print("이미지 확장자:", change_im.format)
    print("이미지 사이즈:", change_im.size)
    print("이미지 가로:", img_width)
    print("이미지 세로:", img_height)
    print("이미지 모드:", change_im.mode)
except OSError as e:
    print(e)


[output]
이미지 확장자: WEBP
이미지 사이즈: (600, 300)
이미지 가로: 600
이미지 세로: 300
이미지 모드: RGB

이미지 속성 확인

print(f'파일 이름 : {img_obj.filename}')
print(f'파일형식(format) : {img_obj.format}')
print(f'용량(size) : {img_obj.size}')
print(f'색상모드 : {img_obj.mode}')
print(f'width : {img_obj.width}')
print(f'height : {img_obj.height}')
파일 이름 : 아이유.png
파일형식(format) : PNG
용량(size) : (425, 426)
색상모드 : RGBA
width : 425
height : 426

이미지 크기 변경하기 : resoze((w,h), option)

인자는 size 요소 - 튜플자료형

# 이미지 size 1/2로 줄이기
w, h = img_obj.size
result_img = img_obj.resize((w // 2, h // 2))
result_img.show()
  • option
필터내용
PIL.Image.NEAREST입력 이미지에서 가장 가까운 픽셀 하나를 선택합니다. 다른 모든 입력 픽셀은 무시합니다.
PIL.Image.BOX소스 이미지의 각 픽셀은 동일한 가중치를 가진 대상 이미지의 한 픽셀에 기여합니다. 업 스케일링의 경우 NEAREST. 이 필터는 resize() 및 thumbnail()메서드 에서만 사용할 수 있습니다 .
PIL.Image.BILINEAR크기 조정을 위해 출력 값에 기여할 수있는 모든 픽셀에서 선형 보간법을 사용하여 출력 픽셀 값을 계산합니다. 다른 변환의 경우 입력 이미지의 2x2 환경에 대한 선형 보간이 사용됩니다.
PIL.Image.HAMMINGBILINEAR보다 선명한 이미지를 생성합니다. BOX처럼 로컬 수준의 전위가 없습니다. 이 필터는 resize() 및 thumbnail()메서드 에서만 사용할 수 있습니다 .
PIL.Image.BICUBI크기 조정을 위해 출력 값에 기여할 수 있는 모든 픽셀에서 삼차 보간법을 사용하여 출력 픽셀 값을 계산합니다. 다른 변환의 경우 입력 이미지의 4x4 환경에 대한 큐빅 보간이 사용됩니다.
PIL.Image.LANCZOS출력 값에 기여할 수있는 모든 픽셀에서 고품질 Lanczos 필터 (잘린 sinc)를 사용하여 출력 픽셀 값을 계산합니다. 이 필터는 resize() 및 thumbnail()메서드 에서만 사용할 수 있습니다 .

이미지 자르기 : crop((left, upper, right, lower))

Alt text

cropped_img = img.crop((200, 200, 425, 426))
cropped_img.show()

이미지 회전 : rotate(회전각도)

result_img = img_obj.rotate(45) # 45도 회전(반시계방향)
result_img.show()

이미지 상하, 좌우 대칭 : transpose(옵션)

옵션

  • Image.FLIP_LEFT_RIGHT : 좌우 대칭처리
  • Image.FLIP_TOP_BOTTOM : 상하 대칭처리
  • 회전처리 Image.ROTATE_90 : 90도 회전 Image.ROTATE_180: 180도 회전 Image.ROTATE_270: 270도 회전
result_img = img_obj.transpose(Image.FLIP_LEFT_RIGHT)
result_img.show()
result_img = img_obj.transpose(Image.ROTATE_270)
result_img.show()

이미지 합치기 : new(mode,size,color)

Alt textAlt textAlt textAlt text


from PIL import Image, ImageFilter

# 이미지 불러오기
img1 = Image.open('아이유.png')
img2 = Image.open('1.png')
img3 = Image.open('2.png')

# 새 이미지 만들기
new_img = Image.new('RGBA',(700,700),(255, 192, 0))

# 이미지 붙이기
new_img.paste(img1, (10,10))     # left,top 위치만 지정
new_img.paste(img2,(20+img1.width,10))
new_img.paste(img3,(20+img1.width,20+img2.height))

new_img.show()

이미지 저장

from PIL import Image, ImageFilter

# 이미지 불러오기
img_obj = Image.open('아이유.png')
img_obj.save('아이유2.png')

result_obj = Image.open('아이유2.png')
result_obj.show()

thumbnail 만들기

from PIL import Image
size = (40, 40)  #튜플자료형으로 괄호 생략 가능(#<class 'tuple'>)

img_obj = Image.open("아이유.png")
img_obj.thumbnail(size)

img_obj.save("아이유3.png")
result_img = Image.open("아이유3.png")
result_img.show()

ImageFilter 모듈 사용

from PIL import Image, ImageFilter
img_obj = Image.open("아이유.png")  # 하드 드라이브에서 이미지를 읽어 들인다.

Image.filter()함수를 사용하여 이미지 필터 적용

  • BLUR
  • CONTOUR
  • DETAIL
  • EDGE_ENHANCE
  • EDGE_ENHANCE_MORE
  • EMBOSS
  • FIND_EDGES
  • SHARPEN
  • SMOOTH
  • SMOOTH_MORE

Blur 처리

옵션 ImageFilter.BLUR : 고정된 값으로 Blur처리 ImageFiler.BoxBlur()함수 ImageFilter.GaussianBlur()함수

result_img = img_obj.filter(ImageFilter.BLUR)
result_img.show()

result_img = img_obj.filter(ImageFilter.BoxBlur(10))
result_img.show()

result_img = img_obj.filter(ImageFilter.GaussianBlur(10))
result_img.show()
#전체옵션 보기
from PIL import Image, ImageFilter

img_obj = Image.open("아이유.png")  # 하드 드라이브에서 이미지를 읽어 들인다.

filter_list = [ImageFilter.BLUR, ImageFilter.CONTOUR, ImageFilter.DETAIL,
               ImageFilter.EDGE_ENHANCE, ImageFilter.EDGE_ENHANCE_MORE,
               ImageFilter.EMBOSS, ImageFilter.FIND_EDGES,
               ImageFilter.SHARPEN, ImageFilter.SMOOTH,
               ImageFilter.SMOOTH_MORE]

for i in range(len(filter_list)):
    result_img = img_obj.filter(filter_list[i])
    # filter_img.save("C:/Users/ilike/Pictures/filter_img_{}.jpg".format(i))
    result_img.show()

이미지 처리

현재 디렉토리의 모든 png 이미지를 썸네일로 만들기


from PIL import Image
import glob, os, pathlib

target = glob.glob("./*.png")
print("파일 개수 :", len(target))
size = (40, 40)  #튜플자료형으로 괄호 생략 가능(#<class 'tuple'>)
for file in target:
    file_path = pathlib.Path('.') / file
    img_obj = Image.open(file)
    img_obj.thumbnail(size)

    img_obj.save(file_path.stem + ".thumbnail"+".png")

이미지를 바이트배열(bytearray)로 변환

io.BytesIO()를 사용하여 이미지를 byte array로 변환

from PIL import Image
import io

def image_to_byte_array(image):
    img_obj = Image.open(image)
    byte_arr = io.BytesIO()
    img_obj.save(byte_arr, format=img_obj.format)
    return byte_arr.getvalue()
img = "아이유.png"
print(image_to_byte_array(img))

이미지를 넘파이 배열로 변환

numpy.array()함수를 사용하여 이미지를 배열 객체로 반환할 수 있습니다.

from PIL import Image
import numpy as np
img = Image.open("아이유.png")

numpy_img = np.array(img)
print(type(numpy_img))
print(numpy_img)
#실행결과
<class 'numpy.ndarray'>
[[[246 246 248]
  [246 246 248]
  [246 246 248]
  ...
  [242 241 246]
  [242 241 246]
  [242 241 246]]
  .....이하생략

넘파이(numpy) 배열을 이미지로 변환

from PIL import Image
import numpy as np
img = Image.open("아이유.png")

#numpy_array = np.array(img, dtype="uint8")
numpy_array = np.array(img)
   
image2 = Image.fromarray(numpy_array, 'RGB')
image2.show() 

이미지를 픽셀 값으로 변환

from PIL import Image
import numpy as np
img = Image.open("아이유.png")

pixel_list = list(img.getdata())
print(pixel_list)
np.savetxt("pixel_type_data.txt", pixel_list, fmt='%d', delimiter=" ")

이미지의 특정 픽셀의 RGB 색상 구하기

convert()함수를 사용하여 RGB 데이터를 가져옵니다.
그런 다음, getpixel()함수를 사용하여 특정 픽셀의 x, y 좌표값을 지정하면 픽셀값을 튜플자료형으로 반환합니다.

from PIL import Image
img = Image.open("C:/Users/ilike/Pictures/IU_400x400.jpg")

rgb_img = img.convert("RGB")

#지정한 좌표값의 픽셀값 튜플자료형으로 반환
tuple_item = rgb_img.getpixel((1, 100))
print(tuple_item) 

r, g, b = tuple_item
print(r)
print(g)
print(b)
#실행결과
(244, 245, 249)
244
245
249

이미지 관리 프로그램

from io import BytesIO
from PIL import Image
import sys


def data_to_img(data):
    """Return PIL Image object, with data from in-memory <data>"""
    # open함수와 비슷한 기능
    fp = BytesIO(data)
    return Image.open(fp)  # reads from memory


def img_to_data(img, fmt=None):
    """Return image data from PIL Image <img>, in <fmt> format"""
    fp = BytesIO()
    if not fmt:
        fmt = img.format  # keeps the original format
        img.save(fp, fmt)  # writes to memory
    return fp.getvalue()


def convert_image(data, fmt=None):
    """Convert image <data> to PIL <fmt> image data"""
    img = data_to_img(data)
    return img_to_data(img, fmt)


def get_file_data(name):
    """Return PIL Image object for image file <name>"""
    img = Image.open(name)
    print("img", img, img.format)
    return img_to_data(img)


if __name__ == "__main__":
    for name in sys.argv[1:]:
        data = get_file_data(name)
        print("in", len(data), data[:10])
    for fmt in ("gif", "png", "jpeg"):
        outdata = convert_image(data, fmt)
        print("out", len(outdata), outdata[:10])