The idea for this library came from the www.robohash.org website. The artwork for this library came from worldlabel.com. Thank-you to www.worldlabel.com for putting their clip-art into the public domain so that free software projects like this one can use it.

doodlehash, a C library that makes a random face from a string of text. You can use doodlehash to make an avatar from an email address. The idea is that you can use identifying text for a person to generate a random image.

You give it some random text, as well as a desired height and width of the face, and doodlehash gives you back a randomly generated face on a GdkPixbuf. Call g_object_unref on the returned pixbuf when you're done with it.

There is a known bug in this version of the software: width must be the same as height for faces to be generated properly.

The init and term functions mostly equate to the same named functions inside librsvg2 (a run-time dependency of doodlehash). doodlehash_init does a little extra work of checking if it can see any data files -- it will return non-zero if it can't find any.

Note that the doodlehash software needs to be built with --prefix=/usr so that the doodlehash pkg-config file gets installed into the right place.

The remainder of this document will describe how to change the behaviour of doodlehash. If you want to add a new mouth, or change a hairstyle, or if you just want to know how doodlehash works; then read on.

The drawing order of the parts of the face is hard-coded into the doodlehash library. There aren't any hints (yet) that can be passed to draw one object before or after another.

The drawing order is as follows:

The head is drawn on a background of white.

Cheeks.

A nose.

Eyes.

Eyebrows.

Spectacles.

A Chin.

A Mouth.

A Moustache.

Ears.

Earrings.

Hair.

The drawing order is important because it means that some facial objects will obscure others. It means that hair cannot go behind the head or the ears. But mostly it means good things like, earrings get drawn on ears; that fuzzy eyebrows obscure eyes; that a moustache obscures a mouth; and that eyeglasses can be transparent to see-through to the eyes.

Doodlehash looks for data files in /usr/share/doodlehash (again, this requires the software to be built with configure --prefix=/usr). This directory has a single subdirectory for each of the face parts:

cheeks/

chins/

ears/

earrings/

eyes/

eyebrows/

hair/

heads/

moustaches/

mouths/

noses/

spectacles/

Each of the subdirectories hold zero or more specially annotated (e.g. doodlehash-aware) SVG files.

Some of the face parts are implemented as left/right pairs of SVG files. The left graphic filename must have the -left.svg suffix, while the right-side graphic must have a -right.svg suffix. Doodlehash requires this naming convention to function properly.

The subdirectories that have these left/right pairs are:

cheeks/

ears/

earrings/

eyebrows/

Sometimes a particular part of the face is clearly male or female, and it doesn't always make sense to mix and match the parts. A big old Hulk Hogan moustache probably doesn't make a lot of sense on a head that has a pretty pink bow on it. Or maybe it does -- but Carlos wouldn't be comfortable with that.

SVG files that begin with m- are marked as being only applicable for male faces, while files that start with m- females only. By default all SVG files are applicable to both male and female.

The various parts of the face connect together in a straightforward manner:

Earrings connect to ears.

Moustaches connect to the mouth.

Eyebrows connect to eyes.

Everything else connects to the head.

The SVG files are specially annotated by naming rectangles. This is easily accomplished in an SVG editor like Inkscape. The following names are rectangle IDs that doodlehash recongizes:

connect-to-ear

an earring SVG will have a rectangle named this.

connect-to-mouth

a moustache SVG will have a rectangle named this.

connect-to-head

used by: eyes, nose, cheeks, ears, mouth, and chin SVG files.

connect-to-moustache

used by mouth SVG files.

connect-to-left-brow, connect-to-right-brow

used by eye SVG files.

connect-to-earring

used by ear SVG files.

connect-to-eyes

used by head SVG files.

connect-to-left-ear, connect-to-right-ear

used by head SVG files.

connect-to-left-cheek, connect-to-right-cheek

used by head SVG files.

connect-to-nose

used by head SVG files.

connect-to-mouth

used by head SVG files.

The doodlehash library places the SVGs on top of each other according to where their connection points align. Imagine the connect-to-ear point in the earring SVG lining up with the connect-to-earring point in an ear SVG. Likewise the for connect-to-nose point in the head SVG lining up with the connect-to-head point in the nose SVG. Is this easy or what?

Beware that if the calculated upper-left corner of a face part has a negative subscript, it will not be drawn on the face.

Spectacles are connected at the point as the eyes. The dimensions of the spectacles SVG must be precisely the same as the eyes to be considered for random inclusion on the face. In this manner the doodlehash library is shown which eyes go with which spectacles.

A hair file must have the same dimensions as the head file to be considered for random inclusion on the face. In this manner the doodlehash library is shown which hair goes with which head.

Although the named SVG elements are rectangles, the point of the top-left corner is used when connecting face parts (and not the center of the rectangle).

Inkscape is your friend. You will be spending a lot time in Inkscape if you want to make your own set of faces. Placing hair can be difficult -- to make it easier, you can include a transparent generic head shape in your hair SVG files, and then work in outline-mode to place the hair in just the right place.

