NFT images generator using Python Jupyter Notebook
Tags: nft, crypto, blockchain, python
Published: 2021-08-29 17:16:56




## 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](https://www.python.org/downloads/)
- Install PIP
Download PIP get-pip.py
```
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py

python get-pip.py
```
- Install Python Pillow
```
pip install pillow
```

-  Install Python display
```
pip install display
```

- Install Jupyter Notebook
```
pip install jupyter 
```
- Set up developing folders similar to the following structure
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ef1de58qnovwvbtdz7jm.png)
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/93nfyxt6s896t7gkrdr4.jpg)
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4mqpwn5as53eoh464ffo.jpg)![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b237pci54l1f04tdcgrx.png)![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oeokb9pc6v6fvhjexntv.png)![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n2gh1y05blrj1gx08nlq.png)![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lwlfrypi7rztlahh11ko.png)
- Shift + right click => choose PowerShell

- Run Jupyter in your generator folder
```
jupyter notebook
```
- Choose New => Python 3 to create a new notebook

- Import necessary packages.
```python
from PIL import Image 
from IPython.display import display 
import random
import json
```

- Inject all the shapes and set their weights
```python
# 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", 
}

```

- Create a function to generate unique image combinations
```python
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)
```
- Return true if all images are unique
```python
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))
```
- Add token Id to each image
```python
i = 0
for item in all_images:
    item["tokenId"] = i
    i = i + 1
```
- Print all images
```python
print(all_images)
```
- Get traits count
```python
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)
```
- Generate Metadata for all Traits
```python
METADATA_FILE_NAME = './metadata/all-traits.json'; 
with open(METADATA_FILE_NAME, 'w') as outfile:
    json.dump(all_images, outfile, indent=4)
```
- Generate Images
```python
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)
```
- Generate Metadata for each Image
```python
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()
```

- 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](https://dev.to/victorquanlam/step-by-step-guide-to-nfts-creation-and-sale-for-beginners-using-opensea-4dm6) will show you how to upload your first nft  to Opensea. 

My latest [blog](https://dev.to/victorquanlam/generate-879-120-cryptopunk-nfts-with-javascript-nodejs-command-line-app-step-by-step-10hp) which shows you how to make an nft generator using JAVASCRIPT