Last Updated: February 25, 2016
· chadoh

batch convert PNGs to SVGs using bash and copy to new location

You need imagemagick for the convert command, and potrace for the potrace command. Both can probably be installed via your trusty package installer (homebrew on OSX, for example).

This assumes that the original PNGs have only two colors: transparent and white. The resulting SVGs will be transparent & black, but that's easy to change within the resulting SVG files themselves.

Without further ado:

for f in *_shape.png; do convert $f -fill black -opaque white -alpha off $(echo $f | sed 's/\.png$/.pnm/') && potrace $(echo $f | sed 's/\.png$/.pnm/') -s -o $(echo $f | sed 's/\.png$/.svg/') && cp $(echo $f | sed 's/\.png$/.svg/g') my/new/folder/; done

Whoa that looks like a lot. Quick breakdown:

Batch copy files to a new location:

for f in *_shape.png; do cp $f my/new/folder/; done

Convert a single PNG to an SVG:

convert pic.png -fill black -opaque white -alpha off pic.pnm && potrace pic.pnm -s -o pic.svg

Ok, this part's tricky. You need to first convert it to the intermediary filetype of "PNM", because potrace can work with those but not PNGs.

And let's explain that -fill black -opaque white -alpha off part: this all comes from imagemagick, as part of its convert command. It says "fill the opaque white parts with black and turn off the transparency". Which will result in a transparent & white photo being white & black.

So convert pic.png -fill black -opaque white -alpha off pic.pnm is an imagemagick command to turn a transparent & white PNG into a white & black PNM.

Which is exactly the sort of image file that potrace can turn into an SVG. Which is what the next part of this command does: potrace pic.pnm -s -o pic.svg.

batch convert PNGs to SVGs:

for f in *_shape.png; do convert $f -fill black -opaque white -alpha off $(echo $f | sed 's/\.png$/.pnm/') && potrace $(echo $f | sed 's/\.png$/.pnm/') -s -o $(echo $f | sed 's/\.png$/.svg/'); done

Ok, if you ignore all the parts in $(...), this is actually pretty similar to the command to convert one PNG to an SVG. It's just wrapped in a for f in ...; do ...; done.

Those $(...) parts are there because we don't know the exact filename anymore, but we need to change it. You could bulk rename files this same way to make them all match a new pattern.

Here's an explanation:

$(echo $f | sed 's/\.png$/.pnm/')

sed is a command-line editing tool. You could, if you were so inclined, use it instead of vim or Sublime Text to edit your source code.

Let's take this piece by piece:

  • echo $f – print whatever $f currently is to standard out
  • echo $f | sed – pipe that standard out into the sed command. So now sed will operate on & change whatever $f is
  • sed 's/\.png$/.pnm/' – sed will replace a .png at the end of the filename with a .pnm
  • $(...) – this is how you can put a sub-command inside a larger command

All together now:

for f in *_shape.png; do convert $f -fill black -opaque white -alpha off $(echo $f | sed 's/\.png$/.pnm/') && potrace $(echo $f | sed 's/\.png$/.pnm/') -s -o $(echo $f | sed 's/\.png$/.svg/') && cp $(echo $f | sed 's/\.png$/.svg/g') my/new/folder/; done

It should make more sense now!