Python Imaging Library
The Python Imaging Library (PIL) adds image processing capabilities to your Python interpreter. This library supports many file formats, and provides powerful image processing and graphics capabilities.
Python Imaging Library(PIL)은 파이썬 인터프리터에 다양한 이미지 파일 형식을 지원하고 강력한 이미지 처리와 그래픽 기능을 제공하는 자유-오픈 소스 소프트웨어 라이브러리이다. 줄여서 PIL이라고 부른다. 윈도우와 맥 오에스 엑스, 리눅스를 지원한다. PIL의 최신 버젼은 1.1.7이고 2009년 9월에 릴리즈 되었으며 파이선 1.5-2.7을 지원한다.
개발은 2011년 PIL 저장소에 대한 마지막 커밋으로 중단된 것으로 보이며 Pillow라는 후속 프로젝트가 PIL 저장소에서 갈려져 나와 Phthon 3.x 지원을 추가 했다. Pillow는 PIL 후속 프로젝트로써 데비안 및 우분투 등의 리눅스 배포판에서 PIL을 대체하기 위해서 채택 되었다.
JPEG Image Quality in PIL
The quality parameter
The image quality, on a scale from 1 (worst) to 95 (best). The default is 75. Values above 95 should be avoided; 100 disables portions of the JPEG compression algorithm, and results in large files with hardly any gain in image quality.
Using a quality factor of 95 should be enough to preserve the image quality:
Subsampling
According to this post, even if you use quality=100
, the saved image will still be slightly different from the original image. This is because PIL will also use subsampling technique to reduce the image size. You can use subsampling=0
to turn off this feature. Overall, to retain the content of original image, you may use:
labelme2coco image utils
import base64
import io
import numpy as np
import PIL.ExifTags
import PIL.Image
import PIL.ImageOps
def img_data_to_pil(img_data):
f = io.BytesIO()
f.write(img_data)
img_pil = PIL.Image.open(f)
return img_pil
def img_data_to_arr(img_data):
img_pil = img_data_to_pil(img_data)
img_arr = np.array(img_pil)
return img_arr
def img_b64_to_arr(img_b64):
img_data = base64.b64decode(img_b64)
img_arr = img_data_to_arr(img_data)
return img_arr
def img_pil_to_data(img_pil):
f = io.BytesIO()
img_pil.save(f, format="PNG")
img_data = f.getvalue()
return img_data
def img_arr_to_b64(img_arr):
img_pil = PIL.Image.fromarray(img_arr)
f = io.BytesIO()
img_pil.save(f, format="PNG")
img_bin = f.getvalue()
if hasattr(base64, "encodebytes"):
img_b64 = base64.encodebytes(img_bin)
else:
img_b64 = base64.encodestring(img_bin)
return img_b64
def img_data_to_png_data(img_data):
with io.BytesIO() as f:
f.write(img_data)
img = PIL.Image.open(f)
with io.BytesIO() as f:
img.save(f, "PNG")
f.seek(0)
return f.read()
def apply_exif_orientation(image):
try:
exif = image._getexif()
except AttributeError:
exif = None
if exif is None:
return image
exif = {
PIL.ExifTags.TAGS[k]: v
for k, v in exif.items()
if k in PIL.ExifTags.TAGS
}
orientation = exif.get("Orientation", None)
if orientation == 1:
# do nothing
return image
elif orientation == 2:
# left-to-right mirror
return PIL.ImageOps.mirror(image)
elif orientation == 3:
# rotate 180
return image.transpose(PIL.Image.ROTATE_180)
elif orientation == 4:
# top-to-bottom mirror
return PIL.ImageOps.flip(image)
elif orientation == 5:
# top-to-left mirror
return PIL.ImageOps.mirror(image.transpose(PIL.Image.ROTATE_270))
elif orientation == 6:
# rotate 270
return image.transpose(PIL.Image.ROTATE_270)
elif orientation == 7:
# top-to-right mirror
return PIL.ImageOps.mirror(image.transpose(PIL.Image.ROTATE_90))
elif orientation == 8:
# rotate 90
return image.transpose(PIL.Image.ROTATE_90)
else:
return image