Login

Image resize on demand

Author:
VidJa
Posted:
December 29, 2008
Language:
Python
Version:
1.0
Score:
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	
	

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 3 months, 1 week ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 3 months, 2 weeks ago
  3. Serializer factory with Django Rest Framework by julio 10 months, 1 week ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 11 months ago
  5. Help text hyperlinks by sa2812 11 months, 3 weeks ago

Comments

Please login first before commenting.