Awesome
Looking for Matt & John's® 10 000 punks collection (Anno 2017)? See Punks - The Free White Label Quick Starter Edition »
New to Ordinal Punks? For some background see Awesome 100 Ordinal Punks (Anno 2023) Notes - 24×24 Pixel Art on the (Bitcoin) Blockchain »
100 Ordinal Punks - The Free White Label Quick Starter Edition
Yes, you can. Let's (re)create from zero / scratch a pixel-perfect copy of the Ordinal Punks collection (Anno 2023) using text prompts ("attributes").
Note / Disclaimer: I (Gerald Bauer) am the creator of the punk's not dead text-to-image generation algorithm (& punk spritesheet) BUT have heard about Ordinal Punks in the news and I have no insight knowledge and I am NOT affiliated with Ordinal Punks (HODLing: 0).
Update Since getting attacked (repeatedly) by "More Punks" the Ordinal Punks founder "Flow Stay" has reached out to my call for help and "unlocked / verified" my Ordinal Punks discord (chat server) membership where I now post in the #general or #pixelart-programming channels (from time-to-time).
Let's get the official metadata (text-prompt attributes) from Inscription @ #58665 uploaded by Tropo Farmer (on February 11th, 2023).
Triva / Errata: While preparing this step-by-step guide / tutorial I found two bugs / errors in the official metadata:
- Ordinal Punk #25 - Incl. An Extra Hoodie
"attributes": [{"trait_type": "Type", "value": "Male 2"}, {"trait_type": "Hair", "value": "Sombrero"}, {"trait_type": "Mouth", "value": "Mustache"}, {"trait_type": "Clothes","value": "Hoodie"}]
- Ordinal Punk #84 - The (Punk) Type Reads: Alien Male Green BUT is really (Human) Male 1
"attributes": [{"trait_type": "Type", "value": "Male Alien Green"}, {"trait_type": "Eyes", "value": "Eye Mask"}, {"trait_type": "Mouth","value": "Chinstrap"}, {"trait_type": "Hair", "value": "Fedora Black & White"}]
Note: On March 25th, 2023 - I assume - "Flow Stay" uploaded a fixed version of the official metadata (text-prompt attributes). See Inscription @ #592145 that now reads:
- Ordinal Punk #25
"attributes": [{"trait_type": "Type", "value": "Male 2"}, {"trait_type": "Hair", "value": "Sombrero"}, {"trait_type": "Mouth", "value": "Mustache"}]
- Ordinal Punk #84
"attributes": [{"trait_type": "Type", "value": "Male 1"}, {"trait_type": "Eyes", "value": "Eye Mask"}, {"trait_type": "Mouth","value": "Chinstrap"}, {"trait_type": "Hair", "value": "Fedora Black & White"}]
Update Since getting "unlocked / verified" on the Ordinal Punks discord (chat server) and now with full (read) access I can report that "Flow Stay" has posted all metadata (text-prompt) attributes in the #trait-list channel (on February 8th, 2023)
Letting everyone know the traits before json metadata file goes out:
1: ["Male Robot", "Big Beard"]
2: ["Male2", "Birthday Hat", "Bubble Gum"]
3: ["Female1", "Flowers", "Frown", "Gold Chain"]
4: ["Male Demon", "Hoodie", "Pipe"]
5: ["Male Blue Ape", "Buck Teeth", "Cowboy Hat"]
6: ["Male3", "Laser Eyes", "Cowboy Hat Black & White"]
7: ["Male1", "Burger King Cap"]
8: ["Male Vampire", "Demon Horns"]
9: ["Orange Female", "Crown"]
10: ["Female3", "Choker", "Wild White Hair", "Cigarette", "Mole", "Big Shades", "Frown"]
11: ["Male Zombie", "Mole", "3D Glasses", "Frown", "Big Beard", "Earring"]
12: ["Male Orc", "Beanie", "VR", "Clown Nose"]
13: ["Female4", "Pilot Helmet", "Silver Chain", "Clown Eyes Green"]
14: ["Male Orange", "Beanie Black & White"]
15: ["Male4", "Police Cap Black & White", "Regular Shades"]
16: ["Male4", "3D Glasses Black & White"]
17: ["Male Demon", "Cigarette", "Laser Eyes"]
18: ["Male4", "Buck Teeth", "Cigarette", "Frown", "Gold Chain", "Knitted Cap", "Earring", "Mole"]
19: ["Female1", "Bow"]
20: ["Male Zombie Ape", "Cigar", "Bubble Gum"]
21: ["Male Gold Alien", "Top Hat Black & White", "Silver Chain"]
22: ["Male Blue", "Clown Hair Blue"]
23: ["Female2", "Rosy Cheeks", "Tiara", "Smile"]
24: ["Male1", "Medical Mask", "Clown Nose", "Hoodie"]
25: ["Male2", "Sombrero", "Mustache"]
26: ["Male Vampire", "Bubble Gum", "Spots", "Do Rag"]
27: ["Male Mummy", "Beanie"]
28: ["Male2", "Crazy Hair", "Regular Shades", "Cigar"]
29: ["Male Zombie", "Hoodie", "Gold Chain", "VR"]
30: ["Male2", "Jester Hat"]
31: ["Male1", "Red Cap"]
32: ["Male4", "Laser Eyes", "Messy Hair"]
33: ["Female2", "Hoodie", "Eye Patch"]
34: ["Female3", "Black Lipstick", "Choker", "Eye Mask"]
35: ["Male Skeleton", "Eye Patch", "Fedora"]
36: ["Female4", "Clown Hair Green", "Classic Shades"]
37: ["Male1", "3D Glasses", "Cigarette", "Buck Teeth"]
38: ["Female Orc", "Blonde Bob"]
39: ["Female Zombie", "Birthday Hat", "VR"]
40: ["Male2", "Laser Eyes", "Bandana"]
41: ["Female Mummy", "Crown"]
42: ["Female Demon", "Cigar", "Choker"]
43: ["Female4", "Nerd Glasses", "Frumpy Hair"]
44: ["Female1", "Cowboy Hat", "Pipe"]
45: ["Male2", "Top Hat", "Silver Chain", "Smile"]
46: ["Blue Male", "Burger King Cap", "Classic Shades"]
47: ["Purple Female", "Clown Eyes Green", "Blonde Bob"]
48: ["Gold Male", "Laser Eyes", "Frown", "Cap Forward"]
49: ["Female3", "Beanie", "Blue Eyeshadow", "Earring"]
50: ["Male Alien Ape", "Goat", "Fedora"]
51: ["Blue Female", "Nerd Glasses", "Blonde Short"]
52: ["Female Pink Alien", "3D Glasses"]
53: ["Female Demon", "Frumpy Hair", "Clown Nose"]
54: ["Male3", "Heart Shades", "Do Rag"]
55: ["Female Skeleton", "Bandana", "Cigarette"]
56: ["Female2", "Earring", "Mole", "Cap", "Smile"]
57: ["Male4", "Clown Nose", "Top Hat Black & White"]
58: ["Female Vampire", "Heart Shades"]
59: ["Blue Male", "Cowboy Hat Black & White", "Pipe", "Cigarette"]
60: ["Male1", "Crazy Hair", "Clown Eyes Blue", "Eye Mask"]
61: ["Female Demon", "Blue Eyeshadow"]
62: ["Male2", "Big Shades", "Beanie Black & White"]
63: ["Female Zombie", "Frown"]
64: ["Female Orc", "Mole", "Frumpy Hair", "Green Eye Shadow"]
65: ["Male1", "Frown", "Do Rag", "Gold Chain", "Classic Shades"]
66: ["Female Ape", "Sombrero"]
67: ["Male Yellow Alien", "Smile", "Goat"]
68: ["Gold Female", "Clown Hair Green", "Choker"]
69: ["Female Robot", "3D Glasses"]
70: ["Orange Male", "Bandana", "Chinstrap"]
71: ["Female3", "Green Eye Shadow", "Top Hat Black & White"]
72: ["Female Mummy", "Dark Hair"]
73: ["Female Purple Alien", "Pipe", "Knitted Cap"]
74: ["Orange Female", "Cap Forward"]
75: ["Male Demon", "Big Beard"]
76: ["Male Robot", "Classic Shades", "Cigarette"]
77: ["Male4", "Eye Mask", "Silver Chain", "Bandana", "Clown Nose"]
78: ["Male Zombie", "Pipe", "Hoodie"]
79: ["Male3", "Earring", "3D Glasses Black & White"]
80: ["Male Orc"]
81: ["Female Vampire", "Dark Hair"]
82: ["Male Mummy", "Cowboy Hat Black & White", "Eye Mask"]
83: ["Male Green Alien", "Clown Eyes Blue"]
84: ["Male1", "Eye Mask", "Chinstrap", "Fedora Black & White"]
85: ["Male4", "Silver Chain", "Cap Forward", "Pipe", "Demon Horns"]
86: ["Male Skeleton", "Clown Eyes Green"]
87: ["Female3", "Do Rag", "Gold Chain"]
88: ["Male4", "Cap Forward Black & White", "3D Glasses Black & White"]
89: ["Female Zombie", "Cap", "Earring", "Green Eye Shadow", "Cigar"]
90: ["Male Vampire", "Demon Horns", "Chinstrap"]
91: ["Female1", "Cowboy Hat", "Green Eye Shadow", "Black Lipstick", "Choker"]
92: ["Male Robot", "Crazy Hair"]
93: ["Male Orc", "Eye Mask", "Goat", "Gold Chain"]
94: ["Male Alien Ape", "Eye Patch", "Frumpy Hair"]
95: ["Female3", "Clown Nose", "Medical Mask", "Cigarette"]
96: ["Orange Male", "Classic Shades", "Big Beard", "Bandana"]
97: ["Male Gold Alien", "3D Glasses", "Beanie Black & White", "Cigarette", "Silver Chain", "Mole"]
98: ["Yellow Female", "Tiara", "Crown", "Silver Chain"]
99: ["Male Yellow Ape", "Cap Forward", "Earring", "Medical Mask"]
100: ["Male Demon", "Cowboy Hat Black & White", "Buck Teeth"]
For your convenience I have reformated the dataset in javascript notation (.json) into the tabular dataset in the comma-separated values (.csv) format. The ordinalpunks.csv dataset (with 100 records / rows) reads:
id, type, gender, skin_tone, accessories
1, Robot, Male,, Big Beard
2, Human, Male, 2, Bubble Gum / Birthday Hat
3, Human, Female, 1, Flowers / Frown / Gold Chain
4, Demon, Male,, Hoodie / Pipe
5, Ape, Male, Blue, Buck Teeth / Cowboy Hat
6, Human, Male, 3, Laser Eyes / Cowboy Hat B & W
7, Human, Male, 1, Cap Burger King
8, Vampire, Male,, Demon Horns
9, Human, Female, Orange, Crown
...
Method №1 - Using The "Classic" Punk Command-Line Tool
The Official Ordinal Punks website points / links via "using an open source algorithm to generate the profile pictures (pfps)" to the punk's not dead command-line tool.
Let's try to generate some punks on the command-line in your terminal using official text-to-image prompts / attributes.
Once you have installed the (crypto) punk's not dead command-line tool package try:
$ punk -h
resulting in:
NAME
punk - punk (or cryptopunk) command line tool
SYNOPSIS
punk [global options] command [command options] [arguments...]
VERSION
3.0.0
GLOBAL OPTIONS
-d, --dir,
-o, --out, --outdir=DIR - Output directory (default: .)
-f, --file=FILE - All-in-one
composite image (default: ./punks.png)
--offset=NUM - Start counting at offset (default: 0)
--seed=NUM - Seed for random number generation /
shuffle (default: 4142)
-z, --zoom=ZOOM - Zoom factor x2, x4, x8, etc. (default: 1)
--help - Show this message
--version - Display the program version
--verbose - (Debug) Show debug messages
COMMANDS
g, gen, generate - Generate punk characters from text attributes (from
scratch / zero) via builtin punk spritesheet
l, ls, list - List all punk archetype and attribute names from builtin
punk spritesheet
q, query - Query (builtin off-chain) punk contract for punk text
attributes by IDs - use 0 to 9999
t, tile - Get punk characters via image tiles from all-in-one punk
series composite (./punks.png) - for IDs use 0 to 9999
f, flip - Flip (vertically) all punk characters in all-in-one punk
series composite (./punks.png)
s, shuffle - Shuffle all punk characters (randomly) in all-in-one
punk series composite (./punks.png)
help - Shows a list of commands or help for one command
No worries. We are only interested in the g/gen/generate command. Let's generate Ordinal Punk No. 1. Type:
$ punk --offset=1 gen robot_male big_beard
resulting in:
==> generating >robot_male + big_beard<...
lookup 24×24 >robotmale< => 69: Robot / Archetype - Robot (m+l)
lookup 24×24 >bigbeard_(m+l)< => 387: Big Beard / Attribute (m+l)
saving punk #1 to >./punk-0001.png<...
Let's regenerate with a zoom factor of 8x (8 times 24px = 192px) to get the "original" inscribed size of 192×192px. Type:
$ punk --offset=1 --zoom=8 gen robot_male big_beard
resulting in:
==> generating >robot_male + big_beard<...
lookup 24×24 >robotmale< => 69: Robot / Archetype - Robot (m+l)
lookup 24×24 >bigbeard_(m+l)< => 387: Big Beard / Attribute (m+l)
setting zoom to 8x
saving punk #1 to >./punk-0001@8x.png<...
Voila!
Note: The text-to-image generator uses space-separated
text prompts / attributes, that is, change "Male 2" to male_2
(or male2
)
and "Bubble Gum" to bubble_gum
(or bubblegum
) and so on.
Let's try some more:
$ punk --offset=2 --zoom=8 gen male_2 bubble_gum birthday_hat
$ punk --offset=3 --zoom=8 gen female_1 flowers frown gold_chain
$ punk --offset=4 --zoom=8 gen demon_male hoodie pipe
$ punk --offset=5 --zoom=8 gen ape_male_blue buck_teeth cowboy_hat
resulting in:
And so on. Wondering what "magic" text-prompts / attributes you can use? Sorry, no artificial intelligence (a.i.) model in use :-( - you can lookup the "hard-coded" names in the official punk spritesheet name list - see spritesheet.csv.
Tip of the Day - Did you know? The punk text-to-image generator is part of the Factory of Modern Originals (FoMO).
Let's retry with - bonus! - different backgrounds added in:
$ fab --name=punk1 --zoom=8 --background=ukraine punk robot_male big_beard
$ fab --name=punk2 --zoom=8 --background=pride punk male_2 bubble_gum birthday_hat
$ fab --name=punk3 --zoom=8 --background=matrix1 punk female_1 flowers frown gold_chain
$ fab --name=punk4 --zoom=8 --background=0x638596 punk demon_male hoodie pipe
$ fab --name=punk5 --zoom=8 --background=0xffbf00 punk ape_male_blue buck_teeth cowboy_hat
resulting in:
==> welcome to the fab(ricate) tool:
lookup 24×24 >robotmale< => 69: Robot / Archetype - Robot (m+l)
lookup 24×24 >bigbeard_(m+l)< => 387: Big Beard / Attribute (m+l)
saving original punk (192×192) to >./punk1@8x.png<...
lookup 24×24 >male2< => 6: Human 2 / Archetype - Human (m+l)
lookup 24×24 >bubblegum_(u+l)< => 376: Bubble Gum / Attribute (u+l)
lookup 24×24 >birthdayhat_(u+l)< => 434: Birthday Hat / Attribute (u+l)
saving original punk (192×192) to >./punk2@8x.png<...
...
And so on.
Method №2 - Using The Punk Image Script
Let's automate and use the punk machinery with a script. Let's read in the 100 ordinal punk metadata records:
require 'punks'
recs = read_csv( "./ordinalpunks.csv" )
puts " #{recs.size} record(s)"
#=> 100 record(s)
And let's wipe-up a rec_to_attributes
method that "transforms" a metadata record
such as
{"id" =>"1",
"type" =>"Robot",
"gender" =>"Male",
"skin_tone" =>"",
"accessories"=>"Big Beard"}
# or
{"id" =>"2",
"type" =>"Human",
"gender" =>"Male",
"skin_tone" =>"2",
"accessories"=>"Bubble Gum / Birthday Hat"}
into an array of strings / attributes ready for text-to-image generation e.g.
["Robot Male", "Big Beard"]
# or
["Human Male 2", "Bubble Gum", "Birthday Hat"]
def rec_to_attributes( rec )
type = rec['type']
gender = rec['gender']
skin_tone = rec['skin_tone']
# note: merge type+gender+skin_tone into one attribute
base = "#{type} #{gender}"
base << " #{skin_tone}" unless skin_tone.empty?
accessories = rec['accessories'].split( '/' ).map { |acc| acc.strip }
attributes = [base] + accessories
attributes
end
And all-together now. Let's generate the 100 ordinal punk images in 24×24 format and in 192×192 with 8x zoom:
recs.each do |rec|
id = rec['id']
puts "==> generating punk ##{id}..."
attributes = rec_to_attributes( rec )
pp attributes
img = Punk::Image.generate( *attributes )
img.save( "./tmp/#{id}.png")
img.zoom(8).save( "./tmp/#{id}@8x.png")
end
Run the script - resulting in:
/1.png
1@8x.png
2.png
2@8x.png
...
100.png
100@8x.png
...
...
Bonus: Let's generate an all-in-one composite. Change the loop to:
composite = ImageComposite.new( 10, 10, width: 24,
height: 24 )
recs.each do |rec|
id = rec['id']
puts "==> generating punk ##{id}..."
attributes = rec_to_attributes( rec )
pp attributes
img = Punk::Image.generate( *attributes )
img.save( "./tmp/#{id}.png")
img.zoom(8).save( "./tmp/#{id}@8x.png")
composite << img ## bonus: add to composite
end
## save all-in-one composite
composite.save( "./tmp/punks.png" )
composite.zoom(4).save( "./tmp/punks@2x.png" )
Rerun the script. Resulting in:
and the 4x version:
Bonus - Ordinal Punks v2 - New Improved Formula
Update While preparing some ordinal punk variants e.g. greenbacks, gold/silver/bronze, blue chip, etc. (see the Ordinal Punk Sandbox) I found minor & major bugs / errors / glitches in the official metadata (text-prompt attributes).
Before diving into the new and improved version 2 formula - let's have a looksie at half a dozen before & afters, that is, v1s vs v2s. Can you spot the differences?
Before - After (in 4x)
№6 ⇒
№48 ⇒
№59 ⇒
№78 ⇒
№88 ⇒
...
For some hints - here's the break down of the new improved version 2 formula:
(1) Broken / wrong stacking order for laser eyes & friends. In Ordinal Punk #6 or Ordinal Punk #48, for example, the laser eyes get semi-hidden by the headwear / hats - the fix: let' change the order, that is, paste the hats before the laser eyes.
- №6 - Laser Eyes / Cowboy Hat B & W ⇒ Cowboy Hat / Laser Eyes
- №48 - Laser Eyes / Cap Forward ⇒ Cap Forward / Laser Eyes
The same holds for pipes or cigarettes (with smoke).
- №37 - 3D Glasses / Cigarette / Buck Teeth ⇒ 3D Glasses / Buck Teeth / Cigarette
- №78 - Pipe / Hoodie ⇒ Hoodie / Pipe
(2) Cigarette or Pipe? Ordinal Punk #59 sports a cigarette AND a pipe - the fix: let's drop the cigarette. Cigar or Bubble Gum? Ordinal Punk #52 sports a cigar AND a bubble gum - the fix: let's drop the (hidden) cigar. Tiara or Crown? Ordinal Punk #98 sports a tiara AND a crown - the fix: let's drop the (hidden) tiara.
(3) True colors. Some Ordinal Punks use black & white attributes (sixteen in total) - the fix: let's change all black & white attributes to "true color".
- Beanie B & W ⇒ Beanie
- Police Cap B & W ⇒ Police Cap
- 3D Glasses B & W ⇒ 3D Glasses
- ...
For your convenience and easy (re)use I have published the alternate dataset v2 in the comma-separated values (.csv) format. The ordinalpunks_v2.csv dataset (with 100 records / rows) reads:
id, type, gender, skin_tone, accessories
1, Robot, Male,, Big Beard
2, Human, Male, 2, Birthday Hat / Bubble Gum
3, Human, Female, 1, Flowers / Frown / Gold Chain
4, Demon, Male,, Hoodie / Pipe
5, Ape, Male, Blue, Cowboy Hat / Buck Teeth
6, Human, Male, 3, Cowboy Hat / Laser Eyes
7, Human, Male, 1, Cap Burger King
8, Vampire, Male,, Demon Horns
9, Human, Female, Orange, Crown
...
Rerun the script. Resulting in:
and the 4x version:
That's it.
Questions? Comments?
Post them over at the Help & Support page. Thanks.