I've learned. I'll share.

February 1, 2008

The Easy Way to Print Flash Cards (with Python and ImageMagick)

Here's a valued lessons that I learned the long and hard way: how to easily print flash cards. Don't waste any time doing it the hard way like I did. Follow my easy route and save yourself some time.

The other day, my wife had a very simple computer need: print and cut pictures into little uniform cards, like flash cards with pictures. It sounds like a simple problem, but there's a simple way and an easy way, and I'd like to share with you the easy way.

The simple way is what she did: use some software like Scribus (in her case) or Microsoft Word (if she were almost anyone else), copy the pictures in, manually align them, and print. That works great ... until you try and do 700 pictures (about 80 pages of 9 pictures per page). Scribus ate all of the computer's memory, the hard drive thrashed like mad, everything slowed down, and my poor wife spent hours putting it all together. I doubt Word would have fared much better.

But it still wasn't over. When she tried to print, the printer printed out one page with "error" on it. So, we exported to a PDF, and tried printing that: "error" again. So, we tried to print one page at a time: after about 5 minutes, it printed. All I could figure was that something bad was going on between the computer and the printer and involving sending these images uncompressed.

At this point, I decided that it was time to call it quits on manual work and use automated work: write a program to do this for me. I'm not about to manually tell 78 pages to individually print. So, with some quick bash command line work, I told it to print each page by itself. That worked for a few pages, but some were still too big and we got the dreaded "error".

Finally, I decdied to really role up my sleeves and write a program like we should have in the first place: in go pictures, out comes a PDF, and your print the PDF. Additionally, I wanted like to control the DPI of the images used to control the data flow to the printer. I did so, made the PDF, printed it and (after a while, still), it printed. Hurray! Even better, now if we wanted to change pictures or change sizes, we'll be able to do it with very little work.

So here's the program. Put some pictures in a directory, run the program, and print the pdf of "flash cards" or "image thumbnails" or "reading lessons" or whatever you want to call them. You could even make this into an Automator task in Mac OS X. It uses ImageMagick, though, so make sure you have that installed first.

from subprocess import call

MONTAGE = ["montage", "-bordercolor", "white"]
CONVERT = ["convert", "-bordercolor", "white"]

def montage_files_of_paths(paths, name,
                           columns =  3, rows    = 3,
                           width   = 10, height  = 8, xborder = .33, yborder = .33, density = 200,
                           frame   = 5,  spacing = 10,                                            
                           intermediate_ext = "png", final_ext = "pdf"):

    width, height, xborder, yborder = (int(val * density) for val in (width, height, xborder, yborder))
    thumbnail_width  = int((width  - (xborder * 2)) / columns)
    thumbnail_height = int((height - (yborder * 2)) / rows)  

    call(MONTAGE + ["-tile",     "%rx%r" % (rows, columns),
                    "-geometry", "%rx%r+%r+%r" % (thumbnail_width, thumbnail_height, spacing, spacing),
                    "-frame",    str(frame),
                    "-density",  str(density)]
                 + [path + "[0]" for path in paths] #[0] to ignore animated GIFS
                 + [name + "." + intermediate_ext])
    call(CONVERT + ["-border",   "%rx%r" % (xborder, yborder),
                    "-density",  str(density),
                    "-annotate", "0x0+%r+%r" % (xborder, yborder), name,
                    name + "*." + intermediate_ext,
                    name + "."  + final_ext])

import sys

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print "usage: %s image_directory, image_directory, image_directory ..." % (sys.argv[0],)
        for dirname in sys.argv[1:]:
            montage_files_of_paths([dirname+"/*"], dirname)

1 comment:

  1. Công ty vận tải hàng hóa chuyên nhận vận chuyển nội địa tốt nhất hiện nay. Hãy đến với chúng tôi sanvanchuyen.vn bạn sẽ được tận hưởng những dịch vụ vận chuyển tốt nhất hiện nay. Có thể kể đến dịch vụ vận chuyển hàng hóa bắc nam giá rẻ, vận chuyển hàng đông lạnh, vận chuyển hàng tươi sống, vận chuyển hàng đi Sài Gòn, vận chuyển hàng hóa đi Hà Nội... Và còn rất nhiều dịch vụ đang chờ đón bạn. Nếu như bạn có thắc mắc hay cần sử dụng hãy liên hệ với chúng tôi nhé.


Blog Archive

Google Analytics