Browse Source

Add option to process huge images

pull/431/head
David Schultz 5 years ago
parent
commit
aa83db8d10
  1. 1
      AUTHORS
  2. 14
      sigal/gallery.py
  3. 1
      sigal/settings.py
  4. 5
      sigal/templates/sigal.conf.py
  5. 26
      tests/test_gallery.py

1
AUTHORS

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

14
sigal/gallery.py

@ -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]

1
sigal/settings.py

@ -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'],

5
sigal/templates/sigal.conf.py

@ -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"

26
tests/test_gallery.py

@ -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,31 @@ 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.setattr('PIL.Image.MAX_IMAGE_PIXELS', 100000000)
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'] = 100000000
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

Loading…
Cancel
Save