Converting PNG to SVG

Let’s say, you’ve found a funny black-and-white picture on the Internet and you want it badly in hi-res or vector which is even better. Well, there is a command-line tool called Potrace.

Installation

It has precompiled distributions for OS X, Linux and Windows. Potrace is also available in major package managers, including Homebrew:

$ brew install potrace

The manual installation is super easy, however. For OS X do the following:

$ cd potrace-1.12.mac-i386
$ sudo cp mkbitmap.1 potrace.1 /usr/share/man/
$ sudp cp mkbitmap potrace /usr/local/bin

Usage

Potrace works with bitmaps (PBM, PGM, PPM, or BMP format). It means you have to convert the image you have to one of those formats. We will be using ImageMagick’s convert program. If you don’t have it installed, you can use Homebrew to get it:

$ brew install imagemagick

Alright. Let’s say you’ve got this image (by Nation of Amanda) in PNG format with transparency: ‘Nap all day, sleep all night, party never’ by Nation of Amanda All you need to do is to run this:

$ convert -alpha remove party-never.png pgm: \
| mkbitmap -f 32 -t 0.4 - -o - \
| potrace --svg -o party-never.svg

It converts PNG file to PGM format, removes image transparency, outputs the result image to the standard input of mkbitmap that transforms the input with highpass filtering and thresholding into a suitable for the potrace program format, that finally generates SVG file. You can play around with highpass filtering (-f) and thresholding (-t) values until you have the final look that you want.

As a result you might have now: ‘Nap all day, sleep all night, party never’ by Nation of Amanda That’s it.

What’s worth watching

Introduction to CSS Explorer

I’ve been curious about the state of our CSS code and its changes over the time. So I’ve written recently a program called specificity. What does it do? It answers the following questions:

  1. What is a total number of selectors in your CSS codebase? How has it been changing over the time?
  2. What is a maximum/average/median selector‘s specificity of your CSS codebase? How has it been changing over the time?
  3. How does the distribution of selector‘s specificity of your CSS codebase look like? How has it been changing over the time?
  4. How many selectors in your CSS codebase contain at least one rule with the !important directive? How has it been changing over the time?

Wait, why is it so important? It’s not, until you have a codebase of dozens of thousands lines of code that is hard to maintain and you do a lot of experiments. And of course, if it’s not even important, it’s quite interesting at least.

CSS specificity chart

So, node-specificity provides two commands. One is for parsing your CSS files and creating profiles. Second is for reading or “exploring” these profiles. Let’s look at an example. I have a few versions of CSS of the website you’re reading right now. As I’m writing this post the website is using v8.css.

Alright, let’s create profiles for these files:

$ node-specificity parse v1.css --label=v1 --output=v1.json
...
$ node-specificity parse v8.css --label=v8 --output=v8.json

We’ve created a profile for each CSS file since we want to observe changings over the time. If you use more than one CSS file on your website, you have to create a profile for all of them, for instance:

$ node-specificity parse main.css print.css --label=2014-12-23 --output=20141223.json

Label acts as a profile’s name in reports. Once we have profiles created, we are able to run a report. Let’s start a ‘server’ report:

$ node-specificity explore v*.json --report=server
Server is running on http://localhost:4000/
Press Ctrl + C to stop it.

Open a browser and go to “http://localhost:4000/”. Now you’re supposed to be seeing the page with different controls and a weird graph. It‘s the specificity distribution chart (see in the picture above). For each specificity (tuple) it shows the total number of selectors of this specificity in the specific profile.

Other graphs are: number of selectors in your CSS files and total number of selectors in profiles, how many of them contain rules with the !important directive, average and median values of selector’s specificity for CSS files and profiles.

Number of selectors chart

You are able to explore all these graphs for a specific profile. To do this, you have to select the particular profile’s label in the dropdown list. For instance, it’s the specificity distribution bar chart for ‘v8.json’ profile in the picture below.

CSS specificity chart

So, server report is quite a powerful tool. Bear in mind, images above are for the profiles of one humble CSS file. If you have a few files for profile, it gets better.

There is also inspect report (it’s used as the default one). If you run node-specificity explore v8.json, it will print out the list of all selectors in the given profile, the summary on specificity numbers and the specificity distribution chart, which is very similar to the one you can see above.

Screenshot of the ‘inspect’ report

Reports can accept additional command line options. There are few of them. In the example above, --no-inspect-selectors option has been used. It disables printing out the list of all selectors.

That’s it. Happy exploring!

What’s worth watching

Open all modified files in editor

Often I finish working day without committing changes to the repository. Thus, next morning I need to open all the files I was working yesterday. And I found an efficient way to do this.

$ vim -p $(git diff --name-only HEAD | sed "s,$(git rev-parse --show-prefix),," | tr "\n" " ")

It opens Vim and loads all modified files in tabs. You could add this command as an alias to your .bashrc, but adding this to .gitconfig seems like a better option. This is what you need to add to your ~/.gitconfig.

[alias]
open = "!vim -c \"cd $GIT_PREFIX\" -p $(git diff --name-only HEAD | tr '\\n' ' ')"

To run this command you need to type git open in the terminal. Since all commands prefixed with an exclamation point are executed from the top-level directory of a repository, we need to change working directory in Vim to the current one. And of course you can replace Vim by your favorite editor or event by $EDITOR.

Besides, If you use sort of file watchers to perform certain operations when files change, then you would find the following command quite helpful. It changes modification time of all modified files at once.

[alias]
touch = "!touch -c $(git diff --name-only HEAD | tr '\\n' ' ')"

You can find more handy aliases in .dotfiles of mine.

Archive