A quick (and silly) way to create generative avatars
I was asked to help create some pseudo-NFT style avatars for Cambridge Digital Humanities' Faust Shop project. Something with vaguely the same æsthetic as those daft "Crypto Punks".
You can see it in action partway through this TikTok video.
@cambridgeuniversity Visit the #Faust Shop and see what happens when you make a deal with your digital double. #Devil #EduTok #Cambridge #Performance #Philosophy
♬ original sound - Cambridge University
Here are some examples of the types of avatars I generated:
First off, how do generative avatars work? Obviously an artist hasn't drawn hundreds of thousands of unique pieces of art. Instead, they have created a few base elements and then use those to generate millions of combinations.
Here's a very quick guide to making very bad generative art.
Start with a random string
Those planet-burning NFTs are derived from a cryptographic hash of something. For example, the address of a cryptocurrency wallet or transaction. We're going to use something much simpler; the humble MD5 algorithm.
MD5 shouldn't be used for anything which needs to be kept safe and secure. But for our purposes, it generates 32 sufficiently-random hexadecimal values. For example d41d8cd98f00b204e9800998ecf8427e
.
In our case, we take some data from the user - for example their email address - and then hash it with MD5 to produce 32 hexadecimal characters. Here's some code in PHP:
$hash = md5($email);
$characters = str_split($hash);
Extract meaning from noise
Let's take the above MD5 hash and get something useful out of it. For example, the first three characters could be the colour of the background #d41
. The next three could be the colour of the avatar's skin #d8c
. And so on.
// A canvas to draw the avatar on
$canvas = imagecreatetruecolor(23, 23);
// Generated colours
$colour_background = imagecolorallocate($canvas,
hexdec($characters[0].$characters[0]),
hexdec($characters[1].$characters[1]),
hexdec($characters[2].$characters[2]),
);
We can also use the characters as the basis for decision-making. For example, if the 7th character is greater than 5, the avatar will have a big nose. If it's less than 5, it will have a small nose.
if ( hexdec($characters[7]) > 5 ) {
// Big nose
imagefilledrectangle($canvas, 10, 12, 10, 13, $colour_nose);
} else {
imagefilledrectangle($canvas, 10, 12, 10, 12, $colour_nose);
}
We can also use that to decide whether the avatar should have a specific feature. For example, if the 8th character is odd then draw a halo, but don't draw anything if it is even.
Generate base elements
For this project, we didn't need lots of different elements. A few simple ones were enough to generate hundreds of thousands of combinations:
- Background colour
- Skin colour
- Nose colour
- Nose shape
- Lip colour
- Lip shape
- Eye colour
- Eye direction
- Decorations like halos, horns, glasses, and earrings
- Whether it is facing left or right
Limitations
There are a few problems with this approach. There is no guarantee that the background colour will be sufficiently different from the foreground colour. If the mouth is the same colour as the skin, it will disappear.
If the colours are broadly similar, they might be hard to visually distinguish. As in this example:
Because this was a quick project, there wasn't much time to create lots of varieties of decorations. For example, hair is always a rectangle - albeit one which varies in height.
Pixel art is an unsubtle medium. There's no way to add anything small - like zits or eyebrows - to a face which is only a few pixels wide.
Final thoughts
Cryptographic hash visualisations were first conceived, as far as I am aware, at the tail end of the last century. They have been a prominent feature of some PKI packages for over a decade.
Humans have difficulty recognising long strings of digits. But we're reasonably good at recognising images - especially faces. Using generative art to create visually distinct faces could be a reasonable way to help people validate whether they've previously encountered a cryptographic signature.
But, for now, this is just a simple implementation for generating something that looks and behaves like a basic NFT.
This post first appeared on the Faust-Shop website
Ben Griffiths said on twitter.com:
Coincidentally, I took my son to see this a few weeks ago. We were totally confused throughout the whole thing. It was great!
Neil Brown said on twitter.com:
This is neat!
More comments on Mastodon.