SlideShare ist ein Scribd-Unternehmen logo
1 von 25
Downloaden Sie, um offline zu lesen
Random and Dynamic Images
     using Python CGI

                  Steven Kryskalla
               September 14 2005
            skryskalla@gmail.com
              http://lost-theory.org
Overview
•   Intro
•   Simple Python CGI
•   Random Image Script
•   Python’s Graphics Libraries (PIL)
•   Dynamic Image Script
•   Slightly more advanced Python CGI
•   A small surprise…
Intro
• CGI Programming with Python
• Python Graphics Libraries (PIL)

• Goals:
  – Create a random image script
  – Create a dynamic image script
  – Learn about Python’s features as a web
    scripting language
  – Learn a little about Python’s graphics
    capabilities
Simple Python CGI
• Like any other language
• Generate content from scripts

• Python’s built in CGI test server:
  python -c "import CGIHTTPServer;CGIHTTPServer.test()"


• First goal: write a random image script
• First step: redirecting a static image to the
  browser
   – Duplicate the behavior of a normal server
Simple Python CGI
 • Set the Content-type
 • Pipe image to browser:


if __name__ == "__main__":
   print "Content-type: image/pngn"
   print file(r"c:pythonrandom_img1.png", "rb").read()
Simple Python CGI
• What if we are serving multiple file types?
• Lookup the file’s extension to get the content-
  type
                            .png        .png   .jpg     .jpeg     .gif
ext2conttype = {"jpg": "image/jpeg",
                "jpeg": "image/jpeg",
                "png": "image/png",
                "gif": "image/gif"}

def content_type(filename):
        return ext2conttype[filename[filename.rfind(".")+1:].lower()]

if __name__ == "__main__":
        imgpath = r“c:pythonrandom_img3.jpg"
        print "Content-type: %sn“ % (content_type(imgpath))
        print file(imgpath, "rb").read()
Random Image Script
• We can serve up an image file
• We can find the content type of any image

• Pick a random image
  – os.listdir()
  – Filter out the non-images
  – random.choice() on the remaining
    images
Random Image Script
from os import listdir
from random import choice
ext2conttype = {"jpg": "image/jpeg",
                "jpeg": "image/jpeg",
                "png": "image/png",
                "gif": "image/gif"}

def content_type(filename):
       return ext2conttype[filename[filename.rfind(".")+1:].lower()]

def isimage(filename):
       """true if filename's extension is in content-type lookup"""
       filename = filename.lower()
       return filename[filename.rfind(".")+1:] in ext2conttype

def random_file(dir):
       """returns the filename of a randomly chosen image in dir"""
       images = [f for f in listdir(dir) if isimage(f)]
       return choice(images)

if __name__ == "__main__":
       dir = "c:pythonrandom_img“
       r = random_file(dir)
       print "Content-type: %sn" % (content_type(r))
       print file(dir+r, "rb").read()
Random Image Script
• Not that useful…
• Improvements, etc.
  – Serve multiple directories of images
  – Randomly serve other kinds of files
  – Use as a starting point for a dynamic image
    script
Python’s Graphics Libraries
• Many to choose from:
  – PIL
  – Agg
  – Gnuplot
  – ImageMagick
  –…
• PIL
• Is there more interest in this?
PIL
• www.pythonware.com/products/pil
• Docs available on website

• First get acquainted with basic PIL
  functionality
PIL
• Image
• Image objects handle input, output, and
  information about PIL images
• Opening an image:
  – Image.open(filename)
  – Image.open(“test.png”)
