views:

126

answers:

2

I'm building a online font previewer, with following architecture. I wrapped preview creation function in a standalone .py file and making system calls to it in a Django view in order to run them in parallel and maximum performance on multi-core CPU system.

preview.py

....
def make_preview(text, fontfile, imagefile, fontsize=30):
    try:
        font = ImageFont.truetype(fontfile, fontsize)
        text_width, text_height = font.getsize(text)
        img = Image.new('RGBA', (text_width, text_height))
        draw = ImageDraw.Draw(img)
        draw.text((0, 0), text, font=font, fill=(0, 0, 0))
        return True
    except:
        return False
if __name__=='__main__':
    make_preview(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])

views.py

...
def ajax_preview(resquest):
    ttf_file_list = [construct a list of .ttf files]
    image_list = []
    for ttf_file in ttf_file_list:
        image_file = ttf_file.replace('.ttf', '.png')
        image_list.append(image_file)
        subprocess.Popen(['python', 'preview.py', text, ttf_file, image_file, 30)
    return HttpResponse(image_list)

Is it possible to make above code even faster? Maybe there is a better architecture to do this job or any optimization I can do for the code?

+2  A: 

You should look into the multiprocessing module. You could create a pool of workers equal to your number of CPU cores and then send jobs to your make_preview function.

Mark
I agree. Do several in parallel to save time.
steveha
A: 

If this is a font chooser, where you can reasonably display the same text every time you show it, you can pre-render the font samples and save the results as .PNG or .GIF files. (You don't want to use JPEG images because they will make your fonts blurry; JPEGs use lossy compression.)

Then you can make your font chooser a block of pre-rendered HTML that refers to the pre-rendered preview images.

You would only need to re-generate your previews when you install or remove fonts from your system.

steveha
better yet, fonts that don't have a pic yet (or can't be found for some reason) could render as before.
Matthew
@steveha, it's a font chooser but it works by creating preview images for user submitted text dynamically. So save rendered .PNG images for next time use wont help in this case.
jack
@jack, it currently uses text submitted by the user. The question is, can you change it to always show the same text? Because that would provide a huge speedup. As a user, I don't mind if the font chooser doesn't show my text; it could show some sample text. If it has to show the user's text, you can't cache it, and it will be hard to speed up. If you can't cache it, your best bet would be to write a C program that does the whole preview in one step, ideally a multi-threaded C program. But will your users actually care if the preview just says "Sample Text 1234" in each font?
steveha
@steveha, yes, it's a font chooser. it has pre-generated sample text previews but that's not enough. it also has an option to generate dynamic preview using submitted text. because different text may have huge difference in appearance for a same font.
jack