본문 바로가기
프로그래밍

Python을 사용하여 NFT 이미지 , 메타데이터 대량 생성

by it-view 2021. 12. 30.
반응형

제가 첫 번째 글을 쓸 때, 저는 단지 NFT 이미지 생성 과정을 탐색하고 있었습니다. 자세히 알아보니 단순히 이미지를 생성하는 것만이 아니라 메타데이터를 생성하고, 이미지를 클라우드에 저장하는 것도 가능하다는 것을 알게 되었습니다. 이 기사는 첫 번째 기사의 개선된 버전이라고 생각하시면 됩니다.

이 코드는 이전 코드보다 몇 가지 개선된 점이 있습니다. 주요 내용은 다음과 같습니다.

  • 사용자는 원하는 만큼 레이어를 추가할 수 있으며, 코드에서 레이어의 이름만 지정하면 된다.
  • 각 계층의 변형 수는 동일할 필요가 없으며, 코드는 각 폴더의 파일 목록을 로드하여 계층 사용을 나타낸다.
  • 이 코드는 생성된 이미지의 메타데이터를 포함하는 .json 파일도 생성합니다.

다시 한 번 말하지만, 나는 전문 프로그래머가 아니며 내 코드는 작업을 수행하는 가장 좋은 방법이 아닐 것이다. 하지만 이봐, 그것은 효과가 있다!

 

디렉토리 구조:

다음 이미지는 디렉토리 구조를 보여줍니다.

루트 폴더에는 각각 계층을 나타내는 하위 폴더가 포함되어 있습니다. 레이어를 나타내는 각 하위 폴더에는 레이어를 선택하고 병합하려는 순서대로 번호가 매겨져야 합니다. 그래서 배경인 이미지의 가장 낮은 층은 이름 "1", 다음 층 "2" 등이 될 것입니다. 5개의 레이어로 구성된 이미지에서 배경은 1이고 가장 위에 있는 레이어는 5가 됩니다.

각 도면층 하위 폴더에는 해당 도면층의 각 변형을 나타내는 이미지 파일이 포함됩니다. 업데이트된 코드가 파일 이름을 불러오기 때문에 번호를 매길 필요가 없습니다. 그러나 생성된 이미지 파일의 메타데이터에 사용되므로 각 파일의 이름을 적절하게 지정해야 합니다.

 

클라우드에 이미지 저장:

당신의 NFT 컬렉션의 모든 이미지는 어딘가에 저장되어야 합니다. 원하는 곳에 저장하도록 선택할 수 있지만 언제든지 사진에 액세스할 수 있도록 신뢰할 수 있는 스토리지여야 합니다. 인기 있는 옵션은 피냐타입니다. Pinata는 행성 간 파일 시스템이라고 하는 피어 투 피어 파일 시스템에 데이터를 저장합니다. 피냐타는 꽤 직설적이에요. 최대 1GB까지 무료 스토리지로 등록할 수 있습니다. 로그인한 후 폴더를 업로드합니다. 테스트 파일이 있는 폴더라면 어디든 좋습니다. 이 단계에서는 메타데이터 파일에서 사용할 수 있는 URL 주소를 가져옵니다. 폴더를 업로드한 후 홈 페이지로 돌아가면 폴더 이름이 표시됩니다. 그 옆에는 알파벳과 숫자의 긴 순서인 CID가 보이실 겁니다. 그것을 복사하여 쉽게 접근할 수 있는 위치에 저장하세요. 우리의 코드에 필요할 것입니다.

매개 변수 설정:

몇 가지 매개 변수를 정의해 보겠습니다.

#Name of your  project, using test for now.
project = ‘test’
#The CID of the folder on Pinata.
url = ‘QtgdsX3fsfT45fsggrd’
#The local folder which will have the layers' subfolders.
folder = ‘layers’
#The number of images you want to generate.
count = ‘100’
#List containing the names of the layers, in the sequence you want
#the layers to be picked by the code and merged.
layers_names = [“background”, “face”, “shirt”, “accessory”]
 

생성할 수 있는 이미지의 총 수는 각 계층의 하위 폴더에 있는 파일 수를 곱하여 계산할 수 있습니다. 4개의 레이어가 있고 각 레이어가 파일로 표현되는 4개의 변형을 가진다고 가정하자. 가능한 고유 이미지의 총 수는 다음과 같습니다.

4x4x4x4=256

