74 lines
2.4 KiB
Python
74 lines
2.4 KiB
Python
import os
|
|
import sys
|
|
import traceback
|
|
from PIL import Image, ImageOps
|
|
from multiprocessing import Process
|
|
|
|
|
|
# style tuples: max x, max y, rotate ok)
|
|
# rotate ok means x and y maxes can be swapped if it fits the image's aspect ratio better
|
|
THUMB_STYLES = {"tiny": (80, 80, False),
|
|
"small": (100, 100, False),
|
|
"feed": (250, 250, False),
|
|
"preview": (1024, 768, True),
|
|
"big": (2048, 1536, True)}
|
|
|
|
|
|
def thumb_path(style_name, uuid):
|
|
return os.path.join("thumbs", style_name, uuid[0:2], "{}.jpg".format(uuid))
|
|
|
|
|
|
def image_style(image, style_name, orientation):
|
|
"""
|
|
Given an input PIL Image object, return a scaled/cropped image object of style_name
|
|
"""
|
|
thumb_width, thumb_height, flip_ok = THUMB_STYLES[style_name]
|
|
i_width, i_height = image.size
|
|
|
|
im_is_rotated = orientation % 2 != 0 or i_height > i_width
|
|
|
|
if im_is_rotated and flip_ok:
|
|
thumb_width, thumb_height = thumb_height, thumb_width
|
|
|
|
# prevents scale-up (why do i want this?)
|
|
thumb_width = min(thumb_width, i_width) if i_width > 0 else thumb_width
|
|
thumb_height = min(thumb_height, i_height) if i_height > 0 else thumb_height
|
|
|
|
image = image.rotate(90 * orientation, expand=True)
|
|
return ImageOps.fit(image, (thumb_width, thumb_height), Image.ANTIALIAS)
|
|
|
|
|
|
def image_file_style(src_path, output_path, style_name, orientation):
|
|
"""
|
|
Given an input and output image paths, create a scaled/cropped image file of style_name
|
|
"""
|
|
image = Image.open(src_path)
|
|
if image.mode != "RGB":
|
|
image = image.convert("RGB")
|
|
output = image_style(image, style_name, orientation)
|
|
output.save(output_path, 'JPEG')
|
|
|
|
|
|
def _image_file_style_process_worker(src_path, output_path, style_name, orientation):
|
|
try:
|
|
image_file_style(src_path, output_path, style_name, orientation)
|
|
except Exception:
|
|
traceback.print_exc()
|
|
if os.path.exists(output_path):
|
|
os.unlink(output_path)
|
|
sys.exit(1)
|
|
|
|
|
|
def image_file_style_process(src_path, output_path, style_name, orientation):
|
|
"""
|
|
Same as image_file_style but the image manipulation is done in a background process
|
|
"""
|
|
p = Process(target=_image_file_style_process_worker,
|
|
args=(src_path, output_path, style_name, orientation))
|
|
p.start()
|
|
p.join()
|
|
if p.exitcode != 0:
|
|
return False
|
|
|
|
return True
|