-
Notifications
You must be signed in to change notification settings - Fork 28
Open
Description
I have observed this behavior on both the demo app in the README and also the example in examples/flask (using python 3.8.X or so).
when processing a PNG (seemingly, ones that support transparency, which is probably most PNGs that exist), using an ImageProcessor
that is set for fmt="jpeg"
, PIL is complaining that it doesnt know how to handle this without losing the transparency data.
when this happens a stack trace like this is printed:
Traceback (most recent call last):
File "/home/ace/.local/share/virtualenvs/flask-OlzCv1Bp/lib/python3.8/site-packages/PIL/JpegImagePlugin.py", line 630, in _save
rawmode = RAWMODE[im.mode]
KeyError: 'RGBA'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/ace/.local/share/virtualenvs/flask-OlzCv1Bp/lib/python3.8/site-packages/flask/app.py", line 2525, in wsgi_app
response = self.full_dispatch_request()
File "/home/ace/.local/share/virtualenvs/flask-OlzCv1Bp/lib/python3.8/site-packages/flask/app.py", line 1822, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/ace/.local/share/virtualenvs/flask-OlzCv1Bp/lib/python3.8/site-packages/flask/app.py", line 1820, in full_dispatch_request
rv = self.dispatch_request()
File "/home/ace/.local/share/virtualenvs/flask-OlzCv1Bp/lib/python3.8/site-packages/flask/app.py", line 1796, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
File "./flask_sam.py", line 105, in index
new_person = Person(name=request.form['name'], avatar=request.files['avatar'])
File "<string>", line 4, in __init__
File "/home/ace/.local/share/virtualenvs/flask-OlzCv1Bp/lib/python3.8/site-packages/sqlalchemy/orm/state.py", line 576, in _initialize_instance
manager.dispatch.init_failure(self, args, kwargs)
File "/home/ace/.local/share/virtualenvs/flask-OlzCv1Bp/lib/python3.8/site-packages/sqlalchemy/util/langhelpers.py", line 148, in __exit__
raise exc_value.with_traceback(exc_tb)
File "/home/ace/.local/share/virtualenvs/flask-OlzCv1Bp/lib/python3.8/site-packages/sqlalchemy/orm/state.py", line 573, in _initialize_instance
manager.original_init(*mixed[1:], **kwargs)
File "/home/ace/.local/share/virtualenvs/flask-OlzCv1Bp/lib/python3.8/site-packages/sqlalchemy/orm/decl_base.py", line 1947, in _declarative_constructor
setattr(self, k, kwargs[k])
File "/home/ace/.local/share/virtualenvs/flask-OlzCv1Bp/lib/python3.8/site-packages/sqlalchemy/orm/attributes.py", line 531, in __set__
self.impl.set(
File "/home/ace/.local/share/virtualenvs/flask-OlzCv1Bp/lib/python3.8/site-packages/sqlalchemy/orm/attributes.py", line 1264, in set
value = self.fire_replace_event(
File "/home/ace/.local/share/virtualenvs/flask-OlzCv1Bp/lib/python3.8/site-packages/sqlalchemy/orm/attributes.py", line 1279, in fire_replace_event
value = fn(
File "/home/ace/.local/share/virtualenvs/flask-OlzCv1Bp/lib/python3.8/site-packages/sqlalchemy/orm/events.py", line 2348, in wrap
return fn(target, *arg)
File "/home/ace/.local/share/virtualenvs/flask-OlzCv1Bp/lib/python3.8/site-packages/sqlalchemy/ext/mutable.py", line 536, in set_
value = cls.coerce(key, value)
File "/home/ace/.local/share/virtualenvs/flask-OlzCv1Bp/lib/python3.8/site-packages/sqlalchemy_media/attachments.py", line 97, in coerce
return cls.create_from(*value)
File "/home/ace/.local/share/virtualenvs/flask-OlzCv1Bp/lib/python3.8/site-packages/sqlalchemy_media/attachments.py", line 115, in create_from
return instance.attach(*args, **kwargs)
File "/home/ace/.local/share/virtualenvs/flask-OlzCv1Bp/lib/python3.8/site-packages/sqlalchemy_media/attachments.py", line 724, in attach
return super().attach(*args, **kwargs)
File "/home/ace/.local/share/virtualenvs/flask-OlzCv1Bp/lib/python3.8/site-packages/sqlalchemy_media/attachments.py", line 424, in attach
processor.process(descriptor, attachment_info)
File "/home/ace/.local/share/virtualenvs/flask-OlzCv1Bp/lib/python3.8/site-packages/sqlalchemy_media/processors.py", line 335, in process
img.save(output_buffer, format=format_)
File "/home/ace/.local/share/virtualenvs/flask-OlzCv1Bp/lib/python3.8/site-packages/PIL/Image.py", line 2353, in save
save_handler(self, fp, filename)
File "/home/ace/.local/share/virtualenvs/flask-OlzCv1Bp/lib/python3.8/site-packages/PIL/JpegImagePlugin.py", line 632, in _save
raise OSError(f"cannot write mode {im.mode} as JPEG") from e
OSError: cannot write mode RGBA as JPEG
the best/easiest workaround seems to be to remove the fmt
parameter from the instantiation of ImageProcessor
. This will keep the existing format of whatever image is uploaded by the user (assuming it wasn't rejected by the validation).
Longer term it may be better to either:
- catch this exception and throw something more informative to the user to tell them that, for example, a non-jpeg was uploaded to an image processor that they specified as jpeg and that they should either remove this, or change their validator to catch it sooner
- allow the
ImageProcessor
to handle conversion to that format (seems like there may be a bug with this, potentially related to changes in pillow). This seems to have been the initially intended behavior
Metadata
Metadata
Assignees
Labels
No labels