From 063670e9b42c94bb6c4cf5c2838ab67a62349822 Mon Sep 17 00:00:00 2001 From: Brett Smith Date: Sat, 17 Mar 2012 23:43:46 -0400 Subject: [PATCH] Refactor image resize code, with better filenames (#261) The code to make thumbnail- and medium-sized images in processing.py is pretty similar, so I rolled that out into a separate function that we call with different arguments as appropriate. The new function should work identically to the old code, except it saves images with filenames based on the original filename, like `foobar.medium.jpg` instead of just `medium.jpg`. This fixes bug #261. --- mediagoblin/media_types/image/processing.py | 89 +++++++++++---------- 1 file changed, 48 insertions(+), 41 deletions(-) diff --git a/mediagoblin/media_types/image/processing.py b/mediagoblin/media_types/image/processing.py index 6ba91a15..2a00606a 100644 --- a/mediagoblin/media_types/image/processing.py +++ b/mediagoblin/media_types/image/processing.py @@ -23,6 +23,46 @@ from mediagoblin.processing import BadMediaFail, \ from mediagoblin.tools.exif import exif_fix_image_orientation, \ extract_exif, clean_exif, get_gps_data, get_useful +MAX_FILENAME_LENGTH = 255 # the limit in VFAT -- seems like a good baseline + +def resize_image(entry, filename, basename, file_tail, exif_tags, workdir, + new_size, size_limits=None): + """Store a resized version of an image and return its pathname. + + Arguments: + entry -- the entry for the image to resize + filename -- the filename of the original image being resized + basename -- simple basename of the given filename + file_tail -- ending string and extension for the resized filename + exif_tags -- EXIF data for the original image + workdir -- directory path for storing converted image files + new_size -- 2-tuple size for the resized image + size_limits (optional) -- image is only resized if it exceeds this size + + """ + try: + resized = Image.open(filename) + except IOError: + raise BadMediaFail() + resized = exif_fix_image_orientation(resized, exif_tags) # Fix orientation + + if ((size_limits is None) or + (resized.size[0] > size_limits[0]) or + (resized.size[1] > size_limits[1])): + resized.thumbnail(new_size, Image.ANTIALIAS) + + resized_filename = (basename[:MAX_FILENAME_LENGTH - len(file_tail)] + + file_tail) + resized_filepath = create_pub_filepath(entry, resized_filename) + + # Copy the new file to the conversion subdir, then remotely. + tmp_resized_filename = os.path.join(workdir, resized_filename) + with file(tmp_resized_filename, 'w') as resized_file: + resized.save(resized_file) + mgg.public_store.copy_local_to_storage( + tmp_resized_filename, resized_filepath) + return resized_filepath + def process_image(entry): """ Code to process an image @@ -46,50 +86,17 @@ def process_image(entry): exif_tags = extract_exif(queued_filename) gps_data = get_gps_data(exif_tags) - try: - thumb = Image.open(queued_filename) - except IOError: - raise BadMediaFail() - - thumb = exif_fix_image_orientation(thumb, exif_tags) - - thumb.thumbnail(THUMB_SIZE, Image.ANTIALIAS) - - # Copy the thumb to the conversion subdir, then remotely. - thumb_filename = 'thumbnail' + extension - thumb_filepath = create_pub_filepath(entry, thumb_filename) - - tmp_thumb_filename = os.path.join( - conversions_subdir, thumb_filename) - - with file(tmp_thumb_filename, 'w') as thumb_file: - thumb.save(thumb_file) - - mgg.public_store.copy_local_to_storage( - tmp_thumb_filename, thumb_filepath) + # Always create a small thumbnail + thumb_filepath = resize_image(entry, queued_filename, basename, + '.thumbnail' + extension, exif_tags, + conversions_subdir, THUMB_SIZE) # If the size of the original file exceeds the specified size of a `medium` - # file, a `medium.jpg` files is created and later associated with the media + # file, a `.medium.jpg` files is created and later associated with the media # entry. - medium = Image.open(queued_filename) - - # Fix orientation - medium = exif_fix_image_orientation(medium, exif_tags) - - if medium.size[0] > MEDIUM_SIZE[0] or medium.size[1] > MEDIUM_SIZE[1]: - medium.thumbnail(MEDIUM_SIZE, Image.ANTIALIAS) - - medium_filename = 'medium' + extension - medium_filepath = create_pub_filepath(entry, medium_filename) - - tmp_medium_filename = os.path.join( - conversions_subdir, medium_filename) - - with file(tmp_medium_filename, 'w') as medium_file: - medium.save(medium_file) - - mgg.public_store.copy_local_to_storage( - tmp_medium_filename, medium_filepath) + medium_filepath = resize_image(entry, queued_filename, basename, + '.medium' + extension, exif_tags, + conversions_subdir, MEDIUM_SIZE, MEDIUM_SIZE) # we have to re-read because unlike PIL, not everything reads # things in string representation :) -- 2.25.1