Skip to content

Instantly share code, notes, and snippets.

@bendmorris
Last active Jul 21, 2021
Embed
What would you like to do?
Potrace script designed for making FontForge pixel fonts
#!/bin/bash
# To use, move the potrace binary to potrace-bin, then place this script
# somewhere on the path so that it'll be found by fontforge.
# After autotracing, you'll need to apply the following transformation:
# scale uniform 10%, using glyph origin as the origin
# get the last parameter passed by fontforge - the name of the temp img file
for last; do true; done
# get all of the other parameters
length=$(($#-1))
array=${@:1:$length}
# get the size of the passed image
size=$(identify $last | grep -Po "[0-9]+x[0-9]+" | head -1)
# multiply that size by 10
newsize=$(python -c "x = '$size'; print('x'.join([str(int(i)*10) for i in x.split('x')]))")
# scale up 10x and then use potrace to trace the pixelated outline
cat $last | mkbitmap -s 1 | convert -scale $newsize - - | potrace-bin -a 0 $array
@bendmorris

This comment has been minimized.

Copy link
Owner Author

@bendmorris bendmorris commented Oct 26, 2013

Required tools:

identify and convert (from imagemagick: http://www.imagemagick.org/script/index.php)
mkbitmap (comes with potrace)
python

@codeman38

This comment has been minimized.

Copy link

@codeman38 codeman38 commented Jun 22, 2014

If you add -r 720 to the potrace command, it will eliminate the need for resizing the outline afterward. Correction-- it looks like the -r option is actually specified in the command invoked by fontforge. This can automatically be updated to have an extra 0 appended, using a command like the following:
array="echo "$array" | sed -r 's/ -r ([0-9]+)/ -r \10/g'"

(Explanation: The -r option of potrace identifies the resolution of the bitmap file for use in calculating the dimensions of the EPS output. The original bitmap is 72 DPI; since it was multiplied by 10, the resized bitmap is 720 DPI.)

Edited to add: Additionally, to make this script work on Mac OS X, change grep -Po to grep -Eo, and sed -r to sed -E. (The -P option is unique to the GNU version of grep, while the -E option exists in both GNU and BSD versions; the same appears to be true for -E in sed, though not in all versions of gnu grep.)

@Artoria2e5

This comment has been minimized.

Copy link

@Artoria2e5 Artoria2e5 commented Nov 4, 2016

Here is a better way to do this job: https://gist.github.com/anonymous/1853b5d13093d3c27a0b93db42045055

A few notes to add:

  • potrace only accepts "the last word" for an option. Don't bother using sed to replace it; just add what you want at the end.
  • identify has a format option, so why grepping around?
  • mkbitmap does some high-pass filtering to preserve details over background, yet this generally messes up bitmap fonts' large dark areas. Use -n to turn it off.
@2kCarlos

This comment has been minimized.

Copy link

@2kCarlos 2kCarlos commented Sep 18, 2020

How do I run this?
In FontForge, going under File > Execute Script only has options for Python or FF (legacy) scripts, not bash scripts like this one.

I'm following a pixel art font tutorial and they say just go to Edit > Autotrace, probably cause they already "installed" the script or whatever.
How do I get it to be there?

I'm on Linux (Ubuntu 20.04.1 LTS, just installed today), with GNOME Desktop 3.36.3.

@2kCarlos

This comment has been minimized.

Copy link

@2kCarlos 2kCarlos commented Sep 18, 2020

I tried the following:

sudo vim /usr/local/bin/potrace (went into INSERT mode to paste your code above into the file, saved the file with !wq)
sudo chmod +x /usr/local/bin/potrace
/usr/local/bin/potrace (to run the bash script)

I get 3 errors on Line 17:
It doesn't know what mkbitmap, convert, or potrace-bin is.

  1. I don't understand where a potrace-bin is supposed to come from, or what the "potrace binary" is if I just need to run this bash script?
    I don't see a binary?

  2. I downloaded magick as the "Complete portable application on Linux, no installation required. Just download and run.", but I just have a magick file sitting in my Downloads folder now that doesn't do anything.


I'm coming from a Windows background, so there's a lot I don't get here...

@bendmorris

This comment has been minimized.

Copy link
Owner Author

@bendmorris bendmorris commented Sep 18, 2020

This is 7 years old, I can't guarantee it still works and I'm not in a position to update it.

@2kCarlos

This comment has been minimized.

Copy link

@2kCarlos 2kCarlos commented Sep 18, 2020

Ohhh I figured out how to run it --I didn't realize potrace is an actual library/tool that I can get from:
sudo apt install potrace,
and as stated above, that installs mkbitmap with it (for me, these 2 binaries were installed to /usr/bin/potrace and /usr/bin/mkbitmap)

Fixes I figured out:

  1. This script is called potrace because it's supposed to replace the potrace that you have installed.
    Instead of confusingly renaming it to potrace-bin, I called it potrace-original.
    Then, this script should get saved to /usr/bin/potrace, and calls the /usr/bin/potrace-original binary to do the rest.

  2. I also moved the magick file to /usr/bin/magick, and modified the script above to say magick convert instead of just convert on Line 17. It didn't know where the "convert" command was coming from.


Now that that's all sorted out, I called Element > Autotrace in FontForge and am getting a Python error I believe:

ValueError: invalid literal for int() with base 10: ''

Then another error when calling magick convert -- it says:

convert: no images defined `-' @ error/convert.c/ConvertImageCommand/3285.

And finally a 3rd error:

potrace: stdin: empty file

Time to figure this out..

@2kCarlos

This comment has been minimized.

Copy link

@2kCarlos 2kCarlos commented Sep 18, 2020

I've only spent a week or so in Python.. I wonder why it's saying the i being passed into int(i) is empty?

@Alligrater

This comment has been minimized.

Copy link

@Alligrater Alligrater commented Jul 18, 2021

for whom it may concern...
newsize=$(python -c "x = '$size'; print('x'.join([str(int(i)*10) for i in x.split('x')]))")

use python3 instead of python up there

@moto3101

This comment has been minimized.

Copy link

@moto3101 moto3101 commented Jul 21, 2021

I also tried to make this work on Ubuntu 20.04 but without success so far. On my 18.04 Ubuntu with FontForge from 2017 it works without any problems. Btw using python3 instead did not have any effect for me.
I tried to use an older potrace version --> no difference
Currently Im trying to compile the fontforge version from 2017 since I cant find a release from that time

If anyone finds a solution please post it here, thx!

@Alligrater

This comment has been minimized.

Copy link

@Alligrater Alligrater commented Jul 21, 2021

I might have a lead on whats happening here. if it doesn't work even if you switched to python3, the whole sequence probably didn't happen at all, because if you have been using python 2, the program would fail on the print() statement since it's illegal syntax

did you see any outputs on the console?

@moto3101

This comment has been minimized.

Copy link

@moto3101 moto3101 commented Jul 21, 2021

I might have a lead on whats happening here. if it doesn't work even if you switched to python3, the whole sequence probably didn't happen at all, because if you have been using python 2, the program would fail on the print() statement since it's illegal syntax

did you see any outputs on the console?

I just tried it again with a fresh installation and now it just works.. my god that have been 4 hours now...Thanks a lot for your reply :)

For anyone who is (after all this time) still interested in getting this to work, just follow these simple steps for a fresh installed Ubuntu 20.04:

sudo apt-get update
sudo apt-get install potrace imagemagick fontforge

Python 3 is already preinstalled, so nothing to be done there.
Then, create a file called potrace in your /usr/local/bin (leave the original potrace binary as it is)

sudo nano /usr/local/bin/potrace

(or any other editor of your choice)

paste the following shell script there (its the same as above just with python3 and with an explicite call of the potrace binary in the /usr/bin folder) and save it

#!/bin/bash
# To use, move the potrace binary to potrace-bin, then place this script
# somewhere on the path so that it'll be found by fontforge.
# After autotracing, you'll need to apply the following transformation:
#   scale uniform 10%, using glyph origin as the origin

# get the last parameter passed by fontforge - the name of the temp img file
for last; do true; done
# get all of the other parameters
length=$(($#-1))
array=${@:1:$length}
# get the size of the passed image
size=$(identify $last | grep -Po "[0-9]+x[0-9]+" | head -1)
# multiply that size by 10
newsize=$(python3 -c "x = '$size'; print('x'.join([str(int(i)*10) for i in x.split('x')]))")
# scale up 10x and then use potrace to trace the pixelated outline
cat $last | mkbitmap -s 1 | convert -scale $newsize - - | /usr/bin/potrace -a 0 $array

make the file executable

sudo chmod 0755 /usr/local/bin/potrace

Then start FontForge, import your bdf as background and use the autotrace on the elements you like :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment