2021年12月19日 星期日

使用Python來建立您自己的NFT圖片集


參考文章:Create Your Own NFT Collection With Python

圖片下載:https://github.com/usetech-llc/substrapunks/archive/refs/heads/master.zip

維基百科:非同質化代幣(NFT)

注意!程式碼176-181和195行,要注意必須要更改成實際的目錄夾。

程式碼:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
from PIL import Image 
from IPython.display import display 
import random
import json
import os

# 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 = ["ears1", "ears2", "ears3", "ears4"] 
ears_weights = [25, 30 , 44, 1]

eyes = ["regular", "small", "rayban", "hipster", "focused"] 
eyes_weights = [70, 10, 5, 1, 14]

hair = ['hair1', 'hair10', 'hair11', 'hair12', 'hair2', 'hair3', 'hair4',
 'hair5',
 'hair6',
 'hair7',
 'hair8',
 'hair9']
hair_weights = [10 , 10 , 10 , 10 ,10, 10, 10 ,10 ,10, 7 , 1 , 2]

mouth = ['m1', 'm2', 'm3', 'm4', 'm5', 'm6']
mouth_weights = [10, 10,50, 10,15, 5]

nose = ['n1', 'n2']
nose_weights = [90, 10]

# Dictionary variable for each trait. 
# Eech trait corresponds to its file name

face_files = {
    "White": "face1",
    "Black": "face2"
}

ears_files = {
    "ears1": "ears1",
    "ears2": "ears2",
    "ears3": "ears3",
    "ears4": "ears4"
}

eyes_files = {
    "regular": "eyes1",
    "small": "eyes2",
    "rayban": "eyes3",
    "hipster": "eyes4",
    "focused": "eyes5"     
}

hair_files = {
    "hair1": "hair1",
    "hair2": "hair2",
    "hair3": "hair3",
    "hair4": "hair4",
    "hair5": "hair5",
    "hair6": "hair6",
    "hair7": "hair7",
    "hair8": "hair8",
    "hair9": "hair9",
    "hair10": "hair10",
    "hair11": "hair11",
    "hair12": "hair12"
}

mouth_files = {
    "m1": "m1",
    "m2": "m2",
    "m3": "m3",
    "m4": "m4",
    "m5": "m5",
    "m6": "m6"
}

nose_files = {
    "n1": "n1",
    "n2": "n2"   
}

## 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)

# 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)

# 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 Images    
for item in all_images:

    im1 = Image.open(f'<下載解壓縮的目錄夾>/substrapunks-master/scripts/face_parts/face/{face_files[item["Face"]]}.png').convert('RGBA')
    im2 = Image.open(f'<下載解壓縮的目錄夾>/substrapunks-master/scripts/face_parts/eyes/{eyes_files[item["Eyes"]]}.png').convert('RGBA')
im3 = Image.open(f'<下載解壓縮的目錄夾>/substrapunks-master/scripts/face_parts/ears/{ears_files[item["Ears"]]}.png').convert('RGBA')
im4 = Image.open(f'<下載解壓縮的目錄夾>/substrapunks-master/scripts/face_parts/hair/{hair_files[item["Hair"]]}.png').convert('RGBA')
im5 = Image.open(f'<下載解壓縮的目錄夾>/substrapunks-master/scripts/face_parts/mouth/{mouth_files[item["Mouth"]]}.png').convert('RGBA')
im6 = Image.open(f'<下載解壓縮的目錄夾>/substrapunks-master/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("<新建儲存圖片的資料夾>/" + file_name)

程式解說:
  • 第1-5行 匯入會使用到的程式套件。
  • 第6-31行 主要是分配特質稀有度,每個獨特的頭像都包含五個特徵:臉、耳朵、頭髮、嘴、鼻子等,當有些鼻子必須比其他鼻子更稀有,您需要為您擁有的不同類型的鼻子分配權重,分別是90%和10%,但數組的總數應始終為 100。我們有兩種類型的面孔,黑與白,您必須指定白臉圖像有 60% 的機會,黑臉有40% 的機會。
  • 第32-83行,對特徵進行分類作業,如果您想為您的特徵使用不同的名稱,可以使用字典,例如:特徵名稱“face1”被歸類為白臉,而“face2”被歸類為黑臉。
  • 第85-116行為定義圖像特徵,建立每個頭像圖像是由六張圖片的組合:臉、鼻子、嘴巴、耳朵和眼睛。第104-107行有判斷是否重複,若重複則更外產生。
  • 第117-130行是為了驗證唯一性,對於 NFT 頭像項目,重要的是每個頭像都是獨一無二的。因此,您需要檢查所有圖像是否都是唯一的。接下來,為每個圖像添加一個唯一標識符。在第112行會列印出
Are all images unique? True。
  • 第131-172為性狀計數,要確切知道每個特徵出現的次數,您必須要跟踪現在有多少特徵出現在您的圖像集中。但要特別注意根據預定義的權重和隨機函數分配了特徵。這意味著即使您將白人面孔的權重定義為 60,也不可能恰好有 60 個白人面孔,例如這次產生了53個白臉但產生了47個黑臉。執行結果如下:
{'White': 53, 'Black': 47}
{'ears1': 29, 'ears2': 34, 'ears3': 35, 'ears4': 2}
{'regular': 66, 'small': 16, 'rayban': 11, 'hipster': 0, 'focused': 7}
{'hair1': 8, 'hair10': 8, 'hair11': 13, 'hair12': 12, 'hair2': 13, 'hair3': 12, 'hair4': 6, 'hair5': 11, 'hair6': 11, 'hair7': 4, 'hair8': 1, 'hair9': 1}
{'m1': 6, 'm2': 7, 'm3': 56, 'm4': 12, 'm5': 13, 'm6': 6}
{'n1': 92, 'n2': 8}

  • 第173-195行是為了生成圖像,執行結果在本文文章一開頭。

沒有留言:

張貼留言