Merge pull request #30 from matze/adjust-images-after-resizing

Adjust images after resizing
This commit is contained in:
Simon Conseil
2013-08-08 11:02:08 -07:00
7 changed files with 55 additions and 31 deletions

View File

@@ -289,15 +289,12 @@ def process_image(filepath, outpath, settings):
if settings['keep_orig']:
shutil.copy(filepath, join(outpath, settings['orig_dir'], filename))
sigal.image.generate_image(
filepath, outname, settings['img_size'], None, options=options,
copyright_text=settings['copyright'], method=settings['img_processor'],
copy_exif_data=settings['copy_exif_data'])
sigal.image.generate_image(filepath, outname, settings, options=options)
if settings['make_thumbs']:
thumb_name = join(outpath, get_thumb(settings, filename))
sigal.image.generate_thumbnail(
outname, thumb_name, settings['thumb_size'], None,
outname, thumb_name, settings['thumb_size'],
fit=settings['thumb_fit'], options=options)

View File

@@ -27,14 +27,16 @@ import sys
from PIL import Image as PILImage
from PIL import ImageDraw, ImageOps
from PIL.ExifTags import TAGS
from pilkit.processors import Transpose
from pilkit.processors import Transpose, Adjust
from pilkit.utils import save_image
from datetime import datetime
def generate_image(source, outname, size, format, options=None,
autoconvert=True, copyright_text='', method='ResizeToFit',
copy_exif_data=True):
def _has_exif_tags(img):
return hasattr(img, 'info') and 'exif' in img.info
def generate_image(source, outname, settings, options=None):
"""Image processor, rotate and resize the image.
:param source: path to an image
@@ -47,7 +49,7 @@ def generate_image(source, outname, size, format, options=None,
original_format = img.format
# Preserve EXIF data
if copy_exif_data and hasattr(img, 'info') and 'exif' in img.info:
if settings['copy_exif_data'] and _has_exif_tags(img):
options = options or {}
options['exif'] = img.info['exif']
@@ -58,6 +60,8 @@ def generate_image(source, outname, size, format, options=None,
pass
# Resize the image
method = settings['img_processor']
try:
logger.debug('Processor: %s', method)
processor_cls = getattr(pilkit.processors, method)
@@ -65,18 +69,21 @@ def generate_image(source, outname, size, format, options=None,
logger.error('Wrong processor name: %s', method)
sys.exit()
processor = processor_cls(*size, upscale=False)
processor = processor_cls(*settings['img_size'], upscale=False)
img = processor.process(img)
if copyright_text:
add_copyright(img, copyright_text)
# Adjust the image after resizing
img = Adjust(**settings['adjust_options']).process(img)
format = format or img.format or original_format or 'JPEG'
logger.debug(u'Save resized image to {0} ({1})'.format(outname, format))
save_image(img, outname, format, options=options, autoconvert=autoconvert)
if settings['copyright']:
add_copyright(img, settings['copyright'])
outformat = img.format or original_format or 'JPEG'
logger.debug(u'Save resized image to {0} ({1})'.format(outname, outformat))
save_image(img, outname, outformat, options=options, autoconvert=True)
def generate_thumbnail(source, outname, box, format, fit=True, options=None):
def generate_thumbnail(source, outname, box, fit=True, options=None):
"Create a thumbnail image"
logger = logging.getLogger(__name__)
@@ -88,9 +95,9 @@ def generate_thumbnail(source, outname, box, format, fit=True, options=None):
else:
img.thumbnail(box, PILImage.ANTIALIAS)
format = format or img.format or original_format or 'JPEG'
logger.debug(u'Save thumnail image to {0} ({1})'.format(outname, format))
save_image(img, outname, format, options=options, autoconvert=True)
outformat = img.format or original_format or 'JPEG'
logger.debug(u'Save thumnail image to {0} ({1})'.format(outname, outformat))
save_image(img, outname, outformat, options=options, autoconvert=True)
def add_copyright(img, text):

View File

@@ -29,6 +29,8 @@ _DEFAULT_CONFIG = {
'destination': '_build',
'img_size': (640, 480),
'img_processor': 'ResizeToFit',
'adjust_options': {'color': 1.0, 'brightness': 1.0,
'contrast': 1.0, 'sharpness': 1.0},
'make_thumbs': True,
'thumb_prefix': '',
'thumb_suffix': '',
@@ -119,3 +121,10 @@ def read_settings(filename=None):
"largest value first.", key)
return settings
def create_settings(**kwargs):
"""Create a new default setting copy and initialize it with kwargs."""
settings = _DEFAULT_CONFIG.copy()
settings.update(kwargs)
return settings

View File

@@ -26,6 +26,13 @@ img_size = (800, 600)
# - SmartResize: identical to ResizeToFill, but uses entropy to crop the image
# img_processor = 'ResizeToFit'
# Adjust the image after resizing it. A default value of 1.0 leaves the images
# untouched.
# adjust_options = {'color': 1.0,
# 'brightness': 1.0,
# 'contrast': 1.0,
# 'sharpness': 1.0}
# Generate thumbnails
# make_thumbs = True

View File

@@ -86,7 +86,7 @@ def generate_video(source, outname, size, options={}):
stderr=devnull)
def generate_thumbnail(source, outname, box, format, fit=True, options=None):
def generate_thumbnail(source, outname, box, fit=True, options=None):
"Create a thumbnail image"
# 1) dump an image of the video
tmpfile = outname + ".tmp.jpg"
@@ -94,6 +94,6 @@ def generate_thumbnail(source, outname, box, format, fit=True, options=None):
subprocess.call(['ffmpeg', '-i', source, '-an', '-r', '1',
'-vframes', '1', '-y', tmpfile], stderr=devnull)
# 2) use the generate_thumbnail function from sigal.image
sigal.image.generate_thumbnail(tmpfile, outname, box, format, fit, options)
sigal.image.generate_thumbnail(tmpfile, outname, box, fit, options)
# 3) remove the image
os.unlink(tmpfile)

View File

@@ -181,11 +181,11 @@ class Writer(object):
if ext in self.settings['img_ext_list']:
sigal.image.generate_thumbnail(
source, thumb_path, self.settings['thumb_size'],
None, fit=self.settings['thumb_fit'])
fit=self.settings['thumb_fit'])
else:
sigal.video.generate_thumbnail(
source, thumb_path, self.settings['thumb_size'],
None, fit=self.settings['thumb_fit'])
fit=self.settings['thumb_fit'])
ctx['albums'].append({
'url': d + '/' + self.url_ext,

View File

@@ -6,6 +6,7 @@ from PIL import Image
from sigal import init_logging
from sigal.image import generate_image, generate_thumbnail, get_exif_tags
from sigal.settings import create_settings
CURRENT_DIR = os.path.dirname(__file__)
TEST_IMAGE = 'exo20101028-b-full.jpg'
@@ -17,7 +18,8 @@ def test_generate_image(tmpdir):
dstfile = str(tmpdir.join(TEST_IMAGE))
for size in [(600, 600), (300, 200)]:
generate_image(SRCFILE, dstfile, size, None, method='ResizeToFill')
settings = create_settings(img_size=size, img_processor='ResizeToFill')
generate_image(SRCFILE, dstfile, settings)
im = Image.open(dstfile)
assert im.size == size
@@ -28,8 +30,8 @@ def test_generate_image_processor(tmpdir):
init_logging()
dstfile = str(tmpdir.join(TEST_IMAGE))
with pytest.raises(SystemExit):
generate_image(SRCFILE, dstfile, (200, 200), None,
method='WrongMethod')
settings = create_settings(img_size=(200, 200), img_processor='WrongMethod')
generate_image(SRCFILE, dstfile, settings)
def test_generate_thumbnail(tmpdir):
@@ -37,13 +39,13 @@ def test_generate_thumbnail(tmpdir):
dstfile = str(tmpdir.join(TEST_IMAGE))
for size in [(200, 150), (150, 200)]:
generate_thumbnail(SRCFILE, dstfile, size, None)
generate_thumbnail(SRCFILE, dstfile, size)
im = Image.open(dstfile)
assert im.size == size
for size, thumb_size in [((200, 150), (185, 150)),
((150, 200), (150, 122))]:
generate_thumbnail(SRCFILE, dstfile, size, None, fit=False)
generate_thumbnail(SRCFILE, dstfile, size, fit=False)
im = Image.open(dstfile)
assert im.size == thumb_size
@@ -56,11 +58,13 @@ def test_exif_copy(tmpdir):
test_image)
dst_file = str(tmpdir.join(test_image))
generate_image(src_file, dst_file, (300, 400), None, copy_exif_data=True)
settings = create_settings(img_size=(300, 400), copy_exif_data=True)
generate_image(src_file, dst_file, settings)
raw, simple = get_exif_tags(dst_file)
assert simple['iso'] == 50
generate_image(src_file, dst_file, (300, 400), None, copy_exif_data=False)
settings['copy_exif_data'] = False
generate_image(src_file, dst_file, settings)
raw, simple = get_exif_tags(dst_file)
assert not raw
assert not simple