A million-dollar NFT production tutorial (Python version)

As time goes on, the field of digital collections is getting hotter and hotter. When a cryptopunk avatar was sold to Visa for $150,000, people gradually got to know NFT through various channels.

5b525f560db4e98e84171679c145bdba.png

methodology

The approach behind this generator is simple. Create a unique avatar by combining different traits.

22b92358b6ef4bf128d7ea7fe851940e.png

get your data

You will usetech-llcuse "Substrapunks "data from the repository of .

Download their repository at the link below and extract the zip file to your local computer.

https://github.com/usetech-llc/substrapunks/archive/refs/heads/master.zip

import package

You will use the following packages in this project:

  • PIL

  • IPython

  • random

  • Json

  • OS

from PIL import Image 
from IPython.display import display
import random
import json
import os

Specifies the rarity of NFT properties

Each unique avatar is made up of five characteristics.

  • Face

  • Ears

  • Hair

  • Mouth

  • Nose

Rarity matters because it creates scarcity, which in turn creates value. You will achieve rarity in a feature by assigning weights to the different types in a feature. The sum of the weights should always be 100.

There are two types of faces (black and white). You can stipulate in the program that a picture has a 60% chance of getting a white face and a 40% chance of getting a black face.

# Each image is made up a series of traits
# The weightings for each trait drive the rarity and add up to 100%
face = ["White", "Black"]
face_weights = [60, 40]
ears = ["No Earring", "Left Earring", "Right Earring", "Two Earrings"]
ears_weights = [25, 30, 44, 1]
eyes = ["Regular", "Small", "Rayban", "Hipster", "Focused"]
eyes_weights = [70, 10, 5 , 1 , 14]
hair = ['Up Hair', 'Down Hair', 'Mohawk', 'Red Mohawk', 'Orange Hair', 'Bubble Hair', 'Emo Hair',
 'Thin Hair',
 'Bald',
 'Blonde Hair',
 'Caret Hair',
 'Pony Tails']
hair_weights = [10 , 10 , 10 , 10 ,10, 10, 10 ,10 ,10, 7 , 1 , 2]
mouth = ['Black Lipstick', 'Red Lipstick', 'Big Smile', 'Smile', 'Teeth Smile', 'Purple Lipstick']
mouth_weights = [10, 10,50, 10,15, 5]
nose = ['Nose', 'Nose Ring']
nose_weights = [90, 10]

Categorize Features

The dictionary is used to redirect feature names to their filenames. You can find the signature filenames in:

...\substrapunks-master\scripts\face_parts\ 。

The property name "White" is directed to face1 and "Black" is directed to face2.

01855395d51c4300d6e36dc961d53ab3.png

#Classify traits
face_files = {
    "White": "face1",
    "Black": "face2"
}
ears_files = {
    "No Earring": "ears1",
    "Left Earring": "ears2",
    "Right Earring": "ears3",
    "Two Earrings": "ears4"
}
eyes_files = {
    "Regular": "eyes1",
    "Small": "eyes2",
    "Rayban": "eyes3",
    "Hipster": "eyes4",
    "Focused": "eyes5"     
}
hair_files = {
    "Up Hair": "hair1",
    "Down Hair": "hair2",
    "Mohawk": "hair3",
    "Red Mohawk": "hair4",
    "Orange Hair": "hair5",
    "Bubble Hair": "hair6",
    "Emo Hair": "hair7",
    "Thin Hair": "hair8",
    "Bald": "hair9",
    "Blonde Hair": "hair10",
    "Caret Hair": "hair11",
    "Pony Tails": "hair12"
}
mouth_files = {
    "Black Lipstick": "m1",
    "Red Lipstick": "m2",
    "Big Smile": "m3",
    "Smile": "m4",
    "Teeth Smile": "m5",
    "Purple Lipstick": "m6"
}
nose_files = {
    "Nose": "n1",
    "Nose Ring": "n2"   
}

define image properties

Each avatar you'll create will be a combination of six images: face, nose, mouth, ears, and eyes.

Therefore, you can write a for loop to combine these features into a picture and specify the total number of pictures.

A function creates a dictionary for each image specifying which features it has.

These features are given in terms of random.choice()the function .

This function iterates over the list of face features (white, black) and returns either white (60% chance) or black (40% chance).

