By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,480 Members | 1,164 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,480 IT Pros & Developers. It's quick & easy.

Dynamic image creation for the web...

P: n/a
Hi,

I would like to create images on the fly as a response to an http request.
I can do this with PIL like this (file create_gif.py):
from PIL import Image, ImageDraw

print 'Status: 200 OK'
print 'Content-type: text/html'
print
print '<HTML><HEAD><TITLE>Python Dynamic Image Creation Test</TITLE></HEAD>'
print '<BODY>'
im = Image.new("P", (600, 400))
draw = ImageDraw.Draw(im)
draw.rectangle((0, 0) + im.size, fill="blue")
im.save("images/tmp.gif");
print '<img src="/scripts/images/tmp.gif">'
print '</BODY>'
However, I would like to 1) avoid saving the image in a file on disk and
2) separate the HTLM code from the python image creation code.

Something like this is what I have in mind:
(file index.html):
<html>
<head><meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8">
<title>Python Dynamic Image Creation</title>
</head>
<IMG SRC="/scripts/create_image.py" ALT="Image created on the fly...">
</html>

and in file create_image.py:
from PIL import Image, ImageDraw, ImageFont
im = Image.new("P", (600, 400))
draw = ImageDraw.Draw(im)
draw.rectangle((0, 0) + im.size, fill="blue")
Unfortunately this does not work :-(
What is missing?

Thanks in advance!
/Tompa
Aug 28 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Tompa wrote:
Hi,

I would like to create images on the fly as a response to an http request.
I can do this with PIL like this (file create_gif.py):
from PIL import Image, ImageDraw

print 'Status: 200 OK'
print 'Content-type: text/html'
print
print '<HTML><HEAD><TITLE>Python Dynamic Image Creation
Test</TITLE></HEAD>' print '<BODY>'
im = Image.new("P", (600, 400))
draw = ImageDraw.Draw(im)
draw.rectangle((0, 0) + im.size, fill="blue")
im.save("images/tmp.gif");
print '<img src="/scripts/images/tmp.gif">'
print '</BODY>'
However, I would like to 1) avoid saving the image in a file on disk and
2) separate the HTLM code from the python image creation code.

Something like this is what I have in mind:
(file index.html):
<html>
<head><meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8">
<title>Python Dynamic Image Creation</title>
</head>
<IMG SRC="/scripts/create_image.py" ALT="Image created on the fly...">
</html>

and in file create_image.py:
from PIL import Image, ImageDraw, ImageFont
im = Image.new("P", (600, 400))
draw = ImageDraw.Draw(im)
draw.rectangle((0, 0) + im.size, fill="blue")
Unfortunately this does not work :-(
What is missing?


You are almost there. Your create_image.py does not return anything to the
browser yet.

First return proper HTTP headers, e.g.

sys.stdout.write('Status: 200 OK\r\n')
sys.stdout.write('Content-type: image/gif\r\n')
sys.stdout.write('\r\n')

(Your prints above are mostly equivalent, but do not output the correct \r\n
as line terminator - at least on UNIX style systems. Most webservers
tolarate this, if it's coming from a CGI - but doing it right and not
relying on a certain server behaviour is not bad anyway ;)

Then check the PIL docs to find out, how to output the image to sys.stdout
(instead of writing to a file).

--
Benjamin Niemann
Email: pink at odahoda dot de
WWW: http://www.odahoda.de/
Aug 28 '05 #2

P: n/a
Tompa <to*******@yahoo.com> wrote in
news:ma************************************@python .org:
Hi,

I would like to create images on the fly as a response to an http
request. I can do this with PIL like this (file create_gif.py):
from PIL import Image, ImageDraw


check out sparklines:

http://bitworking.org/projects/sparklines/

It is a script very similar to what you want to do.

The difference between your script and sparklines is mostly that it
sends:

print "Content-type: image/png"

instead of:

print 'Content-type: text/html'
max
Aug 28 '05 #3

P: n/a
Benjamin Niemann <pink <at> odahoda.de> writes:
You are almost there. I don't feel so...
Your create_image.py does not return anything to the
browser yet. Yes, I am aware of that but I do not what to return.
First return proper HTTP headers, e.g.

sys.stdout.write('Status: 200 OK\r\n')
sys.stdout.write('Content-type: image/gif\r\n')
sys.stdout.write('\r\n')
Ok, but if possible I'd rather not return anything HTTP/HTML-related from my
create_image.py file.
Then check the PIL docs to find out, how to output the image to sys.stdout
(instead of writing to a file).

Ok, then I get this:

from PIL import Image, ImageDraw
import sys

im = Image.new("P", (600, 400))
draw = ImageDraw.Draw(im)
draw.rectangle((0, 0) + im.size, fill="blue")

sys.stdout.write('Status: 200 OK\r\n')
sys.stdout.write('Content-type: image/gif\r\n')
sys.stdout.write('\r\n')

im.save(sys.stdout, "GIF")

But this does not work.
I also tested to skip the HTTP-header stuff and just write the gif to
sys.stdout, believing that that would work. But not so...

Hmm, I'm a newbie to Python (as you already probably have noticed ;-) so I
don't know what else I should try. Any hints are welcome!

/Tompa
Aug 28 '05 #4

P: n/a
Max Erickson <maxerickson <at> gmail.com> writes:

check out sparklines:

http://bitworking.org/projects/sparklines/

It is a script very similar to what you want to do.


This sure looks interesting! Strange that I couldn't find this when I googled
for this kind of stuff...
I will check it out - thanks!

Regards,
/Tompa
Aug 28 '05 #5

P: n/a
Tompa wrote:
Benjamin Niemann <pink <at> odahoda.de> writes:
You are almost there. I don't feel so...
Your create_image.py does not return anything to the
browser yet.

Yes, I am aware of that but I do not what to return.
First return proper HTTP headers, e.g.

sys.stdout.write('Status: 200 OK\r\n')
sys.stdout.write('Content-type: image/gif\r\n')
sys.stdout.write('\r\n')


Ok, but if possible I'd rather not return anything HTTP/HTML-related from
my create_image.py file.


When the browser fetches the images for displaying, it performs just another
HTTP request, and you must reply with a valid HTTP response. The
Content-type header is the absolute minimum that must always be returned.
(IIRC the 'Status' can be omitted, if it's 200).
Then check the PIL docs to find out, how to output the image to
sys.stdout (instead of writing to a file).

Ok, then I get this:

from PIL import Image, ImageDraw
import sys

im = Image.new("P", (600, 400))
draw = ImageDraw.Draw(im)
draw.rectangle((0, 0) + im.size, fill="blue")

sys.stdout.write('Status: 200 OK\r\n')
sys.stdout.write('Content-type: image/gif\r\n')
sys.stdout.write('\r\n')

im.save(sys.stdout, "GIF")

But this does not work.
I also tested to skip the HTTP-header stuff and just write the gif to
sys.stdout, believing that that would work. But not so...


Works perfectly here...
What does the error.log of the webserver say?
Hmm, I'm a newbie to Python (as you already probably have noticed ;-) so I
don't know what else I should try. Any hints are welcome!

/Tompa


--
Benjamin Niemann
Email: pink at odahoda dot de
WWW: http://www.odahoda.de/
Aug 28 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.