• Create a new image:
  – Image.new(mode, size, color)
  – Image.new(“RGB”, (300,300), fill=“#000”)
• Save an image
  – Img.save(filename, format)
  – Img.save(“out.png”, “PNG”)
PIL
• ImageDraw
• Create a draw object:
  – draw = ImageDraw.Draw(img)
• Draw object provides simple 2d graphics
  – draw.line(xy, options)
  – draw.line((0,0,300,300), fill=“#00F”)
  – draw.text(xy, str, options)
  – draw.text((50,50), “Hello World”,
               fill=(50,50,150))
PIL
• Create a dynamic image
  script
• No CGI yet
• Creates a random gradient
PIL
import Image,ImageDraw
from random import randint as rint

def randgradient():
   img = Image.new("RGB", (300,300), "#FFFFFF")
   draw = ImageDraw.Draw(img)

   r,g,b = rint(0,255), rint(0,255), rint(0,255)
   dr = (rint(0,255) - r)/300.
   dg = (rint(0,255) - g)/300.
   db = (rint(0,255) - b)/300.
   for i in range(300):
      r,g,b = r+dr, g+dg, b+db
      draw.line((i,0,i,300), fill=(int(r),int(g),int(b)))
      img.save("img.png", "PNG")

if __name__ == "__main__":
       randgradient()
Dynamic Image Script
• Now add CGI
• Don’t write to a file
• Use cStringIO for a file-like object
import Image,ImageDraw
+ import cStringIO
  from random import randint as rint

    def randgradient():
       img = Image.new("RGB", (300,300), "#FFFFFF")
       draw = ImageDraw.Draw(img)
       r,g,b = rint(0,255), rint(0,255), rint(0,255)
       dr = (rint(0,255) - r)/300.
       dg = (rint(0,255) - g)/300.
       db = (rint(0,255) - b)/300.
       for i in range(300):
          r,g,b = r+dr, g+dg, b+db
          draw.line((i,0,i,300), fill=(int(r),int(g),int(b)))

+      f = cStringIO.StringIO()
+      img.save(f, "PNG")

       print "Content-type: image/pngn"
+      f.seek(0)
       print f.read()

    if __name__ == "__main__":
       randgradient()
Slightly More Advanced CGI
• More useful
  applications of
  dynamic images:
  – CAPTCHAs
  – Resize images for
    web photo gallery
  – Sparklines
  – Dynamic graphs of
    log files
Slightly More Advanced CGI
• Dynamically graph log files
• Accept arguments through the query string
  (from forms, user input, etc.)
• cgi module
  – cgi.FieldStorage()
Slightly More Advanced CGI
• Read values out of the FieldStorage
• If a value is not present we can return an
  error message or use a default value
if __name__ == "__main__":
   form = cgi.FieldStorage()
   if "filename" in form:
      if "color" in form:
         graph(form["filename"].value, form["color"].value)
      else:
         graph(form["filename"].value, "55d")
   else:
      print "Content-type: text/htmln"
      print """<html><body>No input file given</body></html>"""
Slightly More Advanced CGI
• The script is now usable with forms
• Simple form:
   <html>
   <head><title>Graph Log File</title></head>
   <body>

   <br>
   <form action="/cgi-bin/dynimg3.py">
      <input maxlength="100" size="55" name="filename" value="">
      <select name="color">
         <option value="FF3333">Red
         <option value="33FF33">Green
         <option value="3333FF">Blue
         <option value="33AAAA">Teal
      </select>
      <input type="submit" value="Graph!">
   </form>

   </body>
   </html>
Conclusion
• Python’s features make it a great CGI
  language
  – Web frameworks extend its usefulness even
    more
• Solid image & graphics libraries allow for
  quick writing of useful visual output
Questions?
Thank you :]


      Now..


A small surprise..
A logo

Weitere ähnliche Inhalte

Was ist angesagt?

2016 bioinformatics i_python_part_2_strings_wim_vancriekinge
2016 bioinformatics i_python_part_2_strings_wim_vancriekinge2016 bioinformatics i_python_part_2_strings_wim_vancriekinge
2016 bioinformatics i_python_part_2_strings_wim_vancriekingeProf. Wim Van Criekinge
 
Python utan-stodhjul-motorsag
Python utan-stodhjul-motorsagPython utan-stodhjul-motorsag
Python utan-stodhjul-motorsagniklal
 
CoderDojo: Intermediate Python programming course
CoderDojo: Intermediate Python programming courseCoderDojo: Intermediate Python programming course
CoderDojo: Intermediate Python programming courseAlexander Galkin
 
Python 101++: Let's Get Down to Business!
Python 101++: Let's Get Down to Business!Python 101++: Let's Get Down to Business!
Python 101++: Let's Get Down to Business!Paige Bailey
 
Teach your kids how to program with Python and the Raspberry Pi
Teach your kids how to program with Python and the Raspberry PiTeach your kids how to program with Python and the Raspberry Pi
Teach your kids how to program with Python and the Raspberry PiJuan Gomez
 
2016 bioinformatics i_python_part_1_wim_vancriekinge
2016 bioinformatics i_python_part_1_wim_vancriekinge2016 bioinformatics i_python_part_1_wim_vancriekinge
2016 bioinformatics i_python_part_1_wim_vancriekingeProf. Wim Van Criekinge
 
Learn python in 20 minutes
Learn python in 20 minutesLearn python in 20 minutes
Learn python in 20 minutesSidharth Nadhan
 
Python and sysadmin I
Python and sysadmin IPython and sysadmin I
Python and sysadmin IGuixing Bai
 
AmI 2017 - Python basics
AmI 2017 - Python basicsAmI 2017 - Python basics
AmI 2017 - Python basicsLuigi De Russis
 
Odessapy2013 - Graph databases and Python
Odessapy2013 - Graph databases and PythonOdessapy2013 - Graph databases and Python
Odessapy2013 - Graph databases and PythonMax Klymyshyn
 
Overview of Python - Bsides Detroit 2012
Overview of Python - Bsides Detroit 2012Overview of Python - Bsides Detroit 2012
Overview of Python - Bsides Detroit 2012Tazdrumm3r
 
Python Traning presentation
Python Traning presentationPython Traning presentation
Python Traning presentationNimrita Koul
 
Matlab and Python: Basic Operations
Matlab and Python: Basic OperationsMatlab and Python: Basic Operations
Matlab and Python: Basic OperationsWai Nwe Tun
 
Recommender Systems with Ruby (adding machine learning, statistics, etc)
Recommender Systems with Ruby (adding machine learning, statistics, etc)Recommender Systems with Ruby (adding machine learning, statistics, etc)
Recommender Systems with Ruby (adding machine learning, statistics, etc)Marcel Caraciolo
 

Was ist angesagt? (20)

2016 bioinformatics i_python_part_2_strings_wim_vancriekinge
2016 bioinformatics i_python_part_2_strings_wim_vancriekinge2016 bioinformatics i_python_part_2_strings_wim_vancriekinge
2016 bioinformatics i_python_part_2_strings_wim_vancriekinge
 
Python utan-stodhjul-motorsag
Python utan-stodhjul-motorsagPython utan-stodhjul-motorsag
Python utan-stodhjul-motorsag
 
CoderDojo: Intermediate Python programming course
CoderDojo: Intermediate Python programming courseCoderDojo: Intermediate Python programming course
CoderDojo: Intermediate Python programming course
 
Python 101++: Let's Get Down to Business!
Python 101++: Let's Get Down to Business!Python 101++: Let's Get Down to Business!
Python 101++: Let's Get Down to Business!
 
Teach your kids how to program with Python and the Raspberry Pi
Teach your kids how to program with Python and the Raspberry PiTeach your kids how to program with Python and the Raspberry Pi
Teach your kids how to program with Python and the Raspberry Pi
 
2016 bioinformatics i_python_part_1_wim_vancriekinge
2016 bioinformatics i_python_part_1_wim_vancriekinge2016 bioinformatics i_python_part_1_wim_vancriekinge
2016 bioinformatics i_python_part_1_wim_vancriekinge
 
2016 02 23_biological_databases_part2
2016 02 23_biological_databases_part22016 02 23_biological_databases_part2
2016 02 23_biological_databases_part2
 
Learn python in 20 minutes
Learn python in 20 minutesLearn python in 20 minutes
Learn python in 20 minutes
 
Python and sysadmin I
Python and sysadmin IPython and sysadmin I
Python and sysadmin I
 
Python 101 1
Python 101   1Python 101   1
Python 101 1
 
AmI 2017 - Python basics
AmI 2017 - Python basicsAmI 2017 - Python basics
AmI 2017 - Python basics
 
Python Part 1
Python Part 1Python Part 1
Python Part 1
 
Python: The Dynamic!
Python: The Dynamic!Python: The Dynamic!
Python: The Dynamic!
 
Odessapy2013 - Graph databases and Python
Odessapy2013 - Graph databases and PythonOdessapy2013 - Graph databases and Python
Odessapy2013 - Graph databases and Python
 
Overview of Python - Bsides Detroit 2012
Overview of Python - Bsides Detroit 2012Overview of Python - Bsides Detroit 2012
Overview of Python - Bsides Detroit 2012
 
Python Traning presentation
Python Traning presentationPython Traning presentation
Python Traning presentation
 
Matlab and Python: Basic Operations
Matlab and Python: Basic OperationsMatlab and Python: Basic Operations
Matlab and Python: Basic Operations
 
Learning How To Use Jquery #5
Learning How To Use Jquery #5Learning How To Use Jquery #5
Learning How To Use Jquery #5
 
Python Part 2
Python Part 2Python Part 2
Python Part 2
 
Recommender Systems with Ruby (adding machine learning, statistics, etc)
Recommender Systems with Ruby (adding machine learning, statistics, etc)Recommender Systems with Ruby (adding machine learning, statistics, etc)
Recommender Systems with Ruby (adding machine learning, statistics, etc)
 

Ähnlich wie Random And Dynamic Images Using Python Cgi

Working with images in matlab graphics
Working with images in matlab graphicsWorking with images in matlab graphics
Working with images in matlab graphicsmustafa_92
 
Python media library
Python media libraryPython media library
Python media libraryRaginiJain21
 
Azure for SharePoint Developers - Workshop - Part 2: Azure Functions
Azure for SharePoint Developers - Workshop - Part 2: Azure FunctionsAzure for SharePoint Developers - Workshop - Part 2: Azure Functions
Azure for SharePoint Developers - Workshop - Part 2: Azure FunctionsBob German
 
create-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdfcreate-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdfShaiAlmog1
 
The Ring programming language version 1.5.2 book - Part 42 of 181
The Ring programming language version 1.5.2 book - Part 42 of 181The Ring programming language version 1.5.2 book - Part 42 of 181
The Ring programming language version 1.5.2 book - Part 42 of 181Mahmoud Samir Fayed
 
What is image in Swift?/はるふ
What is image in Swift?/はるふWhat is image in Swift?/はるふ
What is image in Swift?/はるふha1f Yamaguchi
 
Gae Meets Django
Gae Meets DjangoGae Meets Django
Gae Meets Djangofool2nd
 
CS101- Introduction to Computing- Lecture 41
CS101- Introduction to Computing- Lecture 41CS101- Introduction to Computing- Lecture 41
CS101- Introduction to Computing- Lecture 41Bilal Ahmed
 
High Performance Images: Beautiful Shouldn't Mean Slow
High Performance Images: Beautiful Shouldn't Mean SlowHigh Performance Images: Beautiful Shouldn't Mean Slow
High Performance Images: Beautiful Shouldn't Mean SlowGuy Podjarny
 
Universal Image Loader: Story, Architecture, FAQ
Universal Image Loader: Story, Architecture, FAQUniversal Image Loader: Story, Architecture, FAQ
Universal Image Loader: Story, Architecture, FAQSergey Tarasevich
 
Scalable Assets Presentation
Scalable Assets PresentationScalable Assets Presentation
Scalable Assets PresentationNigel Barber
 
Stupid Canvas Tricks
Stupid Canvas TricksStupid Canvas Tricks
Stupid Canvas Tricksdeanhudson
 
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014Chris Adamson
 
The Django Book CH13 Generating Non-HTML Content
The Django Book CH13 Generating Non-HTML ContentThe Django Book CH13 Generating Non-HTML Content
The Django Book CH13 Generating Non-HTML ContentJohnny Wang
 
could you draw uml diagram for this code from PIL import Image, Im.pdf
could you draw uml diagram for this code from PIL import Image, Im.pdfcould you draw uml diagram for this code from PIL import Image, Im.pdf
could you draw uml diagram for this code from PIL import Image, Im.pdfmurtuzadahadwala3
 
Python imaging-library-overview - [cuuduongthancong.com]
Python imaging-library-overview - [cuuduongthancong.com]Python imaging-library-overview - [cuuduongthancong.com]
Python imaging-library-overview - [cuuduongthancong.com]Dinh Sinh Mai
 

Ähnlich wie Random And Dynamic Images Using Python Cgi (20)

Working with images in matlab graphics
Working with images in matlab graphicsWorking with images in matlab graphics
Working with images in matlab graphics
 
Python media library
Python media libraryPython media library
Python media library
 
Dip syntax 4
Dip syntax 4Dip syntax 4
Dip syntax 4
 
Azure for SharePoint Developers - Workshop - Part 2: Azure Functions
Azure for SharePoint Developers - Workshop - Part 2: Azure FunctionsAzure for SharePoint Developers - Workshop - Part 2: Azure Functions
Azure for SharePoint Developers - Workshop - Part 2: Azure Functions
 
Work With Images
Work With ImagesWork With Images
Work With Images
 
create-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdfcreate-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdf
 
The Ring programming language version 1.5.2 book - Part 42 of 181
The Ring programming language version 1.5.2 book - Part 42 of 181The Ring programming language version 1.5.2 book - Part 42 of 181
The Ring programming language version 1.5.2 book - Part 42 of 181
 
What is image in Swift?/はるふ
What is image in Swift?/はるふWhat is image in Swift?/はるふ
What is image in Swift?/はるふ
 
Bitmap management like a boss
Bitmap management like a bossBitmap management like a boss
Bitmap management like a boss
 
Gae Meets Django
Gae Meets DjangoGae Meets Django
Gae Meets Django
 
CS101- Introduction to Computing- Lecture 41
CS101- Introduction to Computing- Lecture 41CS101- Introduction to Computing- Lecture 41
CS101- Introduction to Computing- Lecture 41
 
High Performance Images: Beautiful Shouldn't Mean Slow
High Performance Images: Beautiful Shouldn't Mean SlowHigh Performance Images: Beautiful Shouldn't Mean Slow
High Performance Images: Beautiful Shouldn't Mean Slow
 
Universal Image Loader: Story, Architecture, FAQ
Universal Image Loader: Story, Architecture, FAQUniversal Image Loader: Story, Architecture, FAQ
Universal Image Loader: Story, Architecture, FAQ
 
Scalable Assets Presentation
Scalable Assets PresentationScalable Assets Presentation
Scalable Assets Presentation
 
Drawing images
Drawing imagesDrawing images
Drawing images
 
Stupid Canvas Tricks
Stupid Canvas TricksStupid Canvas Tricks
Stupid Canvas Tricks
 
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014
 
The Django Book CH13 Generating Non-HTML Content
The Django Book CH13 Generating Non-HTML ContentThe Django Book CH13 Generating Non-HTML Content
The Django Book CH13 Generating Non-HTML Content
 
could you draw uml diagram for this code from PIL import Image, Im.pdf
could you draw uml diagram for this code from PIL import Image, Im.pdfcould you draw uml diagram for this code from PIL import Image, Im.pdf
could you draw uml diagram for this code from PIL import Image, Im.pdf
 
Python imaging-library-overview - [cuuduongthancong.com]
Python imaging-library-overview - [cuuduongthancong.com]Python imaging-library-overview - [cuuduongthancong.com]
Python imaging-library-overview - [cuuduongthancong.com]
 

Mehr von AkramWaseem

Mseduebookexcitinglearningweb Final 120914022330 Phpapp02
Mseduebookexcitinglearningweb Final 120914022330 Phpapp02Mseduebookexcitinglearningweb Final 120914022330 Phpapp02
Mseduebookexcitinglearningweb Final 120914022330 Phpapp02AkramWaseem
 
Xml Messaging With Soap
Xml Messaging With SoapXml Messaging With Soap
Xml Messaging With SoapAkramWaseem
 
Html5 Cheat Sheet
Html5 Cheat SheetHtml5 Cheat Sheet
Html5 Cheat SheetAkramWaseem
 
Ajax Tags Advanced
Ajax Tags AdvancedAjax Tags Advanced
Ajax Tags AdvancedAkramWaseem
 
Ascii Table Characters
Ascii Table CharactersAscii Table Characters
Ascii Table CharactersAkramWaseem
 
Www Kitebird Com Articles Pydbapi Html Toc 1
Www Kitebird Com Articles Pydbapi Html Toc 1Www Kitebird Com Articles Pydbapi Html Toc 1
Www Kitebird Com Articles Pydbapi Html Toc 1AkramWaseem
 
Scripts Python Dbapi
Scripts Python DbapiScripts Python Dbapi
Scripts Python DbapiAkramWaseem
 
Python And My Sq Ldb Module
Python And My Sq Ldb ModulePython And My Sq Ldb Module
Python And My Sq Ldb ModuleAkramWaseem
 
Internet Programming With Python Presentation
Internet Programming With Python PresentationInternet Programming With Python Presentation
Internet Programming With Python PresentationAkramWaseem
 
Docs Python Org Howto Webservers Html
Docs Python Org Howto Webservers HtmlDocs Python Org Howto Webservers Html
Docs Python Org Howto Webservers HtmlAkramWaseem
 

Mehr von AkramWaseem (20)

Mseduebookexcitinglearningweb Final 120914022330 Phpapp02
Mseduebookexcitinglearningweb Final 120914022330 Phpapp02Mseduebookexcitinglearningweb Final 120914022330 Phpapp02
Mseduebookexcitinglearningweb Final 120914022330 Phpapp02
 
Xml Messaging With Soap
Xml Messaging With SoapXml Messaging With Soap
Xml Messaging With Soap
 
Xhtml Basics
Xhtml BasicsXhtml Basics
Xhtml Basics
 
Uml Tutorial
Uml TutorialUml Tutorial
Uml Tutorial
 
Xhtml Basics
Xhtml BasicsXhtml Basics
Xhtml Basics
 
Html5 Cheat Sheet
Html5 Cheat SheetHtml5 Cheat Sheet
Html5 Cheat Sheet
 
Ajax Tags Advanced
Ajax Tags AdvancedAjax Tags Advanced
Ajax Tags Advanced
 
Ascii Table Characters
Ascii Table CharactersAscii Table Characters
Ascii Table Characters
 
Www Kitebird Com Articles Pydbapi Html Toc 1
Www Kitebird Com Articles Pydbapi Html Toc 1Www Kitebird Com Articles Pydbapi Html Toc 1
Www Kitebird Com Articles Pydbapi Html Toc 1
 
Scripts Python Dbapi
Scripts Python DbapiScripts Python Dbapi
Scripts Python Dbapi
 
Python And My Sq Ldb Module
Python And My Sq Ldb ModulePython And My Sq Ldb Module
Python And My Sq Ldb Module
 
Pydbapi
PydbapiPydbapi
Pydbapi
 
My Sq Ldb Tut
My Sq Ldb TutMy Sq Ldb Tut
My Sq Ldb Tut
 
Internet Programming With Python Presentation
Internet Programming With Python PresentationInternet Programming With Python Presentation
Internet Programming With Python Presentation
 
Cgi
CgiCgi
Cgi
 
Docs Python Org Howto Webservers Html
Docs Python Org Howto Webservers HtmlDocs Python Org Howto Webservers Html
Docs Python Org Howto Webservers Html
 
Handson Python
Handson PythonHandson Python
Handson Python
 
Python Tutorial
Python TutorialPython Tutorial
Python Tutorial
 
Python 3 Days
Python  3 DaysPython  3 Days
Python 3 Days
 
Tutorial Python
Tutorial PythonTutorial Python
Tutorial Python
 

Random And Dynamic Images Using Python Cgi

  • 1. Random and Dynamic Images using Python CGI Steven Kryskalla September 14 2005 skryskalla@gmail.com http://lost-theory.org
  • 2. Overview • Intro • Simple Python CGI • Random Image Script • Python’s Graphics Libraries (PIL) • Dynamic Image Script • Slightly more advanced Python CGI • A small surprise…
  • 3. Intro • CGI Programming with Python • Python Graphics Libraries (PIL) • Goals: – Create a random image script – Create a dynamic image script – Learn about Python’s features as a web scripting language – Learn a little about Python’s graphics capabilities
  • 4. Simple Python CGI • Like any other language • Generate content from scripts • Python’s built in CGI test server: python -c "import CGIHTTPServer;CGIHTTPServer.test()" • First goal: write a random image script • First step: redirecting a static image to the browser – Duplicate the behavior of a normal server
  • 5. Simple Python CGI • Set the Content-type • Pipe image to browser: if __name__ == "__main__": print "Content-type: image/pngn" print file(r"c:pythonrandom_img1.png", "rb").read()
  • 6. Simple Python CGI • What if we are serving multiple file types? • Lookup the file’s extension to get the content- type .png .png .jpg .jpeg .gif ext2conttype = {"jpg": "image/jpeg", "jpeg": "image/jpeg", "png": "image/png", "gif": "image/gif"} def content_type(filename): return ext2conttype[filename[filename.rfind(".")+1:].lower()] if __name__ == "__main__": imgpath = r“c:pythonrandom_img3.jpg" print "Content-type: %sn“ % (content_type(imgpath)) print file(imgpath, "rb").read()
  • 7. Random Image Script • We can serve up an image file • We can find the content type of any image • Pick a random image – os.listdir() – Filter out the non-images – random.choice() on the remaining images
  • 8. Random Image Script from os import listdir from random import choice ext2conttype = {"jpg": "image/jpeg", "jpeg": "image/jpeg", "png": "image/png", "gif": "image/gif"} def content_type(filename): return ext2conttype[filename[filename.rfind(".")+1:].lower()] def isimage(filename): """true if filename's extension is in content-type lookup""" filename = filename.lower() return filename[filename.rfind(".")+1:] in ext2conttype def random_file(dir): """returns the filename of a randomly chosen image in dir""" images = [f for f in listdir(dir) if isimage(f)] return choice(images) if __name__ == "__main__": dir = "c:pythonrandom_img“ r = random_file(dir) print "Content-type: %sn" % (content_type(r)) print file(dir+r, "rb").read()
  • 9. Random Image Script • Not that useful… • Improvements, etc. – Serve multiple directories of images – Randomly serve other kinds of files – Use as a starting point for a dynamic image script
  • 10. Python’s Graphics Libraries • Many to choose from: – PIL – Agg – Gnuplot – ImageMagick –… • PIL • Is there more interest in this?
  • 11. PIL • www.pythonware.com/products/pil • Docs available on website • First get acquainted with basic PIL functionality
  • 12. PIL • Image • Image objects handle input, output, and information about PIL images • Opening an image: – Image.open(filename) – Image.open(“test.png”) • Create a new image: – Image.new(mode, size, color) – Image.new(“RGB”, (300,300), fill=“#000”) • Save an image – Img.save(filename, format) – Img.save(“out.png”, “PNG”)
  • 13. PIL • ImageDraw • Create a draw object: – draw = ImageDraw.Draw(img) • Draw object provides simple 2d graphics – draw.line(xy, options) – draw.line((0,0,300,300), fill=“#00F”) – draw.text(xy, str, options) – draw.text((50,50), “Hello World”, fill=(50,50,150))
  • 14. PIL • Create a dynamic image script • No CGI yet • Creates a random gradient
  • 15. PIL import Image,ImageDraw from random import randint as rint def randgradient(): img = Image.new("RGB", (300,300), "#FFFFFF") draw = ImageDraw.Draw(img) r,g,b = rint(0,255), rint(0,255), rint(0,255) dr = (rint(0,255) - r)/300. dg = (rint(0,255) - g)/300. db = (rint(0,255) - b)/300. for i in range(300): r,g,b = r+dr, g+dg, b+db draw.line((i,0,i,300), fill=(int(r),int(g),int(b))) img.save("img.png", "PNG") if __name__ == "__main__": randgradient()
  • 16. Dynamic Image Script • Now add CGI • Don’t write to a file • Use cStringIO for a file-like object
  • 17. import Image,ImageDraw + import cStringIO from random import randint as rint def randgradient(): img = Image.new("RGB", (300,300), "#FFFFFF") draw = ImageDraw.Draw(img) r,g,b = rint(0,255), rint(0,255), rint(0,255) dr = (rint(0,255) - r)/300. dg = (rint(0,255) - g)/300. db = (rint(0,255) - b)/300. for i in range(300): r,g,b = r+dr, g+dg, b+db draw.line((i,0,i,300), fill=(int(r),int(g),int(b))) + f = cStringIO.StringIO() + img.save(f, "PNG") print "Content-type: image/pngn" + f.seek(0) print f.read() if __name__ == "__main__": randgradient()
  • 18. Slightly More Advanced CGI • More useful applications of dynamic images: – CAPTCHAs – Resize images for web photo gallery – Sparklines – Dynamic graphs of log files
  • 19. Slightly More Advanced CGI • Dynamically graph log files • Accept arguments through the query string (from forms, user input, etc.) • cgi module – cgi.FieldStorage()
  • 20. Slightly More Advanced CGI • Read values out of the FieldStorage • If a value is not present we can return an error message or use a default value if __name__ == "__main__": form = cgi.FieldStorage() if "filename" in form: if "color" in form: graph(form["filename"].value, form["color"].value) else: graph(form["filename"].value, "55d") else: print "Content-type: text/htmln" print """<html><body>No input file given</body></html>"""
  • 21. Slightly More Advanced CGI • The script is now usable with forms • Simple form: <html> <head><title>Graph Log File</title></head> <body> <br> <form action="/cgi-bin/dynimg3.py"> <input maxlength="100" size="55" name="filename" value=""> <select name="color"> <option value="FF3333">Red <option value="33FF33">Green <option value="3333FF">Blue <option value="33AAAA">Teal </select> <input type="submit" value="Graph!"> </form> </body> </html>
  • 22. Conclusion • Python’s features make it a great CGI language – Web frameworks extend its usefulness even more • Solid image & graphics libraries allow for quick writing of useful visual output
  • 24. Thank you :] Now.. A small surprise..