Image on demand view
I often post photos on photography fora. Most fora want you to place a link to a photo somewhere on the net, but different fora have different rules. Some fora want you to stick to a maximum of 800 pixels wide, some 700 pixel and some even strange values like 639 pixels. My own site uses 600 pixels so I end up resizing images all the time. Since I keep my originals with my gallery as well (hidden for public viewing) resizing on the fly would be a nice asset.
I'm using my previous snippet to apply a slight unsharp mask for better web display of my photos.
usage This snippet takes the url to my photo application which is a simple link using the pk of my photo table and adds 'width'.jpg to the end (some fora check if the link is an image based on extenstion)
The view takes the width requested and creates the resized image from the original full size image or takes it from the cache for display on demand. To prevent a dozen directories I use a setting to specify which widths are allowed, providing room for several versions of the same image.
Any improvements are appreciated since I'm still rather inexperienced in Python and Django.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | ## put these in your settings.py ##
import os.path
#image on demand settings, writable path by webserver
IMAGE_ON_DEMAND_DIR = os.path.join(MEDIA_ROOT,'image_on_demand/')
#image widths allowed
ALLOWED_WIDTHS=('600','639','700','800')
#usm settings for thumbnails, optional if you use my unsharp mask snippet
RADIUS=1
SIGMA=0.5
AMOUNT=0.8
THRESHOLD=0.016
#################
## urls.py ##
# this is what I have in my urls.py file
# object_id is contains the primary key of my photo database table, 'width' is the width of the
# image wanted
# to the public the URL looks like pointing to a real picture :http://your.domain/photo/36/600.jpg
(r'^photo/(?P<object_id>\d+)/(?P<width>\d+).jpg$', 'gallery.views.image_on_demand'),
## inside views.py of my gallery app ##
def image_on_demand(request,object_id,width):
if width in settings.ALLOWED_WIDTHS:
#get photo
photo=Photo.objects.get(pk=object_id)
#path to original image and file split
original_file=os.path.join(settings.MEDIA_ROOT,photo.image_orig.name)
filehead, filetail = os.path.split(original_file)
#check if image path exists otherwise create it
image_path=os.path.join(settings.IMAGE_ON_DEMAND_DIR,width)
if not os.path.exists(image_path):
os.mkdir(image_path)
#create image path. note, width SHOULD be a string otherwise os.path.join fails
image_file=os.path.join(settings.IMAGE_ON_DEMAND_DIR,width,filetail)
# we need te calculate the new height based on the ratio of the original image, create integers
ratio=float(float(photo.image_orig.width) / float(photo.image_orig.height))
height=int(float(width)/ratio)
width=int(width)
# check if file exists and the original file hasn't updated in between
if os.path.exists(image_file) and os.path.getmtime(original_file)>os.path.getmtime(image_file):
os.unlink(image_file)
# if the image wasn't already resized, resize it.Maybe I should rewrite it to do this directly with PythonMagick
# taken from snippet http://www.djangosnippets.org/snippets/453/
if not os.path.exists(image_file):
image = Image.open(original_file)
#assert False
image.thumbnail([width, height], Image.ANTIALIAS)
format=image.format # preserve the format as it is lost in the USM step
#optional unsharp mask using snippet http://www.djangosnippets.org/snippets/1267/
#image = usm(image,settings.RADIUS,settings.SIGMA,settings.AMOUNT,settings.THRESHOLD)
try:
image.save(image_file, format, quality=90, optimize=1)
except:
image.save(image_file, format, quality=90)
image_data = Image.open(image_file)
response = HttpResponse(mimetype="image/%s"%image_data.format) # create the proper HttpResponse object
try:
image_data.save(response, image_data.format, quality=90, optimize=1)
except:
image_data.save(response, image_data.format, quality=90)
return response
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 1 week ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
Please login first before commenting.