Make the slide height affect the size of the thumbnails generated

This commit is contained in:
Raoul Snyman 2024-04-14 22:36:19 -07:00
parent 6498b66698
commit 885e57ba41
5 changed files with 94 additions and 20 deletions

View File

@ -35,6 +35,9 @@ from openlp.core.common.i18n import UiStrings, translate
log = logging.getLogger(__name__ + '.__init__')
DEFAULT_THUMBNAIL_HEIGHT = 88
class DataType(IntEnum):
U8 = 1
U16 = 2
@ -301,8 +304,8 @@ def create_thumb(image_path, thumb_path, return_icon=True, size=None):
:param Path image_path: The image file to create the icon from.
:param Path thumb_path: The filename to save the thumbnail to.
:param return_icon: States if an icon should be build and returned from the thumb. Defaults to ``True``.
:param size: Allows to state a own size (QtCore.QSize) to use. Defaults to ``None``, which means that a default
height of 88 is used.
:param size: Allows to state a own size (QtCore.QSize) to use. Defaults to ``None``, which means it uses the value
from DEFAULT_THUMBNAIL_HEIGHT.
:return: The final icon.
"""
reader = QtGui.QImageReader(str(image_path))
@ -312,7 +315,7 @@ def create_thumb(image_path, thumb_path, return_icon=True, size=None):
ratio = 1
else:
ratio = reader.size().width() / reader.size().height()
reader.setScaledSize(QtCore.QSize(int(ratio * 88), 88))
reader.setScaledSize(QtCore.QSize(int(ratio * DEFAULT_THUMBNAIL_HEIGHT), DEFAULT_THUMBNAIL_HEIGHT))
elif size.isValid():
# Complete size given
reader.setScaledSize(size)
@ -330,7 +333,7 @@ def create_thumb(image_path, thumb_path, return_icon=True, size=None):
reader.setScaledSize(QtCore.QSize(int(ratio * size.height()), size.height()))
else:
# Invalid; use default height of 88
reader.setScaledSize(QtCore.QSize(int(ratio * 88), 88))
reader.setScaledSize(QtCore.QSize(int(ratio * DEFAULT_THUMBNAIL_HEIGHT), DEFAULT_THUMBNAIL_HEIGHT))
thumb = reader.read()
thumb.save(str(thumb_path), thumb_path.suffix[1:].lower())
if not return_icon:

View File

@ -21,6 +21,7 @@
import logging
from pathlib import Path
from typing import Union
from PyQt5 import QtCore, QtWidgets
@ -159,7 +160,11 @@ class ImageMediaItem(FolderLibraryItem):
if validate_thumb(file_path, thumbnail_path):
icon = build_icon(thumbnail_path)
else:
icon = create_thumb(file_path, thumbnail_path)
size: Union[QtCore.QSize, None] = None
slide_height: Union[int, None] = self.settings.value('advanced/slide max height')
if slide_height and slide_height > 0:
size = QtCore.QSize(-1, slide_height)
icon = create_thumb(file_path, thumbnail_path, size=size)
tree_item = QtWidgets.QTreeWidgetItem([file_name])
tree_item.setData(0, QtCore.Qt.UserRole, item)
tree_item.setIcon(0, icon)

View File

@ -30,7 +30,9 @@ from unittest.mock import MagicMock, patch
from PyQt5 import QtCore, QtGui
from openlp.core.lib import DataType, build_icon, check_item_selected, create_separated_list, create_thumb, \
get_text_file_string, image_to_byte, read_or_fail, read_int, resize_image, seek_or_fail, str_to_bool, validate_thumb
get_text_file_string, image_to_byte, read_or_fail, read_int, resize_image, seek_or_fail, str_to_bool, \
validate_thumb
from openlp.core.common.registry import Registry
from tests.utils.constants import RESOURCE_PATH
@ -275,7 +277,7 @@ def test_image_to_byte_base_64():
assert 'byte_array base64ified' == result, 'The result should be the return value of the mocked base64 method'
def test_create_thumb_with_size(registry):
def test_create_thumb_with_size(registry: Registry):
"""
Test the create_thumb() function with a given size.
"""
@ -310,7 +312,7 @@ def test_create_thumb_with_size(registry):
pass
def test_create_thumb_no_size(registry):
def test_create_thumb_no_size(registry: Registry):
"""
Test the create_thumb() function with no size specified.
"""
@ -345,7 +347,7 @@ def test_create_thumb_no_size(registry):
pass
def test_create_thumb_invalid_size(registry):
def test_create_thumb_invalid_size(registry: Registry):
"""
Test the create_thumb() function with invalid size specified.
"""
@ -381,7 +383,7 @@ def test_create_thumb_invalid_size(registry):
pass
def test_create_thumb_width_only(registry):
def test_create_thumb_width_only(registry: Registry):
"""
Test the create_thumb() function with a size of only width specified.
"""
@ -417,7 +419,7 @@ def test_create_thumb_width_only(registry):
pass
def test_create_thumb_height_only(registry):
def test_create_thumb_height_only(registry: Registry):
"""
Test the create_thumb() function with a size of only height specified.
"""
@ -453,7 +455,7 @@ def test_create_thumb_height_only(registry):
pass
def test_create_thumb_empty_img(registry):
def test_create_thumb_empty_img(registry: Registry):
"""
Test the create_thumb() function with a size of only height specified.
"""
@ -504,7 +506,7 @@ def test_create_thumb_empty_img(registry):
@patch('openlp.core.lib.QtGui.QImageReader')
@patch('openlp.core.lib.build_icon')
def test_create_thumb_path_fails(mocked_build_icon, MockQImageReader, registry):
def test_create_thumb_path_fails(mocked_build_icon: MagicMock, MockQImageReader: MagicMock, registry: Registry):
"""
Test that build_icon() is run against the image_path when the thumbnail fails to be created
"""
@ -539,7 +541,7 @@ def test_check_item_selected_true():
assert result is True, 'The result should be True'
def test_check_item_selected_false(registry):
def test_check_item_selected_false(registry: Registry):
"""
Test that the check_item_selected() function returns False when there are no selected indexes.
"""
@ -610,7 +612,7 @@ def test_validate_thumb_file_exists_and_older():
assert result is False, 'The result should be False'
def test_resize_thumb(registry):
def test_resize_thumb(registry: Registry):
"""
Test the resize_thumb() function
"""
@ -632,7 +634,7 @@ def test_resize_thumb(registry):
assert image.pixel(0, 0) == wanted_background_rgb, 'The background should be white.'
def test_resize_thumb_ignoring_aspect_ratio(registry):
def test_resize_thumb_ignoring_aspect_ratio(registry: Registry):
"""
Test the resize_thumb() function ignoring aspect ratio
"""
@ -654,7 +656,7 @@ def test_resize_thumb_ignoring_aspect_ratio(registry):
assert image.pixel(0, 0) == wanted_background_rgb, 'The background should be white.'
def test_resize_thumb_width_aspect_ratio(registry):
def test_resize_thumb_width_aspect_ratio(registry: Registry):
"""
Test the resize_thumb() function using the image's width as the reference
"""
@ -672,7 +674,7 @@ def test_resize_thumb_width_aspect_ratio(registry):
assert wanted_width == result_size.width(), 'The image should have the requested width.'
def test_resize_thumb_same_aspect_ratio(registry):
def test_resize_thumb_same_aspect_ratio(registry: Registry):
"""
Test the resize_thumb() function when the image and the wanted aspect ratio are the same
"""
@ -691,7 +693,7 @@ def test_resize_thumb_same_aspect_ratio(registry):
@patch('openlp.core.lib.QtCore.QLocale.createSeparatedList')
def test_create_separated_list_qlocate(mocked_createSeparatedList):
def test_create_separated_list_qlocate(mocked_createSeparatedList: MagicMock):
"""
Test the create_separated_list function using the Qt provided method
"""

View File

@ -22,17 +22,20 @@
This module contains tests for the lib submodule of the Images plugin.
"""
from pathlib import Path
from tempfile import TemporaryDirectory
from unittest.mock import ANY, MagicMock, patch
import pytest
from PyQt5 import QtCore, QtWidgets
from openlp.core.common.registry import Registry
from openlp.core.common.enum import ImageThemeMode
from openlp.core.common.registry import Registry
from openlp.core.db.manager import DBManager
from openlp.core.lib import build_icon, create_thumb
from openlp.core.lib.serviceitem import ItemCapabilities
from openlp.core.widgets.views import TreeWidgetWithDnD
from openlp.plugins.images.lib.mediaitem import ImageMediaItem
from tests.utils.constants import TEST_RESOURCES_PATH
@pytest.fixture
@ -258,3 +261,64 @@ def test_generate_thumbnail_path_filename(media_item):
# THEN: The path should be correct
assert result == Path('.') / 'myimage.jpg'
@patch('openlp.plugins.images.lib.mediaitem.create_thumb')
def test_load_item_file_not_exist(mocked_create_thumb: MagicMock, media_item: ImageMediaItem):
"""Test the load_item method when the file does not exist"""
# GIVEN: A media item and an Item to load
item = MagicMock(file_path=Path('myimage.jpg'), file_hash=None)
# WHEN load_item() is called with the Item
result = media_item.load_item(item)
# THEN: A QTreeWidgetItem with a "delete" icon should be returned
assert isinstance(result, QtWidgets.QTreeWidgetItem)
assert result.text(0) == 'myimage.jpg'
mocked_create_thumb.assert_not_called()
@patch('openlp.plugins.images.lib.mediaitem.validate_thumb')
@patch('openlp.plugins.images.lib.mediaitem.create_thumb', wraps=create_thumb)
@patch('openlp.plugins.images.lib.mediaitem.build_icon', wraps=build_icon)
def test_load_item_valid_thumbnail(mocked_build_icon: MagicMock, mocked_create_thumb: MagicMock,
mocked_validate_thumb: MagicMock, media_item: ImageMediaItem, registry: Registry):
"""Test the load_item method with an existing thumbnail"""
# GIVEN: A media item and an Item to load
media_item.service_path = Path(TEST_RESOURCES_PATH) / 'images'
mocked_validate_thumb.return_value = True
image_path = Path(TEST_RESOURCES_PATH) / 'images' / 'tractor.jpg'
item = MagicMock(file_path=image_path, file_hash=None)
# WHEN load_item() is called with the Item
result = media_item.load_item(item)
# THEN: A QTreeWidgetItem with a "delete" icon should be returned
assert isinstance(result, QtWidgets.QTreeWidgetItem)
assert result.text(0) == 'tractor.jpg'
assert result.toolTip(0) == str(image_path)
mocked_create_thumb.assert_not_called()
mocked_build_icon.assert_called_once_with(image_path)
@patch('openlp.plugins.images.lib.mediaitem.validate_thumb')
@patch('openlp.plugins.images.lib.mediaitem.create_thumb', wraps=create_thumb)
def test_load_item_missing_thumbnail(mocked_create_thumb: MagicMock, mocked_validate_thumb: MagicMock,
media_item: ImageMediaItem, registry: Registry):
"""Test the load_item method with no valid thumbnails"""
# GIVEN: A media item and an Item to load
with TemporaryDirectory() as tmpdir:
media_item.service_path = Path(tmpdir)
mocked_validate_thumb.return_value = False
image_path = Path(TEST_RESOURCES_PATH) / 'images' / 'tractor.jpg'
item = MagicMock(file_path=image_path, file_hash=None)
registry.get('settings').value.return_value = 400
# WHEN load_item() is called with the Item
result = media_item.load_item(item)
# THEN: A QTreeWidgetItem with a "delete" icon should be returned
assert isinstance(result, QtWidgets.QTreeWidgetItem)
assert result.text(0) == 'tractor.jpg'
assert result.toolTip(0) == str(image_path)
mocked_create_thumb.assert_called_once_with(image_path, Path(tmpdir, 'tractor.jpg'), size=QtCore.QSize(-1, 400))

Binary file not shown.

After

Width:  |  Height:  |  Size: 675 KiB