Recipe11.7.Converting Among Image Formats


Recipe 11.7. Converting Among Image Formats

Credit: Doug Blanding

Problem

Your image files are in various formats (GIF, JPG, PNG, TIF, BMP), and you need to convert among these formats.

Solution

The Python Imaging Library (PIL) can read and write all of these formats; indeed, net of user-interface concerns, image-file format conversion using PIL boils down to a one-liner:

    Image.open(infile).save(outfile)

where filenames infile and outfile have the appropriate file extensions to indicate what kind of images we're reading and writing. We just need to wrap a small GUI around this one-liner functionalityfor example:

#!/usr/bin/env python import os, os.path, sys from Tkinter import * from tkFileDialog import * import Image openfile = '' # full pathname: dir(abs) + root + ext indir = '' outdir = '' def getinfilename( ):     global openfile, indir     ftypes=(('Gif Images', '*.gif'),             ('Jpeg Images', '*.jpg'),             ('Png Images', '*.png'),             ('Tiff Images', '*.tif'),             ('Bitmap Images', '*.bmp'),             ("All files", "*"))     if indir:         openfile = askopenfilename(initialdir=indir, filetypes=ftypes)     else:         openfile = askopenfilename(filetypes=ftypes)     if openfile:         indir = os.path.dirname(openfile) def getoutdirname( ):     global indir, outdir     if openfile:         indir = os.path.dirname(openfile)         outfile = asksaveasfilename(initialdir=indir, initialfile='foo')     else:         outfile = asksaveasfilename(initialfile='foo')     outdir = os.path.dirname(outfile) def save(infile, outfile):     if infile != outfile:         try:             Image.open(infile).save(outfile)         except IOError:             print "Cannot convert", infile def convert( ):     newext = frmt.get( )     path, file = os.path.split(openfile)     base, ext = os.path.splitext(file)     if var.get( ):         ls = os.listdir(indir)         filelist = [  ]         for f in ls:             if os.path.splitext(f)[1] == ext:                 filelist.append(f)     else:         filelist = [file]     for f in filelist:         infile = os.path.join(indir, f)         ofile = os.path.join(outdir, f)         outfile = os.path.splitext(ofile)[0] + newext         save(infile, outfile)     win = Toplevel(root)     Button(win, text='Done', command=win.destroy).pack( ) # Divide GUI into 3 frames: top, mid, bot root = Tk( ) root.title('Image Converter') topframe = Frame(root, borderwidth=2, relief=GROOVE) topframe.pack(padx=2, pady=2) Button(topframe, text='Select image to convert',        command=getinfilename).pack(side=TOP, pady=4) multitext = "Convert all image files\n(of this format) in this folder?" var = IntVar( ) chk = Checkbutton(topframe, text=multitext, variable=var).pack(pady=2) Button(topframe, text='Select save location',        command=getoutdirname).pack(side=BOTTOM, pady=4) midframe = Frame(root, borderwidth=2, relief=GROOVE) midframe.pack(padx=2, pady=2) Label(midframe, text="New Format:").pack(side=LEFT) frmt = StringVar( ) formats = ['.bmp', '.gif', '.jpg', '.png', '.tif'] for item in formats:     Radiobutton(midframe, text=item, variable=frmt, value=item).pack(anchor=NW) botframe = Frame(root) botframe.pack( ) Button(botframe, text='Convert', command=convert).pack(        side=LEFT, padx=5, pady=5) Button(botframe, text='Quit', command=root.quit).pack(        side=RIGHT, padx=5, pady=5) root.mainloop( )

Needing 80 lines of GUI code to wrap a single line of real functionality may be a bit extreme, but it's not all that far out of line in my experience with GUI coding ;-).

Discussion

I needed this tool when I was making .avi files from the CAD application program I generally use. That CAD program emits images in .bmp format, but the AVI[1]-generating program I normally use requires images in .jpg format. Now, thanks to the little script in this recipe (and to the power of Python, Tkinter, and most especially PIL), with a couple of clicks, I get a folder full of images in .jpg format ready to be assembled into an AVI file, or, just as easily, files in .gif ready to be assembled into an animated GIF image file.

[1] AVI (Advanced Visual Interface)

I used to perform this kind of task with simple shell scripts on Unix, using ImageMagick's convert command. But, with this script, I can do exactly the same job just as easily on all sorts of machines, be they Unix, Windows, or Macintosh.

I had to work around one annoying problem to make this script work as I wanted it to. When I'm selecting the location into which a new file is to be written, I need that dialog to give me the option to create a new directory for that purpose. However, on Windows NT, the Browse for Folder dialog doesn't allow me to create a new folder, only to choose among existing ones! My workaround, as you'll see by studying this recipe's Solution, was to use instead the Save As dialog. That dialog does allow me to create a new folder. I do have to indicate the dummy file in that folder, and the file gets ignored; only the directory part is kept. This workaround is not maximally elegant, but it took just a few minutes and almost no work on my part, and I can live with the result.

See Also

Information about Tkinter can be obtained from a variety of sources, such as Fredrik Lundh, An Introduction to Tkinter, (PythonWare: http://www.pythonware.com/library), New Mexico Tech's Tkinter Reference (http://www.nmt.edu/tcc/help/lang/python/docs.html), Python in a Nutshell, and various other books; PIL is at http://www.pythonware.com/products/pil/.



Python Cookbook
Python Cookbook
ISBN: 0596007973
EAN: 2147483647
Year: 2004
Pages: 420

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net