{"id":21585417,"url":"https://github.com/cryptopunksnotdead/punks.whitelabel","last_synced_at":"2025-04-10T20:08:04.958Z","repository":{"id":4800305,"uuid":"5953412","full_name":"cryptopunksnotdead/punks.whitelabel","owner":"cryptopunksnotdead","description":"punks - the free white label quick starter edition -  (re)create from zero / scratch a pixel-perfect copy of the first Matt \u0026 John's® 10 000 punks collection (Anno 2017)","archived":false,"fork":false,"pushed_at":"2024-03-29T08:02:16.000Z","size":965,"stargazers_count":35,"open_issues_count":0,"forks_count":20,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-24T17:52:43.366Z","etag":null,"topics":["10000","24px","24x24","cryptopunks","cryptotulips","pixelart","punkverse"],"latest_commit_sha":null,"homepage":"https://cryptopunksnotdead.github.io","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc0-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cryptopunksnotdead.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2012-09-25T17:05:39.000Z","updated_at":"2024-03-25T22:06:46.000Z","dependencies_parsed_at":"2023-07-06T08:18:42.160Z","dependency_job_id":null,"html_url":"https://github.com/cryptopunksnotdead/punks.whitelabel","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cryptopunksnotdead%2Fpunks.whitelabel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cryptopunksnotdead%2Fpunks.whitelabel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cryptopunksnotdead%2Fpunks.whitelabel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cryptopunksnotdead%2Fpunks.whitelabel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cryptopunksnotdead","download_url":"https://codeload.github.com/cryptopunksnotdead/punks.whitelabel/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248288347,"owners_count":21078903,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["10000","24px","24x24","cryptopunks","cryptotulips","pixelart","punkverse"],"created_at":"2024-11-24T15:10:37.327Z","updated_at":"2025-04-10T20:08:04.935Z","avatar_url":"https://github.com/cryptopunksnotdead.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n---\n\n**Breaking News**  - Looking for the 100 Ordinal Punks collection inscribed into the bitcoin blockchain on February 9th, 2023?\nSee [**100 Ordinal Punks - The Free White Label Quick Starter Edition »**](https://github.com/ordinalpunks/ordinalpunks.starter)\n\n---\n\n\n\n\n\n\n\u003e Q: Dear sir, how do I get rich in ~bits-coin~ punks?\n\u003e\n\u003e A: If we all buy ~bits-coin~ punks from one another\n\u003e at ever higher prices we'll all be rich beyond our wildest dreams.\n\u003e\n\u003e 21 million bits-coin. 10 000 punks. Do the math.\n\n\n\n\n\n\n# Punks - The Free White Label Quick Starter Edition\n\nLet's (re)create from zero / scratch a pixel-perfect\ncopy of the Matt \u0026 John's® 10 000 punks collection (Anno 2017).\n\nYes, you can. Do-it-yourself (DIY) and\nown 100% forever your home-made free clean-room copy\nof the billion dollar (2400×2400) bitmap\nthat kicked-off\na trillion dollar get-rich-quick digital art\nmania / bubble in 2021 -\nselling \"decentralized\" ~blockchain tokens~\ndatabase records\nto ever greater fools at ever higher prices.\n\n\n\n##  Inside the Magic Money Machine - Mint 10 000 Unique Punks from 11 Archtetypes 'n' 122 Attributes\n\n\nLet's copy and (re)use all punk (building) blocks\nin the basic series (24×24):\n\n11 Archetypes:\n\nMale 1/2/3/4 ![](basic/male1.png)\n![](basic/male2.png)\n![](basic/male3.png)\n![](basic/male4.png),\nFemale 1/2/3/4 ![](basic/female1.png)\n![](basic/female2.png)\n![](basic/female3.png)\n![](basic/female4.png),\nZombie ![](basic/zombie.png),\nApe ![](basic/ape.png),\nAlien ![](basic/alien.png)\n\n\u003c!-- note:\n  sort attributes a-z for now - why? why not?\n--\u003e\n\n122 Attributes (by category and a-z):\n- Hat -\n  Bandana (m/f)\n  ![](basic/m/bandana.png)\n  ![](basic/f/bandana.png),\n  Beanie (m)\n  ![](basic/m/beanie.png),\n  Cap (m/f)\n  ![](basic/m/cap.png)\n  ![](basic/f/cap.png),\n  Cap Forward (m)\n  ![](basic/m/capforward.png),\n  Cowboy Hat (m)\n  ![](basic/m/cowboyhat.png),\n  Do-rag (m)\n  ![](basic/m/dorag.png),\n  Fedora (m)\n  ![](basic/m/fedora.png),\n  Headband (m/f)\n  ![](basic/m/headband.png)\n  ![](basic/f/headband.png),\n  Hoodie (m)\n  ![](basic/m/hoodie.png),\n  Knitted Cap (m/f)\n  ![](basic/m/knittedcap.png)\n  ![](basic/f/knittedcap.png),\n  Pilot Helmet (f)\n  ![](basic/f/pilothelmet.png),\n  Police Cap (m)\n  ![](basic/m/policecap.png),\n  Tassle Hat (f)\n  ![](basic/f/tasslehat.png),\n  Tiara (f)\n  ![](basic/f/tiara.png),\n  Top Hat (m)\n  ![](basic/m/tophat.png)\n- Hair -\n  Blonde Bob (f)\n  ![](basic/f/blondebob.png),\n  Blonde Short (f)\n  ![](basic/f/blondeshort.png),\n  Clown Hair Green (m/f)\n  ![](basic/m/clownhairgreen.png)\n  ![](basic/f/clownhairgreen.png),\n  Crazy Hair (m/f)\n  ![](basic/m/crazyhair.png)\n  ![](basic/f/crazyhair.png),\n  Dark Hair (f)\n  ![](basic/f/darkhair.png),\n  Frumpy Hair (m/f)\n  ![](basic/m/frumpyhair.png)\n  ![](basic/f/frumpyhair.png),\n  Half Shaved (f)\n  ![](basic/f/halfshaved.png),\n  Messy Hair (m/f)\n  ![](basic/m/messyhair.png)\n  ![](basic/f/messyhair.png),\n  Mohawk (m/f)\n  ![](basic/m/mohawk.png)\n  ![](basic/f/mohawk.png),\n  Mohawk Dark (m/f)\n  ![](basic/m/mohawkdark.png)\n  ![](basic/f/mohawkdark.png),\n  Mohawk Thin (m/f)\n  ![](basic/m/mohawkthin.png)\n  ![](basic/f/mohawkthin.png),\n  Orange Side (f)\n  ![](basic/f/orangeside.png),\n  Peak Spike (m)\n  ![](basic/m/peakspike.png),\n  Pigtails (f)\n  ![](basic/f/pigtails.png),\n  Pink With Hat (f)\n  ![](basic/f/pinkwithhat.png),\n  Purple Hair (m)\n  ![](basic/m/purplehair.png),\n  Red Mohawk (f)\n  ![](basic/f/redmohawk.png),\n  Shaved Head (m)\n  ![](basic/m/shavedhead.png),\n  Straight Hair (f)\n  ![](basic/f/straighthair.png),\n  Straight Hair Blonde (f)\n  ![](basic/f/straighthairblonde.png),\n  Straight Hair Dark (f)\n  ![](basic/f/straighthairdark.png),\n  Stringy Hair (m/f)\n  ![](basic/m/stringyhair.png)\n  ![](basic/f/stringyhair.png),\n  Vampire Hair (m)\n  ![](basic/m/vampirehair.png),\n  Wild Blonde (f)\n  ![](basic/f/wildblonde.png),\n  Wild Hair (m/f)\n  ![](basic/m/wildhair.png)\n  ![](basic/f/wildhair.png),\n  Wild White Hair (f)\n  ![](basic/f/wildwhitehair.png)\n- Eyes -\n  3D Glasses (m/f)\n   ![](basic/m/3dglasses.png)\n   ![](basic/f/3dglasses.png),\n  Big Shades (m/f)\n  ![](basic/m/bigshades.png)\n  ![](basic/f/bigshades.png),\n  Classic Shades (m/f)\n  ![](basic/m/classicshades.png)\n  ![](basic/f/classicshades.png),\n  Eye Mask (m/f)\n  ![](basic/m/eyemask.png)\n  ![](basic/f/eyemask.png),\n  Eye Patch (m/f)\n  ![](basic/m/eyepatch.png)\n  ![](basic/f/eyepatch.png),\n  Horned Rim Glasses (m/f)\n  ![](basic/m/hornedrimglasses.png)\n  ![](basic/f/hornedrimglasses.png),\n  Nerd Glasses (m/f)\n  ![](basic/m/nerdglasses.png)\n  ![](basic/f/nerdglasses.png),\n  Regular Shades (m/f)\n  ![](basic/m/regularshades.png)\n  ![](basic/f/regularshades.png),\n  Small Shades (m)\n  ![](basic/m/smallshades.png),\n  VR (m/f)\n  ![](basic/m/vr.png)\n  ![](basic/f/vr.png),\n  Welding Goggles (f)\n  ![](basic/f/weldinggoggles.png)\n- Eyes (Makeup) -\n  Blue Eye Shadow (f)\n  ![](basic/f/blueeyeshadow.png),\n  Clown Eyes Blue (m/f)\n  ![](basic/m/clowneyesblue.png)\n  ![](basic/f/clowneyesblue.png),\n  Clown Eyes Green (m/f)\n  ![](basic/m/clowneyesgreen.png)\n  ![](basic/f/clowneyesgreen.png),\n  Green Eye Shadow (f)\n  ![](basic/f/greeneyeshadow.png),\n  Purple Eye Shadow (f)\n  ![](basic/f/purpleeyeshadow.png)\n- Blemishes -\n  Mole (m/f)\n   ![](basic/m/mole.png)\n   ![](basic/f/mole.png),\n  Rosy Cheeks (m/f)\n   ![](basic/m/rosycheeks.png)\n   ![](basic/f/rosycheeks.png),\n  Spots (m/f)\n   ![](basic/m/spots.png)\n   ![](basic/f/spots.png)\n- Nose -\n  Clown Nose (m/f)\n   ![](basic/m/clownnose.png)\n   ![](basic/f/clownnose.png),\n- Ears -\n  Earring (m/f)\n   ![](basic/m/earring.png)\n   ![](basic/f/earring.png)\n- Mouth -\n  Buck Teeth (m)\n   ![](basic/m/buckteeth.png),\n  Frown (m)\n   ![](basic/m/frown.png),\n  Smile (m)\n   ![](basic/m/smile.png)\n- Mouth (Makeup) -\n  Black Lipstick (f)\n   ![](basic/f/blacklipstick.png),\n  Hot Lipstick (f)\n   ![](basic/f/hotlipstick.png),\n  Purple Lipstick (f)\n   ![](basic/f/purplelipstick.png)\n- Mouth Prop -\n  Cigarette (m/f)\n   ![](basic/m/cigarette.png)\n   ![](basic/f/cigarette.png),\n  Medical Mask (m/f)\n   ![](basic/m/medicalmask.png)\n   ![](basic/f/medicalmask.png),\n  Pipe (m/f)\n   ![](basic/m/pipe.png)\n   ![](basic/f/pipe.png),\n  Vape (m/f)\n   ![](basic/m/vape.png)\n   ![](basic/f/vape.png)\n- Beard -\n  Big Beard (m)\n   ![](basic/m/bigbeard.png),\n  Chinstrap (m)\n   ![](basic/m/chinstrap.png),\n  Front Beard (m)\n   ![](basic/m/frontbeard.png),\n  Front Beard Dark (m)\n   ![](basic/m/frontbearddark.png),\n  Goat (m)\n   ![](basic/m/goat.png),\n  Handlebars (m)\n   ![](basic/m/handlebars.png),\n  Luxurious Beard (m)\n   ![](basic/m/luxuriousbeard.png),\n  Mustache (m)\n   ![](basic/m/mustache.png),\n  Muttonchops (m)\n   ![](basic/m/muttonchops.png),\n  Normal Beard (m)\n   ![](basic/m/normalbeard.png),\n  Normal Beard Black (m)\n   ![](basic/m/normalbeardblack.png),\n  Shadow Beard (m)\n   ![](basic/m/shadowbeard.png)\n- Neck Accessory -\n  Choker (f)\n   ![](basic/f/choker.png),\n  Gold Chain (m/f)\n   ![](basic/m/goldchain.png)\n   ![](basic/f/goldchain.png),\n  Silver Chain (m/f)\n   ![](basic/m/silverchain.png)\n   ![](basic/f/silverchain.png)\n\n\n\u003c!-- break --\u003e\n\n(Source: [Punk (Building) Blocks - Basic Series (24×24)](https://github.com/cryptopunksnotdead/punks.blocks#basic-punk-series-2424))\n\n\n\nLet's wipe up a `generate_punk`\nmethod that\npastes / composes together\nthe building blocks / attributes and returns\na ready-to-save image. Example:\n\n\n``` ruby\n# generate punk #0\npunk = generate_punk( 'Female 2', 'Earring', 'Blonde Bob', 'Green Eye Shadow' )\npunk.save( \"./tmp/punk0.png\" )\npunk.zoom(20).save( \"./tmp/punk0@20x.png\" )\n\n# generate punk #1\npunk = generate_punk( 'Male 1', 'Smile', 'Mohawk' )\npunk.save( \"./tmp/punk1.png\" )\npunk.zoom(20).save( \"./tmp/punk1@20x.png\" )\n```\n\n\nHere we go - the billion dollar formula:\n\n``` ruby\nrequire 'pixelart'\n\n\ndef normalize( str )\n  ## allow (ignore):\n  ##    space ( ),\n  ##    underscore (_),\n  ##    dash (-)\n  str.downcase.gsub( /[ _-]/, '' ).strip\nend\n\n\ndef generate_punk( *values, dir: \"./basic\" )\n  punk_type       = values[0]\n  attribute_names = values[1..-1]\n\n  punk_type = normalize( punk_type )\n  path      = \"#{dir}/#{punk_type}.png\"\n  punk = Image.read( path )\n\n  m_or_f = if punk_type.index( 'female' )\n             'f'\n           else\n             'm'\n           end\n\n  attribute_names.each do |attribute_name|\n     next if attribute_name.nil? || attribute_name.empty?  ## note: skip nil/empty attributes\n\n     attribute_name = normalize( attribute_name )\n     path           = \"#{dir}/#{m_or_f}/#{attribute_name}.png\"\n     attribute      = Image.read( path )\n\n     punk.compose!( attribute )\n  end\n\n  punk\nend # method generate\n```\n\n\nLet's test drive punk #0 and punk 1 (see above)\nand voila! In the original 24×24 format:\n\n\n![](i/punk0.png)\n![](i/punk1.png)\n\n\nAnd 20x (480×480):\n\n![](i/punk0@20x.png)\n![](i/punk1@20x.png)\n\n\n\nNote: If you use your own building blocks\nmake sure your type and attribute names\nmatch the filenames (without the `.png` extension).\nFor the matching algorithm all names\nget automatically downcased and all spaces deleted,\nthus,\n`Male 1` will map to `male1.png` ![](basic/male1.png)\nand `3D Glasses` to `3dglasses.png` ![](basic/m/3dglasses.png)\nand `Knitted Cap` to `knittedcap.png` ![](basic/m/knittedcap.png)\nand so on.\n\n\n\n\n\n\nLet's read-in all meta data records for all 10 000 punks.\nSee the [punks.csv](punks.csv) dataset that reads:\n\n```\ntype, attribute1, attribute2, attribute3, attribute4, attribute5, attribute6, attribute7\nFemale 2, Earring, Blonde Bob, Green Eye Shadow,,,,\nMale 1, Smile, Mohawk,,,,,\nFemale 3, Wild Hair,,,,,,\nMale 1, Wild Hair, Pipe, Nerd Glasses,,,,\nMale 2, Goat, Earring, Wild Hair, Big Shades,,,\nFemale 2, Earring, Half Shaved, Purple Eye Shadow,,,,\nMale 2, Do-rag,,,,,,\nFemale 2, Spots, Wild White Hair, Clown Eyes Blue,,,,\nMale 1, Luxurious Beard, Messy Hair,,,,,\nMale 2, Big Beard, Police Cap, Clown Nose,,,,\nFemale 1, Mohawk, Blue Eye Shadow,,,,,\nFemale 2, Black Lipstick, Straight Hair Dark, Clown Eyes Green,,,,\n...\n```\n\n\nLet's try:\n\n``` ruby\nrequire 'csvreader'\n\nrecs = CsvHash.read( './punks.csv' )\nputs \"#{recs.size} punk(s)\"\n#=\u003e 10 000 punk(s)\n```\n\n\nAnd to wrap up let's loop over all 10 000 punks\nand generate a 24×24 version and a 20x zoom, that is,\n480×480. Let's go:\n\n\n``` ruby\nrecs.each_with_index do |rec,i|\n  puts \"==\u003e punk #{i}:\"\n  pp rec\n\n  values = rec.values\n  punk = generate_punk( *values )\n\n  name = \"punk#{i}\"\n\n  punk.save( \"./o/#{name}.png\" )\n  punk.zoom(20).save( \"./o/#{name}@20x.png\" )\nend\n```\n\nYes, that's it.\nIn the `/o` directory you will now find\ntwo images per punk - in the orginal format, that is, 24×24\nand 20x, that is, 480×480 - and get:\n\n```\no/\n  punk0.png\n  punk0@20x.png\n  punk1.png\n  punk1@20x.png\n  punk2.png\n  punk2@20x.png\n  punk3.png\n  punk3@20x.png\n  punk4.png\n  punk4@20x.png\n  punk5.png\n  punk5@20x.png\n  punk6.png\n  punk6@20x.png\n  punk7.png\n  punk7@20x.png\n  punk8.png\n  punk8@20x.png\n  ...\n```\n\nLet's open up the first hundred punks, that is, `punk0.png` to `punk99.png`:\n\n![](i/punk0.png)\n![](i/punk1.png)\n![](i/punk2.png)\n![](i/punk3.png)\n![](i/punk4.png)\n![](i/punk5.png)\n![](i/punk6.png)\n![](i/punk7.png)\n![](i/punk8.png)\n![](i/punk9.png)\n![](i/punk10.png)\n![](i/punk11.png)\n![](i/punk12.png)\n![](i/punk13.png)\n![](i/punk14.png)\n![](i/punk15.png)\n![](i/punk16.png)\n![](i/punk17.png)\n![](i/punk18.png)\n![](i/punk19.png)\n![](i/punk20.png)\n![](i/punk21.png)\n![](i/punk22.png)\n![](i/punk23.png)\n![](i/punk24.png)\n![](i/punk25.png)\n![](i/punk26.png)\n![](i/punk27.png)\n![](i/punk28.png)\n![](i/punk29.png)\n![](i/punk30.png)\n![](i/punk31.png)\n![](i/punk32.png)\n![](i/punk33.png)\n![](i/punk34.png)\n![](i/punk35.png)\n![](i/punk36.png)\n![](i/punk37.png)\n![](i/punk38.png)\n![](i/punk39.png)\n![](i/punk40.png)\n![](i/punk41.png)\n![](i/punk42.png)\n![](i/punk43.png)\n![](i/punk44.png)\n![](i/punk45.png)\n![](i/punk46.png)\n![](i/punk47.png)\n![](i/punk48.png)\n![](i/punk49.png)\n![](i/punk50.png)\n![](i/punk51.png)\n![](i/punk52.png)\n![](i/punk53.png)\n![](i/punk54.png)\n![](i/punk55.png)\n![](i/punk56.png)\n![](i/punk57.png)\n![](i/punk58.png)\n![](i/punk59.png)\n![](i/punk60.png)\n![](i/punk61.png)\n![](i/punk62.png)\n![](i/punk63.png)\n![](i/punk64.png)\n![](i/punk65.png)\n![](i/punk66.png)\n![](i/punk67.png)\n![](i/punk68.png)\n![](i/punk69.png)\n![](i/punk70.png)\n![](i/punk71.png)\n![](i/punk72.png)\n![](i/punk73.png)\n![](i/punk74.png)\n![](i/punk75.png)\n![](i/punk76.png)\n![](i/punk77.png)\n![](i/punk78.png)\n![](i/punk79.png)\n![](i/punk80.png)\n![](i/punk81.png)\n![](i/punk82.png)\n![](i/punk83.png)\n![](i/punk84.png)\n![](i/punk85.png)\n![](i/punk86.png)\n![](i/punk87.png)\n![](i/punk88.png)\n![](i/punk89.png)\n![](i/punk90.png)\n![](i/punk91.png)\n![](i/punk92.png)\n![](i/punk93.png)\n![](i/punk94.png)\n![](i/punk95.png)\n![](i/punk96.png)\n![](i/punk97.png)\n![](i/punk98.png)\n![](i/punk99.png)\n\n\nAnd let's have a looksie at the biggie 20x (480×480) versions:\n\n\n![](i/punk0@20x.png)\n![](i/punk1@20x.png)\n\nand so on.\n\n\n\n\n## Bonus -  Generate an All-In-One (2400×2400) Composite Image\n\nLet's generate an all-in-one composite image holding the complete\ncollection of 10 000 punks in a 100×100 grid.\n\n``` ruby\npunks = CompositeImage.new( 100, 100 )\n\nrecs.each_with_index do |rec,i|\n  values = rec.values\n  punk = generate_punk( *values )\n\n  punks \u003c\u003c punk\nend\n\npunks.save( \"./o/punks.png\" )\n```\n\n\nYes, that's it.\nOpen up `punks.png` to have a looksie.\n\n![](i/punks-preview.png)\n\n\nNote: Only showing the first one hundred punks as a preview.\nDownload [**punks.png**](i/punks.png) ~800k for the full monty.\n\n\n\n## Questions? Comments?\n\nPost them on the [D.I.Y. Punk (Pixel) Art reddit](https://old.reddit.com/r/DIYPunkArt). Thanks.\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcryptopunksnotdead%2Fpunks.whitelabel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcryptopunksnotdead%2Fpunks.whitelabel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcryptopunksnotdead%2Fpunks.whitelabel/lists"}