Merge pull request #431 from dsschult/huge_image

Add an option to process huge images
This commit is contained in:
Simon Conseil
2021-06-16 22:54:11 +02:00
committed by GitHub
5 changed files with 47 additions and 3 deletions

View File

@@ -15,6 +15,7 @@ alphabetical order):
- Christophe-Marie Duquesne
- Craig Gallek
- @datro
- David Schultz
- David Siroky
- Edward Betts
- Edwin Steele

View File

@@ -619,6 +619,9 @@ class Gallery:
self.init_pool(ncpu)
check_or_create_dir(settings['destination'])
if settings['max_img_pixels']:
PILImage.MAX_IMAGE_PIXELS = settings['max_img_pixels']
# Build the list of directories with images
albums = self.albums = {}
src_path = self.settings['source']
@@ -708,7 +711,11 @@ class Gallery:
self.logger.info("Using %s cores", ncpu)
if ncpu > 1:
self.pool = multiprocessing.Pool(processes=ncpu)
def pool_init():
if self.settings['max_img_pixels']:
PILImage.MAX_IMAGE_PIXELS = self.settings['max_img_pixels']
self.pool = multiprocessing.Pool(processes=ncpu,
initializer=pool_init)
else:
self.pool = None
@@ -756,8 +763,6 @@ class Gallery:
for status in self.pool.imap_unordered(worker, media_list):
result.append(status)
bar.update(1)
self.pool.close()
self.pool.join()
except KeyboardInterrupt:
self.pool.terminate()
sys.exit('Interrupted')
@@ -768,6 +773,9 @@ class Gallery:
"defined in the settings file, which can't be serialized.",
exc_info=True)
sys.exit('Abort')
finally:
self.pool.close()
self.pool.join()
else:
with progressbar(media_list, **bar_opt) as medias:
result = [process_file(media_item) for media_item in medias]

View File

@@ -52,6 +52,7 @@ _DEFAULT_CONFIG = {
'links': '',
'locale': '',
'make_thumbs': True,
'max_img_pixels': None,
'medias_sort_attr': 'filename',
'medias_sort_reverse': False,
'mp4_options': ['-crf', '23', '-strict', '-2'],

View File

@@ -46,6 +46,11 @@ theme = 'galleria'
# Size of resized image (default: (640, 480))
img_size = (800, 600)
# Max input image size in pixels (default: None, i.e. use PIL default)
# This option sets `PIL.Image.MAX_IMAGE_PIXELS` in case you want to
# convert/resize very large images.
# max_img_pixels = None
# Output format of images (default: None, i.e. use input format)
# img_format = "JPEG"

View File

@@ -4,6 +4,7 @@ import os
from os.path import join
import pytest
from PIL import Image as PILImage
from sigal.gallery import Album, Gallery, Image, Media, Video
from sigal.video import SubprocessException
@@ -289,6 +290,34 @@ def test_gallery(settings, tmpdir):
logger.setLevel(logging.INFO)
def test_gallery_max_img_pixels(settings, tmpdir, monkeypatch):
"Test the Gallery class with the max_img_pixels setting."
# monkeypatch is used here to reset the value to the PIL default.
# This value does not matter, other than it is "large"
# to show that settings['max_img_pixels'] works.
monkeypatch.setattr('PIL.Image.MAX_IMAGE_PIXELS', 100_000_000)
with open(str(tmpdir.join('my.css')), mode='w') as f:
f.write('color: red')
settings['destination'] = str(tmpdir)
settings['user_css'] = str(tmpdir.join('my.css'))
settings['max_img_pixels'] = 5000
logger = logging.getLogger('sigal')
logger.setLevel(logging.DEBUG)
try:
with pytest.raises(PILImage.DecompressionBombError):
gal = Gallery(settings, ncpu=1)
gal.build()
settings['max_img_pixels'] = 100_000_000
gal = Gallery(settings, ncpu=1)
gal.build()
finally:
logger.setLevel(logging.INFO)
def test_empty_dirs(settings):
gal = Gallery(settings, ncpu=1)
assert 'empty' not in gal.albums