scale thumbnails properly

This commit is contained in:
meeb 2020-12-06 19:10:00 +11:00
parent 60a7305fb7
commit 899803467e
7 changed files with 37 additions and 14 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -429,7 +429,11 @@ class Media(models.Model):
def loaded_metadata(self): def loaded_metadata(self):
if self.pk in _metadata_cache: if self.pk in _metadata_cache:
return _metadata_cache[self.pk] return _metadata_cache[self.pk]
_metadata_cache[self.pk] = json.loads(self.metadata) try:
unpacked_data = json.loads(self.metadata)
except Exception:
return {}
_metadata_cache[self.pk] = unpacked_data
return _metadata_cache[self.pk] return _metadata_cache[self.pk]
@property @property
@ -460,9 +464,9 @@ class Media(models.Model):
dateobj = upload_date if upload_date else self.created dateobj = upload_date if upload_date else self.created
datestr = dateobj.strftime('%Y-%m-%d') datestr = dateobj.strftime('%Y-%m-%d')
source_name = slugify(self.source.name) source_name = slugify(self.source.name)
title = slugify(self.title.replace('&', 'and').replace('+', 'and')) name = slugify(self.name.replace('&', 'and').replace('+', 'and'))
ext = self.source.extension ext = self.source.extension
fn = f'{datestr}_{source_name}_{title}'[:100] fn = f'{datestr}_{source_name}_{name}'[:100]
return f'{fn}.{ext}' return f'{fn}.{ext}'
@property @property

View File

@ -15,7 +15,7 @@ from background_task import background
from background_task.models import Task from background_task.models import Task
from common.logger import log from common.logger import log
from .models import Source, Media from .models import Source, Media
from .utils import get_remote_image from .utils import get_remote_image, resize_image_to_height
def delete_index_source_task(source_id): def delete_index_source_task(source_id):
@ -57,9 +57,6 @@ def index_source_task(source_id):
media.metadata = json.dumps(video) media.metadata = json.dumps(video)
upload_date = media.upload_date upload_date = media.upload_date
if upload_date: if upload_date:
if timezone.is_aware(upload_date):
media.published = upload_date
else:
media.published = timezone.make_aware(upload_date) media.published = timezone.make_aware(upload_date)
media.save() media.save()
log.info(f'Indexed media: {source} / {media}') log.info(f'Indexed media: {source} / {media}')
@ -76,13 +73,12 @@ def download_media_thumbnail(media_id, url):
except Media.DoesNotExist: except Media.DoesNotExist:
# Task triggered but the media no longer exists, ignore task # Task triggered but the media no longer exists, ignore task
return return
width = getattr(settings, 'MEDIA_THUMBNAIL_WIDTH', 430)
height = getattr(settings, 'MEDIA_THUMBNAIL_HEIGHT', 240)
i = get_remote_image(url) i = get_remote_image(url)
ratio = i.width / i.height
new_height = getattr(settings, 'MEDIA_THUMBNAIL_HEIGHT', 240)
new_width = math.ceil(new_height * ratio)
log.info(f'Resizing {i.width}x{i.height} thumbnail to ' log.info(f'Resizing {i.width}x{i.height} thumbnail to '
f'{new_width}x{new_height}: {url}') f'{width}x{height}: {url}')
i = i.resize((new_width, new_height), Image.ANTIALIAS) i = resize_image_to_height(i, width, height)
image_file = BytesIO() image_file = BytesIO()
i.save(image_file, 'JPEG', quality=80, optimize=True, progressive=True) i.save(image_file, 'JPEG', quality=80, optimize=True, progressive=True)
image_file.seek(0) image_file.seek(0)

View File

@ -10,7 +10,7 @@
<a href="{% url 'sync:media-item' pk=m.pk %}" class="collection-item"> <a href="{% url 'sync:media-item' pk=m.pk %}" class="collection-item">
<div class="card mediacard"> <div class="card mediacard">
<div class="card-image"> <div class="card-image">
<img src="{% if m.thumb %}{% url 'sync:media-thumb' pk=m.pk %}{% else %}{% static 'images/nothumb.jpg' %} {% endif %}"> <img src="{% if m.thumb %}{% url 'sync:media-thumb' pk=m.pk %}{% else %}{% static 'images/nothumb.png' %}{% endif %}">
<span class="card-title truncate">{{ m.source }}<br> <span class="card-title truncate">{{ m.source }}<br>
<span>{{ m.name }}</span><br> <span>{{ m.name }}</span><br>
<span>{{ m.published|date:'Y-m-d' }}</span> <span>{{ m.published|date:'Y-m-d' }}</span>

View File

@ -1,5 +1,6 @@
import os import os
import re import re
import math
from pathlib import Path from pathlib import Path
import requests import requests
from PIL import Image from PIL import Image
@ -59,6 +60,27 @@ def get_remote_image(url):
return Image.open(r.raw) return Image.open(r.raw)
def resize_image_to_height(image, width, height):
'''
Resizes an image to 'height' pixels keeping the ratio. If the resulting width
is larger than 'width' then crop it. If the resulting width is smaller than
'width' then stretch it.
'''
ratio = image.width / image.height
scaled_width = math.ceil(height * ratio)
if scaled_width < width:
# Width too small, stretch it
scaled_width = width
image = image.resize((scaled_width, height), Image.ANTIALIAS)
if scaled_width > width:
# Width too large, crop it
delta = scaled_width - width
left, upper = (delta / 2), 0
right, lower = (left + width), height
image = image.crop((left, upper, right, lower))
return image
def file_is_editable(filepath): def file_is_editable(filepath):
''' '''
Checks that a file exists and the file is in an allowed predefined tuple of Checks that a file exists and the file is in an allowed predefined tuple of

View File

@ -127,6 +127,7 @@ MEDIA_PER_PAGE = 36
INDEX_SOURCE_EVERY = 21600 # Seconds between indexing sources, 21600 = every 6 hours INDEX_SOURCE_EVERY = 21600 # Seconds between indexing sources, 21600 = every 6 hours
MEDIA_THUMBNAIL_WIDTH = 430 # Width in pixels to resize thumbnails to
MEDIA_THUMBNAIL_HEIGHT = 240 # Height in pixels to resize thumbnails to MEDIA_THUMBNAIL_HEIGHT = 240 # Height in pixels to resize thumbnails to