레이어를 더 추가하면 숫자가 기하급수적으로 증가합니다. 그러나 테스트의 경우 시간이 많이 걸리기 때문에 100 또는 10으로 설정할 수 있으므로 그렇게 많은 이미지를 생성하지 않는 것이 좋습니다.

필요한 라이브러리 가져오기:

import random
import os
from itertools import product
from PIL import Image
 

가능한 모든 변형 파일 조합 생성:

이제 폴더 매개 변수로 지정된 폴더의 각 하위 폴더에 파일 목록을 로드하겠습니다. 그런 다음 가능한 모든 조합에서 이들을 결합하여 각 층의 변형 가능한 조합을 포함하는 튜플 목록을 생성할 것이다. 이 작업은 코드 한 줄로 수행할 수 있습니다.

combinations = list(product(*[os.listdir(f'{folder}/{x}') for x in os.listdir(folder)]))

이 목록의 각 항목은 각 레이어의 가능한 변형 조합을 나타냅니다. 우리는 파일명을 기준으로 파일을 로드하고 병합하는 데 사용할 것입니다. 끝까지 진행하지 않고 이미지 수를 더 적은 수로 제한한 경우 이 목록을 섞는 것이 좋습니다.

random.shuffle(combinations)
 

이미지 및 메타데이터 생성:

다음 코드는 조합 목록의 각 조합을 반복하여 각 계층 폴더에서 이미지를 로드하여 하나의 이미지로 병합한 다음 해당 이미지에 대한 메타데이터를 생성하고 저장합니다.

c=0
metadata={}
for combination in combinations:
    if c != count:
            if len(combination)>2:
                        comp = image.alpha_composite(image.open(f'{folder}/1/{combination[1]}').convert('RGBA'),
                                                                                              image.open(f'{folder}/2/{combination[2]}').convert('RGBA'))
            n=3
            for item in combination[2:]:
                            if combination.index(item)!=-1:
                                                comp = Image.alpha_composite(comp,
                                                                                                                      image.open(f'{folder}/{n}/{item}').convert('RGBA'))
                    n+=1
        rgb_im = comp.convert('RGB')
        file_name = str(combinations.index(combination)) + ".png"
        rgb_im.save("./images/" + file_name)
        metadata['image']=f'{image_url}/{file_name}'
        metadata['tokenId']=str(combinations.index(combination))
        metadata['name']=project+' '+str(combinations.index(combination))
        metadata['attributes']=[]
        for item in layers_names:
                    metadata['attributes'].append({item:combination[layers_names.index(item)][:-4]})
        with open(f"./metadata/{str(combinations.index(combination))}.json", "w") as outfile:
            json.dump(metadata, outfile, indent=4)
        c+=1
    else:
            break

변수 "c"는 생성된 파일의 수를 기록하고 각 반복이 끝날 때마다 업데이트됩니다. "결합" 목록의 각 항목에 대해 코드는 먼저 "c" 값을 검사하며, "count" 변수와 같지 않으면 루프를 깨트릴 것이다.

처음 두 레이어에 대해서는 경로를 하드 코딩해야 했습니다. 더 나은 방법이 있을 거라고 확신하지만, 이해할 수 없었습니다. 처음 두 개의 레이어 외에 다른 레이어가 하나씩 로드되어 이전에 병합된 레이어와 병합됩니다.

 

"결합" 목록에 있는 각 항목의 색인은 이미지 파일과 json 파일의 파일 이름으로 사용됩니다. 우리는 메타데이터를 위해 "layers_names" 목록이 필요합니다. 목록의 각 항목은 이미지의 속성을 나타내며 값은 해당 계층에서 해당 변동을 나타내는 파일의 파일 이름입니다. 따라서 모든 계층의 폴더에 있는 각 변형은 메타데이터에 표시될 때 적절하게 이름이 지정되어야 합니다. 이미지는 "이미지" 폴더에 저장되고 메타데이터 파일은 "메타데이터" 폴더에 저장됩니다.

코드는 적절한 들여쓰기와 함께 표시되지 않을 가능성이 높으므로 주피터 노트북을 확인해 보십시오. 앞서 언급했듯이, 제 코드는 유치할 수 있지만 저는 배우러 온 것이고 당신의 피드백은 확실히 제 향상에 도움이 될 것입니다. 여기까지 읽어주셔서 감사합니다. 프로젝트를 진행하면서 배운 것을 공유하겠습니다.

댓글