- December 29, 2008
- resize pil pythonmagick image
- 0 (after 0 ratings)
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