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.
This commit is contained in:
Brett Smith 2012-03-17 23:43:46 -04:00
parent 416b439fc8
commit 063670e9b4

View File

@ -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 :)