MongoEngine/mongoengine

Image Field put() silently compresses jpg images

janmueck opened this issue · 2 comments

The put() method of the ImageGridFsProxy opens and saves images before storing them to gridfs.
During saving of the image, as Image.save() is used without keyword arguments the default behavior for .jpg is a quality value of 75, as per Pillow documentation .
This leads to saving a significantly changed (compressed/ reduced quality compressed) version of the image. In my specific case this divides file-size by more than 4 and reduces the image quality visibly which I don't imagine is expected or mentioned anywhere.
I think this issue can be (relatively) easily sidestepped by duplicating the file before the Pillow operations and not saving with pillow at all but I might be missing something.

Bypassing Pillow does not sound like a great idea, I'm not very familiar with the ImageField but I guess Pillow is there for a reason, what we could do instead is adding an option on the ImageFIeld constructor, something like
ImageField(jpeg_quality=95) or alternatively through the **kwargs of the ImageGridFsProxy.put()

And then propagate that whenever we save through Pillow

Yeah I overlooked the setting of the size for the "original" image and thought it was just there to create the image thumbnail.
In this case **kwargs for ImageGridFsProxy makes a lot of sense to me although ImageField options would likely be a little easier to use I imagine being able to pass a **kwargs dict to put() that just gets passed along to Image.save() would allow more varied usage without requiring much work on the mongoengine side.