Scrawls from Preston...

Powered by Pelican.

Thu 04 June 2009

Saving time (and wrists) scripting Illustrator

Sometimes doing tedious layout work in Illustrator is both time consuming and hard on the wrists. In this post I show a quick example of how one can script Illustrator very effectively

I work at a school where I'm involved in putting together our yearbook. For several years now we have done a collage of self portraits.

These can be a chore to layout in Illustrator. You want to randomize the grades, scale everything to be in nice rows and line everything up.

Here is what I started with:

![Picture 46](http://ptone.com/dablog/wp-content/uploads/2009/06/picture-46.png)

Each grade is a different layer (and highlight color)

Its hard to know what size to standardize on to flow these out best onto the cover layout (its a front and back deal)

Also I don't want all of one grade next to another, so they need some shuffling.

So I whipped up this python script to do the grunt work for me.

_quick digression on scripting language_

Note I could have done this in Applescript - and for most of you that would be easier to use. I think that for quick scripts where the bulk of the script is generating apple events - Applescript is generally easier. But as soon as you involve much general programming, Applescript is sorely lacking. It has an awkward and verbose syntax, and has a very limited standard library - so you often have to write all your own utilities. [appscript](http://appscript.sourceforge.net/py-appscript/) is a Python module that provides access to Apples OSA system and allows you to do anything you can do in Applescript. The syntax takes some getting used to, but if you need to do other things in your script - its a win. For example the "Shuffle" bit in the code below was a single line of python, but would have required a PITA sub-routine in Applescript.

#!/usr/bin/env python# encoding: utf-8"""Created by Preston Holmes on 2009-06-04."""import sysimport osimport appscriptimport randomimport timedef main():    il = appscript.app("Adobe Illustrator")    page_items = il.current_document.page_items()    random_index = range(len(page_items))    random.shuffle(random_index)    left_edge = 15    curr_x = left_edge    curr_y = 775    x_max = 600    row_height = 80    print len(random_index)    for i in random_index:        item = page_items[i]        if item.locked() or item.layer.locked():            continue        h = item.height()        w = item.width()        if h == 0 or w ==0:            continue        s = int ((row_height/h) * 100)        # s2 = row_height/h        if (curr_x + w) > x_max:            curr_x = left_edge            curr_y = curr_y - row_height        sm = il.get_scale_matrix(horizontal_scale=s,vertical_scale=s)        # Having some real problems with scale transforms screwing up stroke width - but I'm just working with placed items        il.transform(item,using=sm,line_scale=100,transforming_stroke_patterns=False)        # item.stroked_width.set(1)        # alternate scale approach (also seems to affect stroke width...)        # item.width.set(w*s2)        # item.height.set(h*s2)        left,top,right,bottom = item.geometric_bounds()        dx = curr_x - left        dy = curr_y - top        m = il.get_translation_matrix(delta_x=dx,delta_y=dy)        # can't use concatenated transform as scale will change the amount to move...        # full_m = il.concatenate_scale_matrix(m,horizontal_scale=s,vertical_scale=s)        il.transform(item,using=m)        curr_x = curr_x + (right - left)    if __name__ == '__main__': main()

So what does this get me?

![Picture 47](http://ptone.com/dablog/wp-content/uploads/2009/06/picture-47.png)

I made this to generate one page width - and its easy to split up across pages:

![Picture 48](http://ptone.com/dablog/wp-content/uploads/2009/06/picture-48.png)

And as you can see, it also shuffled the source layers:

![Picture 49](http://ptone.com/dablog/wp-content/uploads/2009/06/picture-49.png)

Now if I want to change how it flows - or add or subtract images I can just change the single row_height parameter of the script and get variations like this:

![Picture 50](http://ptone.com/dablog/wp-content/uploads/2009/06/picture-50.png)

![Picture 51](http://ptone.com/dablog/wp-content/uploads/2009/06/picture-51.png)

If you realize an image needs 90 degree rotation, it no longer requires having to entirely re-layout the whole project

Of course there is still some massaging needed by hand - but it is a fraction of the effort.


http://ptone.com/dablog