NFT images generator using Python Jupyter Notebook

victorquanlam

Victor Quan Lam

Posted on August 29, 2021

NFT images generator using Python Jupyter Notebook

Generate NFT images using python and Jupyter Notebook

Let develop a nft image generator which generates a series of unique images using a collection of layers.

  • Install Python
  • Install PIP Download PIP get-pip.py
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py

python get-pip.py
Enter fullscreen mode Exit fullscreen mode
  • Install Python Pillow
pip install pillow
Enter fullscreen mode Exit fullscreen mode
  • Install Python display
pip install display
Enter fullscreen mode Exit fullscreen mode
  • Install Jupyter Notebook
pip install jupyter 
Enter fullscreen mode Exit fullscreen mode
  • Set up developing folders similar to the following structure Alt Text Alt Text Alt TextAlt TextAlt TextAlt TextAlt Text
  • Shift + right click => choose PowerShell

  • Run Jupyter in your generator folder

jupyter notebook
Enter fullscreen mode Exit fullscreen mode
  • Choose New => Python 3 to create a new notebook

  • Import necessary packages.

from PIL import Image 
from IPython.display import display 
import random
import json
Enter fullscreen mode Exit fullscreen mode
  • Inject all the shapes and set their weights
# Each image is made up a series of traits
# The weightings for each trait drive the rarity and add up to 100%

background = ["Blue", "Orange"] 
background_weights = [30, 70]

circle = ["Blue", "Orange"] 
circle_weights = [30, 70]

square = ["Blue","Orange"] 
square_weights = [30, 70]

# Dictionary variable for each trait. 
# Eech trait corresponds to its file name
# Add more shapes and colours as you wish

background_files = {
    "Blue": "blue",
    "Orange": "orange",
}

square_files = {
    "Blue": "blue-square",
    "Orange": "orange-square",     
}

circle_files = {
    "Blue": "blue-circle",
    "Orange": "orange-circle", 
}

Enter fullscreen mode Exit fullscreen mode
  • Create a function to generate unique image combinations
TOTAL_IMAGES = 8 # Number of random unique images we want to generate ( 2 x 2 x 2 = 8)

all_images = [] 

def create_new_image():

    new_image = {} #

    # For each trait category, select a random trait based on the weightings 
    new_image ["Background"] = random.choices(background, background_weights)[0]
    new_image ["Circle"] = random.choices(circle, circle_weights)[0]
    new_image ["Square"] = random.choices(square, square_weights)[0]

    if new_image in all_images:
        return create_new_image()
    else:
        return new_image


# Generate the unique combinations based on trait weightings
for i in range(TOTAL_IMAGES): 

    new_trait_image = create_new_image()

    all_images.append(new_trait_image)
Enter fullscreen mode Exit fullscreen mode
  • Return true if all images are unique
def all_images_unique(all_images):
    seen = list()
    return not any(i in seen or seen.append(i) for i in all_images)

print("Are all images unique?", all_images_unique(all_images))
Enter fullscreen mode Exit fullscreen mode
  • Add token Id to each image
i = 0
for item in all_images:
    item["tokenId"] = i
    i = i + 1
Enter fullscreen mode Exit fullscreen mode
  • Print all images
print(all_images)
Enter fullscreen mode Exit fullscreen mode
  • Get traits count
background_count = {}
for item in background:
    background_count[item] = 0

circle_count = {}
for item in circle:
    circle_count[item] = 0

square_count = {}
for item in square:
    square_count[item] = 0

for image in all_images:
    background_count[image["Background"]] += 1
    circle_count[image["Circle"]] += 1
    square_count[image["Square"]] += 1

print(background_count)
print(circle_count)
print(square_count)
Enter fullscreen mode Exit fullscreen mode
  • Generate Metadata for all Traits
METADATA_FILE_NAME = './metadata/all-traits.json'; 
with open(METADATA_FILE_NAME, 'w') as outfile:
    json.dump(all_images, outfile, indent=4)
Enter fullscreen mode Exit fullscreen mode
  • Generate Images
for item in all_images:

    im1 = Image.open(f'./layers/backgrounds/{background_files[item["Background"]]}.jpg').convert('RGBA')
    im2 = Image.open(f'./layers/circles/{circle_files[item["Circle"]]}.png').convert('RGBA')
    im3 = Image.open(f'./layers/squares/{square_files[item["Square"]]}.png').convert('RGBA')

    #Create each composite
    com1 = Image.alpha_composite(im1, im2)
    com2 = Image.alpha_composite(com1, im3)

    #Convert to RGB
    rgb_im = com2.convert('RGB')
    file_name = str(item["tokenId"]) + ".png"
    rgb_im.save("./images/" + file_name)
Enter fullscreen mode Exit fullscreen mode
  • Generate Metadata for each Image
f = open('./metadata/all-traits.json',) 
data = json.load(f)

IMAGES_BASE_URI = "ADD_IMAGES_BASE_URI_HERE"
PROJECT_NAME = "ADD_PROJECT_NAME_HERE"

def getAttribute(key, value):
    return {
        "trait_type": key,
        "value": value
    }
for i in data:
    token_id = i['tokenId']
    token = {
        "image": IMAGES_BASE_URI + str(token_id) + '.png',
        "tokenId": token_id,
        "name": PROJECT_NAME + ' ' + str(token_id),
        "attributes": []
    }
    token["attributes"].append(getAttribute("Background", i["Background"]))
    token["attributes"].append(getAttribute("Circle", i["Circle"]))
    token["attributes"].append(getAttribute("Square", i["Square"]))

    with open('./metadata/' + str(token_id), 'w') as outfile:
        json.dump(token, outfile, indent=4)
f.close()
Enter fullscreen mode Exit fullscreen mode
  • It will output all the generated images to the /images folder, and the metadata to the /metadata folder. The filenames will refer to tokenIds.

This blog will show you how to upload your first nft to Opensea.

My latest blog which shows you how to make an nft generator using JAVASCRIPT

💖 💪 🙅 🚩
victorquanlam
Victor Quan Lam

Posted on August 29, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related