## Generate Traits
TOTAL_IMAGES = 100 # Number of random unique images we want to generate
all_images = [] 
# A recursive function to generate unique image combinations
def create_new_image():
    new_image = {} #
    # For each trait category, select a random trait based on the weightings
    new_image ["Face"] = random.choices(face, face_weights)[0]
    new_image ["Ears"] = random.choices(ears, ears_weights)[0]
    new_image ["Eyes"] = random.choices(eyes, eyes_weights)[0]
    new_image ["Hair"] = random.choices(hair, hair_weights)[0]
    new_image ["Mouth"] = random.choices(mouth, mouth_weights)[0]
    new_image ["Nose"] = random.choices(nose, nose_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)

Verify uniqueness

For NFT avatar projects, it is important that each avatar is unique. Therefore, it is necessary to check whether all images are unique. Write a simple function that loops over all images, stores them into a list, and returns the repeated image.

Next, add a unique identifier to each image.

# Returns 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))
# Add token Id to each image
i = 0
for item in all_images:
    item["tokenId"] = i
    i = i + 1
print(all_images)

trait count

Features are assigned according to predetermined weights and a random function. This means that even if you define the weight of white faces as 60, you cannot have exactly 60 white faces. In order to know exactly how many occurrences of each feature, it is necessary to keep track of how many features are present in your collection of images.

To do this, write the following code.

  • Define a dictionary for each feature with their respective categories, starting from 0.

15f2fc52af1e7211bb4e68b2b1836285.png

Cycle through the images you've created, and if traits are encountered, add them to their respective trait dictionaries.

# Get Trait Counts
face_count = {}
for item in face:
    face_count[item] = 0
ears_count = {}
for item in ears:
    ears_count[item] = 0
eyes_count = {}
for item in eyes:
    eyes_count[item] = 0
hair_count = {}
for item in hair:
    hair_count[item] = 0
mouth_count = {}
for item in mouth:
    mouth_count[item] = 0
nose_count = {}
for item in nose:
    nose_count[item] = 0
for image in all_images:
    face_count[image["Face"]] += 1
    ears_count[image["Ears"]] += 1
    eyes_count[image["Eyes"]] += 1
    hair_count[image["Hair"]] += 1
    mouth_count[image["Mouth"]] += 1
    nose_count[image["Nose"]] += 1
print(face_count)
print(ears_count)
print(eyes_count)
print(hair_count)
print(mouth_count)
print(nose_count)

generate image

This is the most amazing part. For each image, the script will do the following.

  • Open the image feature file where we define the trait

19a5d8f5592b01ce7f015c0e148602e1.png

  • Use the PIL package to select the corresponding trait image in your directory.

  • Combine all traits into one image

  • Convert to RGB, the most traditional color model

  • save it to your computer

#### Generate Images
os.mkdir(f'./images')
for item in all_images:
    im1 = Image.open(f'./scripts/face_parts/face/{face_files[item["Face"]]}.png').convert('RGBA')
    im2 = Image.open(f'./scripts/face_parts/eyes/{eyes_files[item["Eyes"]]}.png').convert('RGBA')
    im3 = Image.open(f'./scripts/face_parts/ears/{ears_files[item["Ears"]]}.png').convert('RGBA')
    im4 = Image.open(f'./scripts/face_parts/hair/{hair_files[item["Hair"]]}.png').convert('RGBA')
    im5 = Image.open(f'./scripts/face_parts/mouth/{mouth_files[item["Mouth"]]}.png').convert('RGBA')
    im6 = Image.open(f'./scripts/face_parts/nose/{nose_files[item["Nose"]]}.png').convert('RGBA')
    #Create each composite
    com1 = Image.alpha_composite(im1, im2)
    com2 = Image.alpha_composite(com1, im3)
    com3 = Image.alpha_composite(com2, im4)
    com4 = Image.alpha_composite(com3, im5)
    com5 = Image.alpha_composite(com4, im6)
    #Convert to RGB
    rgb_im = com5.convert('RGB')
    file_name = str(item["tokenId"]) + ".png"
    rgb_im.save("./images/" + file_name)

4bafc347f220609435cd15fbc0631547.png

907395fab864a262202d05982845f2a9.jpeg-Click below to read the original text to join the community members-

Guess you like

Origin blog.csdn.net/BF02jgtRS00XKtCx/article/details/125650266