|
import time |
|
from io import BytesIO |
|
|
|
import pyvips |
|
from PIL import Image # Pillow-SIMD |
|
|
|
|
|
def figure_size(ih, iw, oh, ow): |
|
if oh / ih >= ow / oh: |
|
return int(iw * (oh / ih)), oh |
|
if oh / ih < ow / oh: |
|
return ow, int(ih * (ow / iw)) # width height |
|
|
|
|
|
def scale(ih, iw, oh, ow): |
|
if oh / ih >= ow / oh: |
|
return (oh / ih) |
|
if oh / ih < ow / oh: |
|
return (ow / iw) # scale |
|
|
|
|
|
def bench(last=None, do_print=False, iterations=None, level=0, info=""): |
|
if not last: |
|
return time.clock_gettime(time.CLOCK_THREAD_CPUTIME_ID), time.process_time(), time.perf_counter() |
|
result = ( |
|
time.clock_gettime(time.CLOCK_THREAD_CPUTIME_ID) - last[0], |
|
time.process_time() - last[1], |
|
time.perf_counter() - last[2]) |
|
if do_print: |
|
print() |
|
print((level * " ") + f"took {time.clock_gettime(time.CLOCK_THREAD_CPUTIME_ID) - last[0]} thread time") |
|
print((level * " ") + f"took {time.process_time() - last[1]:.4f} cpu time") |
|
print((level * " ") + f"took {time.perf_counter() - last[2]:.4f} real time") |
|
if iterations: |
|
print((level * " ") + f"took {(time.perf_counter() - last[2]) / iterations:.4f} per iteration") |
|
if info: |
|
print((level * " ") + info) |
|
return result |
|
|
|
|
|
def generate_image_pil(image, height, width, quality=75, optimize=False): |
|
if not isinstance(image, Image.Image): |
|
image = Image.open(BytesIO(image)) |
|
|
|
resize_image = image.resize(figure_size(image.height, image.width, height, width)) |
|
jpg_file = BytesIO() |
|
resize_image.save(jpg_file, format="JPEG", quality=quality, optimize=optimize) |
|
return jpg_file, resize_image |
|
|
|
|
|
def generate_image_vips(image, height, width, quality=75, optimize=False): |
|
if not isinstance(image, pyvips.Image): |
|
image = pyvips.Image.new_from_buffer(image, "") |
|
|
|
resize_image = image.resize(scale(image.height, image.width, height, width)) |
|
|
|
copy_timer = time.perf_counter() |
|
copy = resize_image.copy_memory() |
|
print(f"memory copy took: {time.perf_counter() - copy_timer:.4f}") |
|
|
|
jpg_file = resize_image.write_to_buffer('.jpg', Q=quality, optimize_coding=optimize) |
|
return jpg_file, copy |
|
|
|
|
|
image_file = open('example.jpg', 'rb') # https://files.catbox.moe/fxseh8.jpg |
|
image = BytesIO(image_file.read()) |
|
|
|
outside_run_time = bench() |
|
|
|
run_time = bench() |
|
original_jpg, original = generate_image_pil(image.getbuffer(), 3508, 2480, quality=90, |
|
optimize=False) # insert image decision tree |
|
bench(run_time, do_print=True, level=1, info="original conversion with pil") |
|
|
|
run_time = bench() |
|
preview_jpg, preview = generate_image_pil(original, 800, 600, quality=80, optimize=False) |
|
bench(run_time, do_print=True, level=1, info="preview conversion with pil") |
|
|
|
run_time = bench() |
|
thumbnail_jpg, thumbnail = generate_image_pil(preview, 250, 250, quality=80, optimize=False) |
|
bench(run_time, do_print=True, level=1, info="thumbnail conversion with pil") |
|
|
|
bench(outside_run_time, do_print=True, info="total time for pil") |
|
|
|
open("original_pil.jpg", "wb").write(original_jpg.getbuffer()) |
|
open("preview_pil.jpg", "wb").write(preview_jpg.getbuffer()) |
|
open("thumbnail_pil.jpg", "wb").write(thumbnail_jpg.getbuffer()) |
|
|
|
outside_run_time = bench() |
|
|
|
original_jpg, original = generate_image_vips(image.getvalue(), 3508, 2480, quality=90, optimize=False) |
|
bench(run_time, do_print=True, level=1, info="original conversion with vips") |
|
|
|
|
|
run_time = bench() |
|
preview_jpg, preview = generate_image_vips(original, 800, 600, quality=80, optimize=False) |
|
bench(run_time, do_print=True, level=1, info="preview conversion with vips") |
|
|
|
run_time = bench() |
|
thumbnail_jpg, thumbnail = generate_image_vips(preview, 250, 250, quality=80, optimize=False) |
|
bench(run_time, do_print=True, level=1, info="thumbnail conversion with vips") |
|
|
|
bench(outside_run_time, do_print=True, info="total time for vips") |
|
|
|
open("original_vips.jpg", "wb").write(original_jpg) |
|
open("preview_vips.jpg", "wb").write(preview_jpg) |
|
open("thumbnail_vips.jpg", "wb").write(thumbnail_jpg) |