Try making your own mouth SVG file and add it to the doodlehash library of mouths! Maybe it's a big old frown, or maybe it's a mouth that's laughing.

Doodlehash allows for colour randomization, but they're not all that random. By default it won't generate faces with blond moustaches and black hair. And doodlehash also makes sure that the skin tones match. How does it do that?

Doodlehash knows about skin colour and hair colour. It knows which hair colours go with which skin colours. How does it know that? The colours are listed in each SVG file's metadata description. A single colour description line looks like this:

#000000 #000000 #FFFFFF #FFFFFF

There are four rgb colours in html hexadecimal notation. Other lines in the description that don't have this form are ignored by doodlehash. The first two colours refer to the stroke and fill colours for skin, and the last two colours refer to the stroke and fill colours for hair. So in this case we have skin that is black and hair that is white. This is one potential colour scheme for the SVG file it appears in.

Doodlehash tries to make sure that the following parts "go together": hair, ears, moustache, mouth, nose, eyebrows, chin and cheeks. All of these SVG files will need similar colour description lines in them, if you want the parts to "go together". If an SVG file does not have any colour description lines in it, it will be considered suitable for any colour scheme.

spectacles, and earrings can also have these colour description lines. The two sets of colours don't mean hair and skin though -- instead they are just colours that your spectacles and your earrings look good with.

After doodlehash does the hard work of finding the parts that look good together, it needs to change the colour of the SVG file. Doodlehash is told which parts to change the colour of by setting the stroke and fill colours to special doodlehash placeholder values.

The default face parts do not include any cheeks, noses, ears, moustaches, spectacles, or earrings. This doesn't mean that they can't be used; they just lack proper artwork. The default heads have ears already on them because flawlessly lining up ears with many different heads seemed too time consuming.

Beware that adding one moustache will moustachio all randomly generated male faces. This can be addressed by adding a number of blank moustaches.

Try adding some spectacles. Make sure you a differently sized set of eyes, otherwise all of your randomly generated faces will be bespectacled.

Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU Free Documentation
License (GFDL), Version 1.2 or any later version published
by the Free Software Foundation with no Invariant Sections,
no Front-Cover Texts, and no Back-Cover Texts. You can find
a copy of the GFDL at this link or in the file COPYING-DOCS
distributed with this manual.

This manual is part of a collection of GNOME manuals
distributed under the GFDL. If you want to distribute this
manual separately from the collection, you can do so by
adding a copy of the license to the manual, as described in
section 6 of the license.

Many of the names used by companies to distinguish their
products and services are claimed as trademarks. Where those
names appear in any GNOME documentation, and the members of
the GNOME Documentation Project are made aware of those
trademarks, then the names are in capital letters or initial
capital letters.

DOCUMENT AND MODIFIED VERSIONS OF THE DOCUMENT ARE PROVIDED
UNDER THE TERMS OF THE GNU FREE DOCUMENTATION LICENSE
WITH THE FURTHER UNDERSTANDING THAT:

DOCUMENT IS PROVIDED ON AN "AS IS" BASIS,
WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR
IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
THAT THE DOCUMENT OR MODIFIED VERSION OF THE
DOCUMENT IS FREE OF DEFECTS MERCHANTABLE, FIT FOR
A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE
RISK AS TO THE QUALITY, ACCURACY, AND PERFORMANCE
OF THE DOCUMENT OR MODIFIED VERSION OF THE
DOCUMENT IS WITH YOU. SHOULD ANY DOCUMENT OR
MODIFIED VERSION PROVE DEFECTIVE IN ANY RESPECT,
YOU (NOT THE INITIAL WRITER, AUTHOR OR ANY
CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
LICENSE. NO USE OF ANY DOCUMENT OR MODIFIED
VERSION OF THE DOCUMENT IS AUTHORIZED HEREUNDER
EXCEPT UNDER THIS DISCLAIMER; AND

UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL
THEORY, WHETHER IN TORT (INCLUDING NEGLIGENCE),
CONTRACT, OR OTHERWISE, SHALL THE AUTHOR,
INITIAL WRITER, ANY CONTRIBUTOR, OR ANY
DISTRIBUTOR OF THE DOCUMENT OR MODIFIED VERSION
OF THE DOCUMENT, OR ANY SUPPLIER OF ANY OF SUCH
PARTIES, BE LIABLE TO ANY PERSON FOR ANY
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
CONSEQUENTIAL DAMAGES OF ANY CHARACTER
INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS
OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR
MALFUNCTION, OR ANY AND ALL OTHER DAMAGES OR
LOSSES ARISING OUT OF OR RELATING TO USE OF THE
DOCUMENT AND MODIFIED VERSIONS OF THE DOCUMENT,
EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF
THE POSSIBILITY OF SUCH DAMAGES.