Thumbnails for images and videos #87
@ -1,4 +1,5 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
import datetime
|
||||||
import hashlib
|
import hashlib
|
||||||
import io
|
import io
|
||||||
import logging
|
import logging
|
||||||
@ -221,10 +222,16 @@ def get_thumbnail_upload_to(file_hash: str, width: int = None, height: int = Non
|
|||||||
|
|
||||||
def resize_image(image: Image, size: tuple, output, output_format: str = 'PNG', **output_params):
|
def resize_image(image: Image, size: tuple, output, output_format: str = 'PNG', **output_params):
|
||||||
"""Resize a models.ImageField to a given size and write it into output file."""
|
"""Resize a models.ImageField to a given size and write it into output file."""
|
||||||
|
start_t = datetime.datetime.now()
|
||||||
|
|
||||||
source_image = image.convert('RGBA' if output_format == 'PNG' else 'RGB')
|
source_image = image.convert('RGBA' if output_format == 'PNG' else 'RGB')
|
||||||
source_image.thumbnail(size, Image.LANCZOS)
|
source_image.thumbnail(size, Image.LANCZOS)
|
||||||
source_image.save(output, output_format, **output_params)
|
source_image.save(output, output_format, **output_params)
|
||||||
|
|
||||||
|
end_t = datetime.datetime.now()
|
||||||
|
args = {'source': image, 'size': size, 'time': (end_t - start_t).microseconds / 1000}
|
||||||
|
logger.info('%(source)s to %(size)s done in %(time)sms', args)
|
||||||
|
|
||||||
|
|
||||||
def make_thumbnails(
|
def make_thumbnails(
|
||||||
source_path: str, file_hash: str, output_format: str = THUMBNAIL_FORMAT
|
source_path: str, file_hash: str, output_format: str = THUMBNAIL_FORMAT
|
||||||
@ -234,6 +241,7 @@ def make_thumbnails(
|
|||||||
Resulting thumbnail paths a derived from the given file hash and thumbnail sizes.
|
Resulting thumbnail paths a derived from the given file hash and thumbnail sizes.
|
||||||
Return a dict of size keys to output paths of generated thumbnail images.
|
Return a dict of size keys to output paths of generated thumbnail images.
|
||||||
"""
|
"""
|
||||||
|
start_t = datetime.datetime.now()
|
||||||
thumbnails = {}
|
thumbnails = {}
|
||||||
abs_path = os.path.join(settings.MEDIA_ROOT, source_path)
|
abs_path = os.path.join(settings.MEDIA_ROOT, source_path)
|
||||||
image = Image.open(abs_path)
|
image = Image.open(abs_path)
|
||||||
@ -259,12 +267,17 @@ def make_thumbnails(
|
|||||||
default_storage.save(output_path, f)
|
default_storage.save(output_path, f)
|
||||||
thumbnails[size_key] = {'size': size, 'path': output_path}
|
thumbnails[size_key] = {'size': size, 'path': output_path}
|
||||||
image.close()
|
image.close()
|
||||||
|
|
||||||
|
end_t = datetime.datetime.now()
|
||||||
|
args = {'source': source_path, 'time': (end_t - start_t).microseconds / 1000}
|
||||||
|
logger.info('%(source)s done in %(time)sms', args)
|
||||||
return thumbnails
|
return thumbnails
|
||||||
|
|
||||||
|
|
||||||
def extract_frame(source_path: str, output_path: str, at_time: str = '00:00:00.01'):
|
def extract_frame(source_path: str, output_path: str, at_time: str = '00:00:00.01'):
|
||||||
"""Extract a single frame of a video at a given path, write it to the given output path."""
|
"""Extract a single frame of a video at a given path, write it to the given output path."""
|
||||||
try:
|
try:
|
||||||
|
start_t = datetime.datetime.now()
|
||||||
abs_path = os.path.join(settings.MEDIA_ROOT, output_path)
|
abs_path = os.path.join(settings.MEDIA_ROOT, output_path)
|
||||||
ffmpeg = (
|
ffmpeg = (
|
||||||
FFmpeg()
|
FFmpeg()
|
||||||
@ -276,6 +289,10 @@ def extract_frame(source_path: str, output_path: str, at_time: str = '00:00:00.0
|
|||||||
if not os.path.isdir(output_dir):
|
if not os.path.isdir(output_dir):
|
||||||
os.mkdir(output_dir)
|
os.mkdir(output_dir)
|
||||||
ffmpeg.execute()
|
ffmpeg.execute()
|
||||||
|
|
||||||
|
end_t = datetime.datetime.now()
|
||||||
|
args = {'source': source_path, 'time': (end_t - start_t).microseconds / 1000}
|
||||||
|
logger.info('%(source)s done in %(time)sms', args)
|
||||||
except (FFmpegError, FFmpegFileNotFound, FFmpegInvalidCommand) as e:
|
except (FFmpegError, FFmpegFileNotFound, FFmpegInvalidCommand) as e:
|
||||||
logger.exception(f'Failed to extract a frame: {e.message}, {" ".join(ffmpeg.arguments)}')
|
logger.exception(f'Failed to extract a frame: {e.message}, {" ".join(ffmpeg.arguments)}')
|
||||||
raise
|
raise
|
||||||
|
Loading…
Reference in New Issue
Block a user