Dynamic image creation for the web...

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Tompa

    #1

    Dynamic image creation for the web...

    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><T ITLE>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


  • Benjamin Niemann

    #2
    Re: Dynamic image creation for the web...

    Tompa wrote:
    [color=blue]
    > 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><T ITLE>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?[/color]

    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.writ e('Status: 200 OK\r\n')
    sys.stdout.writ e('Content-type: image/gif\r\n')
    sys.stdout.writ e('\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/

    Comment

    • Max Erickson

      #3
      Re: Dynamic image creation for the web...

      Tompa <tompa1969@yaho o.com> wrote in
      news:mailman.86 .1125225066.822 9.python-list@python.org :
      [color=blue]
      > 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
      >[/color]

      check out sparklines:

      Joe Gregorio - REST, Web, Go, APIs, Dad, Husband, Maker, or any linear combination of such. Googler.


      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

      Comment

      • Tompa

        #4
        Re: Dynamic image creation for the web...

        Benjamin Niemann <pink <at> odahoda.de> writes:[color=blue]
        > You are almost there.[/color]
        I don't feel so...
        [color=blue]
        > Your create_image.py does not return anything to the
        > browser yet.[/color]
        Yes, I am aware of that but I do not what to return.
        [color=blue]
        > First return proper HTTP headers, e.g.
        >
        > sys.stdout.writ e('Status: 200 OK\r\n')
        > sys.stdout.writ e('Content-type: image/gif\r\n')
        > sys.stdout.writ e('\r\n')[/color]

        Ok, but if possible I'd rather not return anything HTTP/HTML-related from my
        create_image.py file.
        [color=blue]
        > Then check the PIL docs to find out, how to output the image to sys.stdout
        > (instead of writing to a file).
        >[/color]
        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.writ e('Status: 200 OK\r\n')
        sys.stdout.writ e('Content-type: image/gif\r\n')
        sys.stdout.writ e('\r\n')

        im.save(sys.std out, "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


        Comment

        • Tompa

          #5
          Re: Dynamic image creation for the web...

          Max Erickson <maxerickson <at> gmail.com> writes:[color=blue]
          >
          > check out sparklines:
          >
          > http://bitworking.org/projects/sparklines/
          >
          > It is a script very similar to what you want to do.[/color]

          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


          Comment

          • Benjamin Niemann

            #6
            Re: Dynamic image creation for the web...

            Tompa wrote:
            [color=blue]
            > Benjamin Niemann <pink <at> odahoda.de> writes:[color=green]
            >> You are almost there.[/color]
            > I don't feel so...
            >[color=green]
            >> Your create_image.py does not return anything to the
            >> browser yet.[/color]
            > Yes, I am aware of that but I do not what to return.
            >[color=green]
            >> First return proper HTTP headers, e.g.
            >>
            >> sys.stdout.writ e('Status: 200 OK\r\n')
            >> sys.stdout.writ e('Content-type: image/gif\r\n')
            >> sys.stdout.writ e('\r\n')[/color]
            >
            > Ok, but if possible I'd rather not return anything HTTP/HTML-related from
            > my create_image.py file.[/color]

            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).
            [color=blue][color=green]
            >> Then check the PIL docs to find out, how to output the image to
            >> sys.stdout (instead of writing to a file).
            >>[/color]
            > 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.writ e('Status: 200 OK\r\n')
            > sys.stdout.writ e('Content-type: image/gif\r\n')
            > sys.stdout.writ e('\r\n')
            >
            > im.save(sys.std out, "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...[/color]

            Works perfectly here...
            What does the error.log of the webserver say?
            [color=blue]
            > 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[/color]

            --
            Benjamin Niemann
            Email: pink at odahoda dot de
            WWW: http://www.odahoda.de/

            Comment

            Working...