Unique image & metadata generation using weighted layer collections.

Overview

nft-generator-py

nft-generator-py is a python based NFT generator which programatically generates unique images using weighted layer files. The program is simple to use, and new layers can be added by adding a new layer object and adding names, weights, and image files to the object. You can View The Demo here.

How it works

  • A call to generate_unique_images(amount, config) is made, which is the meat of the application where all the processing happens.
  • The config object is read and for each object in the layers list, random values are selected and checked for uniqueness against all previously generated metadata files.
  • Once we have amount unique tokens created, we layer them against eachother and output them and their metadata to their respective folders, ./metadata and ./images.

Configuration

{
  "layers": [
    {
      "name": "Background",
      "values": ["Blue", "Orange", "Purple", "Red", "Yellow"],
      "trait_path": "./trait-layers/backgrounds",
      "filename": ["blue", "orange", "purple", "red", "yellow"],
      "weights": [30, 45, 15, 5, 10]
    },
    ...
  ],
  "name": "NFT #"
}

The config object is a dict that contains layers and name objects that can be changed to produce different outputs when running the program. Within metadata files, tokens are named using the configuration's name parameter.

  • In ascending order, tokenIds are appended to the name resulting in NFT metadata names such as NFT #0001.
  • tokenIds are padded to the largest amount generated. IE, generating 999 objects will result in names NFT #001, using the above configuration, and generating 1000 objects will result in NFT #0001.

The layers list contains layer objects that define the layers for the program to use when generating unique tokens. Each layer has a name, which will be displayed as an attribute, values, trait_path, filename, and weights.

  • trait_path refers to the path where the image files in filename can be found. Please note that filenames omit .png, and it will automatically be prepended.

  • weight corresponds with the percent chance that the specific value that weight corresponds to will be selected when the program is run. The weights must add up to 100, or the program will fail.

Troubleshooting

  • All images should be in .png format.
  • All images should be the same size in pixels, IE: 1000x1000.
  • The weight values for each attribute should add up to equal 100.

Credits

This project is completely coded by Jonathan Becker, using no external libraries.

