10 000 More Punks - Inside the Punk Art Machinery (Continued) - How To Generate Punks, Algorithmically - Paint by Numbers - A New Punk Series
9 rare CryptoPunks from the LavraLabs [24×24 pixel] series to star in our 21st Century Evening Sale this May [13th] in New York.
All mint numbers under 1k and yes there is a rare Alien! Punks #2, #532, #58, #30, #635, #602, #768, #603, #757. [Estimate: $7,000,000-9,000,0000.]
-- Christie's [- The World's Leading Auction House], April 2021
The bad news - the formula for the original 10 000 algorithmically generated 24×24 pixel CryptoPunks by LavraLabs is a secret (and not included in the published open source code).
The good news - emirongrr has put together a simple pixel art generator to get your started with your own punk series.
Let's convert the pixel art generator
machinery.
Let's start with all the parts of a punk:
PARTS = {
face: { },
hair: { offset: [7, 1] },
glasses: { offset: [6, 7] },
beard: { offset: [11, 19] },
}
A punk is composed of four parts, that is,
- Face
- Hair
- Glasses
- Beard
The face - the first part - is always required and the rest is optional.
For every part there is a matching directory (e.g. /face
, /hair
, /glasses
, etc.) and
for every variant there is an image with an index number starting at 1 (e.g. /face/face1.png
, face/face2.png
, etc.)
Find a cached copy of all images in the i/parts_ii
directory -
looking something like:
parts_ii/
├───face/
│ face1.png
│ face2.png
│ face3.png
├───hair/
│ hair1.png
│ hair2.png
│ hair3.png
├───glasses/
│ glasses1.png
└───beard/
beard1.png
beard2.png
Or an all-together-now sneak preview:
Note: Yes, you can add new variants. Only make sure that the image size for the parts matches the following formats - only the face is in the 100% full-size 24×24 format:
- face => 24×24
- hair => 10×8
- glasses => 12×6
- beard => 3×3
The offset (see in PARTS
above e.g. offset: [7, 1]
)
tells the starting x,y-coordinates in pixel where the part
will get pasted into the full-size 24×24 punk image
e.g. for hair it's x=7, y=1,
for glasses it's x=6, y=7 and so on.
Let's code the artist known as generate_punk
- a method
that returns a (ready-to-save) punk image
from the attribute parts coded as numbers
starting at 1. If the code is 0 than
the (optional) part gets skipped.
codes = [1,1,0,0] # face (1), hair (1), glasses (x), beard (x)
punk = generate_punk( codes )
punk.save( "./punk-1100.png" )
And here's the magic paint by number art machinery:
require 'pixelart' ## helper library for pixel art images (in .png)
def generate_punk( codes )
punk = Pixelart::Image.new( 24, 24 )
PARTS.each_with_index do |(key,part),i|
code = codes[i]
if code != 0 ## if code 0 - let's you skip optional part
## compose parts on top (from face to beard)
path = "./i/parts_ii/#{key}/#{key}#{code}.png"
img = Pixelart::Image.read( path )
x, y = part[:offset] || [0, 0]
punk.compose!( img, x, y )
end
end
punk
end
Let's try for real:
codes = [1,1,0,0] # face (1), hair (1), glasses (x), beard (x)
punk = generate_punk( codes )
punk.save( "./punk-1100.png" )
and let's add a 3x zoom factor:
punk3x = punk.zoom( 3 )
punk3x.save( "./punk-1100x3.png" )
resulting in:
How does the machinery work? The algo generates an empty 24×24 pixel image / canvas and than adds - or is that composes - one part after the other on top all the way from face to beard. That's all the magic.
Let's generate another punk.
codes = [2,3,0,1] # face (2), hair (3), glasses (x), beard (1)
punk = generate_punk( codes )
punk.save( "./punk-#{codes.join}.png" )
punk.zoom( 3 ).save( "./punk-#{codes.join}x3.png" )
resulting in:
And let's generate another punk.
codes = [3,0,1,2] # face (3), hair (x), glasses (1), beard (2)
punk = generate_punk( codes )
punk.save( "./punk-#{codes.join}.png" )
punk.zoom( 3 ).save( "./punk-#{codes.join}x3.png" )
resulting in:
Now generate your own punk series, algorithmically! Yes, you can!