Skip to content
This repository has been archived by the owner on Jul 28, 2020. It is now read-only.

Commit

Permalink
Merge pull request thumbor#578 from Jimdo/clean_up_jpeg_config
Browse files Browse the repository at this point in the history
clean up PILLOW_JPEG-options
  • Loading branch information
masom committed Nov 19, 2015
2 parents 25cb31c + 246ce1c commit c4e51c1
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 19 deletions.
15 changes: 8 additions & 7 deletions thumbor/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,15 @@
Config.define('ALLOWED_SOURCES', [], "Allowed domains for the http loader to download. These are regular expressions.", 'Imaging')
Config.define('QUALITY', 80, 'Quality index used for generated JPEG images', 'Imaging')
Config.define('PROGRESSIVE_JPEG', True, 'Exports JPEG images with the `progressive` flag set.', 'Imaging')

Config.define('PILLOW_JPEG_SUBSAMPLING', None,
'Specify subsampling behavior for Pillow (see `subsampling` in '
'http://pillow.readthedocs.org/en/latest/handbook/image-file-formats.html#jpeg).', 'Imaging')
Config.define(
'PILLOW_COPY_JPEG_SETTINGS',
False,
'If True, use qtables and subsampling from orginal JPG file. Useful if you want to keep jpg quality as identical as '
'possible to original file. Will ignore QUALITY and PILLOW_JPEG_SUBSAMPLING.', 'Imaging')
'Specify subsampling behavior for Pillow (see `subsampling` in http://pillow.readthedocs.org/en/latest/handbook/image-file-formats.html#jpeg). '
'Be careful to use int for 0,1,2 and string for "4:4:4" notation. '
'Will ignore `quality`. Using `keep` will copy the original file\'s subsampling.', 'Imaging')
Config.define('PILLOW_JPEG_QTABLES', None,
'Specify quantization tables for Pillow (see `qtables` in http://pillow.readthedocs.org/en/latest/handbook/image-file-formats.html#jpeg). '
'Will ignore `quality`. Using `keep` will copy the original file\'s qtables.', 'Imaging')

Config.define('WEBP_QUALITY', None, 'Quality index used for generated WebP images. If not set (None) the same level of '
'JPEG quality will be used.', 'Imaging')
Config.define('AUTO_WEBP', False, 'Specifies whether WebP format should be used automatically if the request accepts it '
Expand Down
22 changes: 14 additions & 8 deletions thumbor/engines/pil.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,17 +136,23 @@ def read(self, extension=None, quality=None): # NOQA
self.image = self.image.convert('RGB')
else:

quantization = self.qtables
subsampling = self.subsampling
copy_jpg_settings = self.context.config.PILLOW_COPY_JPEG_SETTINGS
subsampling_config = self.context.config.PILLOW_JPEG_SUBSAMPLING
qtables_config = self.context.config.PILLOW_JPEG_QTABLES

if copy_jpg_settings and (subsampling is not None) and quantization and 2 <= len(quantization) <= 4:
if subsampling_config is not None or qtables_config is not None:
options['quality'] = 0 # can't use 'keep' here as Pillow would try to extract qtables/subsampling and fail
options['qtables'] = quantization
options['subsampling'] = subsampling
orig_subsampling = self.subsampling
orig_qtables = self.qtables

if self.context.config.PILLOW_JPEG_SUBSAMPLING:
options['subsampling'] = int(self.context.config.PILLOW_JPEG_SUBSAMPLING)
if (subsampling_config == 'keep' or subsampling_config is None) and (orig_subsampling is not None):
options['subsampling'] = orig_subsampling
else:
options['subsampling'] = subsampling_config

if (qtables_config == 'keep' or qtables_config is None) and (orig_qtables and 2 <= len(orig_qtables) <= 4):
options['qtables'] = orig_qtables
else:
options['qtables'] = qtables_config

if options['quality'] is None:
options['quality'] = self.context.config.QUALITY
Expand Down
35 changes: 31 additions & 4 deletions vows/pil_engine_vows.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
ctx = Vows.Context

import thumbor.engines.pil as PIL

from os.path import join, abspath, dirname

FIXTURES_FOLDER = join(abspath(dirname(__file__)), 'fixtures')
Expand Down Expand Up @@ -68,13 +69,14 @@ def should_store_subsampling_in_engine(self, engine):
def should_store_quantization_in_engine(self, engine):
expect(len(engine.qtables)).to_equal(2)

class WritingJpegImage(ctx):
class WritingJpegImageWithOriginalJpegSettings(ctx):
def topic(self):
config = Config()
server = ServerParameters(
8889, 'localhost', 'thumbor.conf', None, 'info', None
)
config.PILLOW_COPY_JPEG_SETTINGS = True
config.PILLOW_JPEG_SUBSAMPLING = 'keep'
config.PILLOW_JPEG_QTABLES = 'keep'
context = Context(server, config, Importer(config))

with open("%s/quantization.jpg" % FIXTURES_FOLDER, "rb") as f:
Expand All @@ -86,12 +88,37 @@ def topic(self):

return engine.image

def should_save_with_stored_subsampling_if_quality_is_None(self, image):
def should_save_with_stored_subsampling(self, image):
expect(image.encoderinfo.get('subsampling')).to_equal(0)

def should_save_with_stored_qtables_if_quality_is_None(self, image):
def should_save_with_stored_qtables(self, image):
expect(len(image.encoderinfo.get('qtables'))).to_equal(2)

class WritingJpegImageWithExplicitJpegSettings(ctx):
def topic(self):
config = Config()
server = ServerParameters(
8889, 'localhost', 'thumbor.conf', None, 'info', None
)
config.PILLOW_JPEG_SUBSAMPLING = 2
config.PILLOW_JPEG_QTABLES = 'web_high'
context = Context(server, config, Importer(config))

with open("%s/quantization.jpg" % FIXTURES_FOLDER, "rb") as f:
buffer = f.read()

engine = PIL.Engine(context=context)
engine.load(buffer, '.jpg')
engine.read('.jpg', None)

return engine.image

def should_save_with_explicit_subsampling(self, image):
expect(image.encoderinfo.get('subsampling')).to_equal(2)

def should_save_with_explicit_qtables(self, image):
expect(image.encoderinfo.get('qtables')).to_equal('web_high')

class ResizedPaletteImage(ctx):
def topic(self):
engine = PIL.Engine(None)
Expand Down

0 comments on commit c4e51c1

Please sign in to comment.