Comments
  • incompatibilities not working for me

    incompatibilities not working for me

    dear friend,

    could not figure out why the incompatibilities is not working for me. is this feature still in development or should it work as described ? help would be much appreciated

    thank you

    
        {
          "name": "BOTS",
          "values": ["Bombed", "Doodle", "Gold", "Green", "Grey", "Ironman", "Rot", "Wood", "Yellow", "Zombie"],
          "trait_path": "./trait-layers/2_BOTS",
          "filename": ["Bombed", "Doodle", "Gold", "Green", "Grey", "Ironman", "Rot", "Wood", "Yellow", "Zombie"],
          "weights": [8, 12, 2, 15, 15, 6, 15, 7, 15, 5]
        },
    	{
          "name": "EYES",
          "values": ["Bullaugen", "Eyes_human", "Hawt_Augen", "Schlitzauge", "Tearsdrops"],
          "trait_path": "./trait-layers/4_EYES",
          "filename": ["Bullaugen", "Eyes_human", "Hawt_Augen", "Schlitzauge", "Tearsdrops"],
          "weights": [20, 20, 20, 20, 20]
        },
    	
    	
    	...
    	
    	
    	 "incompatibilities": [
        {"layer": "BOTS", "value": "Ironman", "incompatible_with": ["Bullaugen"]},
        {"layer": "BOTS", "value": "Ironman", "incompatible_with": ["Eyes_human"]},
        {"layer": "BOTS", "value": "Ironman", "incompatible_with": ["Hawt_Augen"]},
        {"layer": "BOTS", "value": "Ironman", "incompatible_with": ["Schlitzauge"]},
        {"layer": "BOTS", "value": "Ironman", "incompatible_with": ["Tearsdrops"]}
    
      ],
    
    
    invalid issue 
    opened by Stadtrausch 12
  • Cant Generate

    Cant Generate

    Hello, First of all thank you for amazing work.

    I'm very noobie, first time trying to do something in .py.

    I just wanted to check if your generator engine is work. I didn't change anything, but all the time have same error

    Exception has occurred: ModuleNotFoundError No module named 'PIL' File "/Users/petre/Desktop/NFT-PY/index.py", line 2, in from PIL import Image

    Could you help me?

    invalid question 
    opened by PetreEP 7
  • Script to update JSON file with proper IPFS Data for images

    Script to update JSON file with proper IPFS Data for images

    Feature Request:

    When deploying the NFT images and metadata to IPFS, it is necessary to first upload the images (and get a unique CID). Then I need to update the JSON files to point at this CID. I can not create the CID in advance of running the generative script (index.py) as I do not have the CID until I upload the images.

    Could a script be added to run after the index.py & once I get the CID to go through all files in the metadata folder and update the baseURI to represent the IPFS CID? (Or regenerate them based on all-object.json?) Obviously the data needs to maintain the connection to the image.

    question issue 
    opened by stocktonellis 7
  • Config Error

    Config Error

    Getting this error when just trying to run the included default settings:

    At line:1 char:30

    • generate_unique_images(amount, config)
    •                          ~
      

    Missing argument in parameter list. + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : MissingArgument

    question 
    opened by ccislegend 6
  • Getting List index out of range error.

    Getting List index out of range error.

    When I try to run the program with my attributes, I keep getting this error: Not sure why? I did add more traits and values than the original. Any ideas?

    % python3 index.py

    Traceback (most recent call last): File "/Users/NAME/Desktop/nft-generator/index.py", line 83, in generate_unique_images(8888, { File "/Users/NAME/Desktop/nft-generator/index.py", line 28, in generate_unique_images trait_files[trait["name"]][key] = trait["filename"][x]; IndexError: list index out of range

    opened by stocktonellis 6
  • Invalid syntax in index.py file

    Invalid syntax in index.py file

    Syntax errors detected :

    Line 67: layers[index] = Image.open(f'{config["layers"][index]["trait_path"]}/{trait_files[attr][item[attr]]}.png').convert('RGBA') ^ SyntaxError: invalid syntax

    Any idea how to resolve? Thanks

    invalid issue 
    opened by nickgag626 5
  • Trait counter

    Trait counter

    I added code to count and write used traits to JSON file.

    from collections import Counter
    
    all_token_rarity = []
    for layer in config["layers"]:
      all_token_rarity.append({ layer["name"]: Counter(image[layer["name"]] for image in all_images) })
    
    with open('./metadata/all-rarity.json', 'w') as outfile:
       json.dump(all_token_rarity, outfile, indent=4)
    

    Maybe someone find it useful.

    enhancement 
    opened by mwkemo 4
  • Metadata issue

    Metadata issue

    Hey, Everything works fine, except metadata name and token id inside. For exmp. When 5 image generation have completed I've got:

    In image Folder: 1,2,3,4,5

    In metadata Folder: 0,1,2,3,4 and all objects.

    I have qustion if it's possible to match token id number to metadata number.

    Thanks,

    Petrre

    invalid issue 
    opened by PetreEP 4
  • it is not possible to generate more than 5 nft with my config.

    it is not possible to generate more than 5 nft with my config.

    the process simply dies if I set a value greater than 5, and with a standard code greater than 20 is not generated "The kernel 'Python 3.10.2 64-bit' died. " `generate_unique_images(5, { "layers": [ { "name": "Background", "values": ["Common", "Uncommon", "Rare", "Epic", "Legendary"], "trait_path": "./trait-layers/backgrounds", "filename": ["blue", "orange", "purple", "red", "yellow"], "weights": [40,35,15,9,1] }, { "name": "Foreground", "values": ["Qw, "Qs","Qe","Qr","Qt" ], "trait_path": "./trait-layers/foreground", "filename": ["qw", "qs", "qe", "qr", "qt"], "weights": [20,20,20,20,20] },

    ], "incompatibilities": [ { "layer": "Foreground", "value": "Qw", "incompatible_with": ["Uncommon", "Rare", "Epic", "Legendary"] }, { "layer": "Foreground", "value": "Qs", "incompatible_with": ["Common", "Rare", "Epic", "Legendary"] }, { "layer": "Foreground", "value": "Qe", "incompatible_with": ["Common", "Uncommon", "Epic", "Legendary"] }, { "layer": "Foreground", "value": "Qr", "incompatible_with": ["Common", "Uncommon", "Rare", "Legendary"] }, { "layer": "Foreground", "value": "Qt", "incompatible_with": ["Common", "Uncommon", "Rare", "Epic"] }, ], "baseURI": ".", "name": "NFT #", "description": "Generation 0" })`

    duplicate 
    opened by Puffini 4
  • Increasing amount causes failure after adding more incompatibilities

    Increasing amount causes failure after adding more incompatibilities

    Hi there, thanks for providing this resource. It helps for learning. Testing, I have been growing the number of incompatibilities between traits and layers. Removing a few target blocks of incompatibilities, you can generate 1000 or more. Adding those sections back will see premature finish with exit code -1073741571 (0xC00000FD) However you can then generate about 200 but exceeding that will again result in EC: -1073741571 (0xC00000FD)

    Does it need more assets in this situation due to growing the number of incompatibilities limiting the total number of possible outcomes below 200?

    bug 
    opened by Atekom 4
  • Value Error:('The number of weights does not match the population')

    Value Error:('The number of weights does not match the population')

    So there's a weird error that happened when I tried to run the code with my own images, I posted my images here but I'm just not sure how to solve this, can someone help? <img width="1440" alt="Screen Shot 2021-09-17 at 11 19 17 AM" src="https://user-images.githubusercontent.com/33333641/133808013-e61d9217-4c78-47b8-9292-befa276b09df.png" Screen Shot 2021-09-17 at 11 19 11 AM Screen Shot 2021-09-17 at 11 19 05 AM Screen Shot 2021-09-17 at 11 19 04 AM Screen Shot 2021-09-17 at 11 18 58 AM

    help wanted 
    opened by awesomekid1021 4
  • Simple script to generate the config.json!

    Simple script to generate the config.json!

    File should be placed in the main directory, the script will then scrape all the files in ./trait-layers to generate a baseline config with balanced rarities.

    opened by whosman 3
  • Weights for layer groups

    Weights for layer groups

    Would be great to add support for weights for layer groups. Lets say we have following layer groups:

    Background - always render Body - always render Head - always render Hats - render only on 20% of images Glasses - render only on 10% of images

    btw. love your script, really nicely done.

    enhancement 
    opened by mwkemo 3
Releases(v2.0.0)
  • v2.0.0(May 2, 2022)

    What's Changed

    • [#17] Adding requirements file by @elyak123 in https://github.com/Jon-Becker/nft-generator-py/pull/18
    • fixed an issue which uses a wrong variable name by @AlexLisong in https://github.com/Jon-Becker/nft-generator-py/pull/22
    • Substitute convert('RGB') for convert('RGBA') by @menezesphill in https://github.com/Jon-Becker/nft-generator-py/pull/33

    New Contributors

    • @elyak123 made their first contribution in https://github.com/Jon-Becker/nft-generator-py/pull/18
    • @AlexLisong made their first contribution in https://github.com/Jon-Becker/nft-generator-py/pull/22
    • @menezesphill made their first contribution in https://github.com/Jon-Becker/nft-generator-py/pull/33

    Full Changelog: https://github.com/Jon-Becker/nft-generator-py/compare/v1.0.2...v2.0.0

    Source code(tar.gz)
    Source code(zip)
  • v1.0.2-beta1(Mar 18, 2022)

  • v1.0.2(Nov 8, 2021)

  • v1.0.1(Nov 2, 2021)

  • stable(Sep 1, 2021)

Owner
Jonathan Becker
Developer & Designer
Jonathan Becker
A little Python tool to convert a TrueType (ttf/otf) font into a PNG for use in demos.

font2png A little Python tool to convert a TrueType (ttf/otf) font into a PNG for use in demos. To use from command line it expects python3 to be at /

Rich Elmes 3 Dec 22, 2021
The ctypes-based simple ImageMagick binding for Python

Wand Wand is a ctypes-based simple ImageMagick binding for Python, supporting 2.7, 3.3+, and PyPy. All functionalities of MagickWand API are implement

Eric McConville 1.2k Dec 30, 2022
Hello, this project is an example of how to generate a QR Code using python 😁

Hello, this project is an example of how to generate a QR Code using python 😁

Davi Antonaji 2 Oct 12, 2021
Python script to generate vector graphics of an oriented lattice unit cell

unitcell Python script to generate vector graphics of an oriented lattice unit cell Examples unitcell --type hexagonal --eulers 12 23 34 --axes --crys

Philip Eisenlohr 2 Dec 10, 2021
Cat avatars for adult independent users

Cat avatars for adult independent users Samples (Natasha, wake up!) Usage Check values from https://shantichat.github.io/avacats/index.json: { "sizes"

4 Nov 05, 2021
🎢😀 Generate an image indicating what you are listening to 😳

I'm Listening to This (song that I've sent you an image about detailing its metadata in a nifty way) Few lines describing your project. πŸ“ Table of Co

Connor B - Viibrant 4 Nov 03, 2021
PyPixelArt - A keyboard-centered pixel editor

PyPixelArt - A keyboard-centered pixel editor The idea behind PyPixelArt is uniting: a cmdpxl inspired pixel image editor applied to pixel art. vim 's

Douglas 18 Nov 14, 2022
Xmas-Tree-GIF-Tool - Convert any given animated gif file into an animation in GIFT CSV format

This repo is made to participate in Matt Parker's XmasTree 2021 event. Convert a

Aven Zitzelberger 2 Dec 30, 2021
Detecting haze image with hazer.

hazer-py Detecting haze image with hazer. What is hazer Hazer is a lib for getting "haze degree". This repository is python version of hazer: https://

Joey777210 2 Dec 27, 2021
Computational Xmas Tree lights!

Computational Xmas Tree This repo contains the code for the computational illumination of a Christmas Tree! It is based on the work by Matt Parker fro

GSD6338 146 Dec 23, 2022
Anime2Gif - an algorithm that detects scenes in a video and generates gifs from it

Anime2Gif Anime2Gif is an algorithm that detects scenes in a video and generates gifs from it. How to use To use it, first, you'll need to install it'

1 Dec 09, 2021
γŠ™οΈ Create standard barcodes with Python. No external dependencies. 100% Organic Python.

python-barcode python-barcode provides a simple way to create barcodes in Python. There are no external dependencies when generating SVG files. Pillow

Hugo Barrera 419 Dec 26, 2022
Tweet2Image - Convert tweets to Instagram-friendly images.

Convert tweets to Instagram-friendly images. How to use If you want to use this repository as a submodule, don't forget to put the fonts d

Janu Lingeswaran 1 Mar 11, 2022
Python modules to work with large multiresolution images.

Large Image Python modules to work with large, multiresolution images. Large Image is developed and maintained by the Data & Analytics group at Kitwar

Girder 136 Jan 02, 2023
Short piece of code to create a rainbow gif of gradual contours from two shapefiles

rainbow-elevation-gif Short piece of code to create a rainbow gif of gradual con

Jess Roberts 6 Jan 17, 2022
Python pygame project that turns your images to matrix rain

Matrix-Rain-An-Image This project implements the classic Matrix digital rain effect in python with pygame to build up an image provided with multiple

7 Dec 11, 2022
Fuzzware is a project for automated, self-configuring fuzzing of firmware images

Fuzzware Fuzzware is a project for automated, self-configuring fuzzing of firmware images. The idea of this project is to configure the memory ranges

190 Dec 21, 2022
Kimimaro: Skeletonize Densely Labeled Images

Kimimaro: Skeletonize Densely Labeled Images # Produce SWC files from volumetric images. kimimaro forge labels.npy --progress # writes to ./kimimaro_o

92 Dec 17, 2022
A Blender add-on to create interesting meshes using symmetry

Procedural Symmetries This Blender add-on automates the process of iteratively applying a set of reflection planes to a base mesh. The result will con

1 Dec 29, 2021
A Python Script to convert Normal PNG Image to Apple iDOT PNG Image.

idot-png-encoder A Python Script to convert Normal PNG Image to Apple iDOT PNG Image (Multi-threaded Decoding PNG). Usage idotpngencoder.py -i inputf

Lrdcq 2 Feb 17, 2022