It’s A Hard Knock Resolution-Independent Life - Or: How To Losslessly get Path Information out of Adobe Photoshop

After about spending 10 effective hours getting a SnapBack arrow path out of Photoshop (no, not Illustrator, because I regularly don’t need it), I have a few tips for myself and for others:

  • Do not write an AppleScript at 2AM to kinda-sorta generate NSBezierPath incantations from Photoshop’s vended data - it will turn out reasonably useless because the incantations will not generate the exact correct path but instead somehow fudge the curves, something you do not want to particularly investigate further.
  • Do not write a test application having text boxes bound to the individual x or y point values of the destination or control points of the curve parts of the paths based on what you got from the previous step in some sort of attempt to fix the essentially almost-there data. You will mess around for a few minutes and then sob violently.
  • Do not extend the test application from the previous step with steppers (up-down controls). You will mess around for another three minutes and acquire a strong urge to hit yourself in the head with a spade.
  • Do draw the shape in a new Photoshop document, Save As as a “Photoshop EPS”, preserve vector data, open this EPS document up in the competent text editor of your choice, search for newpath in this wondrous file, grab everything from that point until closepath, copy and paste it into a new text document and then follow these instructions to acquire a functional line of NSBezierPath incantations (this is script-like grunt work but can be performed by hand; I do not have a script to hand out at this time):

    1. Start from the top. Ignore the newpath line.
    2. For each line that doesn’t say closepath:
      • If the line ends with an m and holds two floating-point values, write [bp moveToPath:NSMakePoint(X,Y)]; where X is the first floating-point value and Y is the second.
      • If the line ends with an l and holds two floating-point values, write [bp lineToPath:NSMakePoint(X,Y)]; where X is the first floating-point value and Y is the second.
      • If the line ends with a v and holds four floating-point values, write [bp curveToPath:NSMakePoint(X,Y) controlPoint1:NSMakePoint(X1,Y1) controlPoint2:NSMakePoint(X2,Y2)]; where X and Y are the last two floating-point values, X1 and Y1 are the floating-point values you last wrote out as part of an earlier X,Y instruction in a previous step (the ‘current point’, as it were) and X2 and Y2 are the first two floating-point values.
      • If the line ends with a y and holds four floating-point values, write [bp curveToPath:NSMakePoint(X,Y) controlPoint1:NSMakePoint(X1,Y1) controlPoint2:NSMakePoint(X,Y)]; where X and Y are the first two floating-point values and X1 and Y1 are the last two floating-point values.
      • If the line ends with a c and holds six floating-point values, write [bp curveToPath:NSMakePoint(X,Y) controlPoint1:NSMakePoint(X1,Y1) controlPoint2:NSMakePoint(X2,Y2)]; where X and Y are the last two floating-point values, X1 and Y1 are the first two floating-point values and X2 and Y2 are the two middle floating-point values.
    3. You’re done. Add to this only an initialization of a new NSBezierPath at the top (NSBezierPath *bp = [[NSBezierPath alloc] init];) and any drawing instructions on the bottom.

So. You may get the impression that I’m taking this “resolution-independent” thing seriously. You may be right.

Comments [+]

  1. I tried doing this once with the built-in ActionScript crap in CS3 and eventually gave up and used a completely different solution. However, that was for doing hit detection on an unusual shape, and I needed an actual path to do the hit detection on. Why isn’t simply using a PDF and an NSImage good enough for you?

    By ryan · 2007.07.18 02:52

  2. Don’t forget the closepath ([bp closePath]).

    By Peter Hosey · 2007.07.18 03:55

  3. Peter - that’s not necessary. I said to add drawing commands, and both stroke and fill implicitly close the path.

    Ryan - yes, I guess I could have used PDFs (if I could get Photoshop to reliably output a transparent PDF, because I’ve had issues with that in the past), but I also saw it as a challenge to actually get the vector data out of Photoshop. I had drawn a shape (plotted a path of the SnapBack arrow against Apple’s largest such image) and I was really confused that I couldn’t just export it as a normal PostScript path directly (just the path, and without those macro methods, just using curveto directly).

    By Jesper · 2007.07.18 09:46

Leave a comment

Your e-mail address is never shown. If you type a line break in the comment, it will show up as a line break (naturally). The following HTML is allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

(required)

(required)


Please note: Your comment will not show up at once. Unless you're spamming or being abusive, you have nothing to worry about. (Read the full policy.)