Sigal PNG -> JPEG conversion is broken (with fix?)
shuhaowu opened this issue · comments
This is a part of series of bugs that I've discovered while making a somewhat complex gallery with sigal.
This issue pertains to PNG -> JPEG conversion. The example can be see in this repo.
So I have a gallery of PNG files with this config file:
title = "Test Gallery"
source = "gallery"
theme = "photoswipe"
img_format = "JPEG"
img_size = (3000, 2000)
keep_orig = True
jpg_options = {
'quality': 90,
'optimize': True,
'progressive': True,
}
plugins = [
# "PIL.PngImagePlugin",
# "PIL.JpegImagePlugin",
]
When I try to build, this happens
Collecting albums /Traceback (most recent call last):
File "/home/shuhao/.local/bin/sigal", line 8, in <module>
sys.exit(main())
File "/usr/lib/python3/dist-packages/click/core.py", line 1128, in __call__
return self.main(*args, **kwargs)
File "/usr/lib/python3/dist-packages/click/core.py", line 1053, in main
rv = self.invoke(ctx)
File "/usr/lib/python3/dist-packages/click/core.py", line 1659, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/usr/lib/python3/dist-packages/click/core.py", line 1395, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/lib/python3/dist-packages/click/core.py", line 754, in invoke
return __callback(*args, **kwargs)
File "/home/shuhao/.local/lib/python3.10/site-packages/sigal/__init__.py", line 173, in build
gal = Gallery(settings, ncpu=ncpu, quiet=quiet)
File "/home/shuhao/.local/lib/python3.10/site-packages/sigal/gallery.py", line 743, in __init__
album = Album(relpath, settings, dirs, files, self)
File "/home/shuhao/.local/lib/python3.10/site-packages/sigal/gallery.py", line 395, in __init__
media = Image(f, self.path, settings)
File "/home/shuhao/.local/lib/python3.10/site-packages/sigal/gallery.py", line 238, in __init__
if imgformat and PILImage.EXTENSION[self.src_ext] != imgformat.upper():
KeyError: '.png'
Looking at PILImage.EXTENSION
shows an empty dictionary. This is because the PIL plugins needed (PIL.PngImagePlugin
, PIL.JpegImagePlugin
), are dynamically loaded, and since sigal starts immediately accessing, it can't find the extension. As a result, the code is broken.
There's a work around, which is to put the two modules above in the plugins
setting for sigal:
plugins = [
"PIL.PngImagePlugin",
"PIL.JpegImagePlugin",
]
Although the plugin import will fail due to the lack of the register
function, it will import those modules correctly and thus allow the build and conversion to proceed normally. I tried importing these directly in the sigal.conf.py, but the import is probably in the wrong order, which means sigal fails later with strange pickling related errors (multiprocessing?).
Not sure what the proper fix is as I'm not super familiar with the sigal code, but preloading the PIL modules are required.
Hmm that's weird, not sure when Pillow's behavior changed. Calling PIL.Image.init()
seems to fix the issue (PIL.Image.open
calls it anyway) so I will add that.