소프트웨어 개발/Javascript

Javascript로 Generative NFT 이미지 합성하기

Leo's notes 2024. 4. 29. 09:16

Imported from Medium story (Sep 4, 2022)

 

최근 대부분의 PFP NFT는 이미지를 구성할 각 파츠 이미지들을 만들어 두고, 프로그래밍을 통해 이를 랜덤으로 조합하여 최종 이미지를 생성하는 방식을 사용합니다.

 

 

BAYC #3419

 

 

예를 들어 BAYC #3419의 경우 그림의 배경, 옷, 눈, 털, 모자, 입을 구성하는 각각의 파츠 이미지들이 합성되어 하나의 최종 이미지를 만들어 냅니다. OpenSea와 같은 NFT 거래소나 NFT 뷰어 앱 등에서 이미지를 구성하는 파츠들을 볼 수 있습니다.

 

 

BAYC #3419 Attributes (OpenSea)

 

 

그리고 BAYC Gallery에 가면 전체적으로 어떤 파츠들이 있고, 각 파츠들을 어떻게 구성했는지도 볼 수 있습니다.

 


 

 

이렇게 하나의 최종 이미지를 만들기 위해서는 보통 배경이 투명한 파츠 이미지들을 만들어 이를 합성합니다. 파츠 이미지들이 준비되었다면, imagemagick 라이브러리와 Javascript를 이용하여 Generative NFT 이미지를 생성할 수 있습니다.

 

먼저 합성할 imageList를 받아 imageName으로 저장해주는 compositeImage함수를 만듭니다. 넘겨받은 imageList에 있는 파일들을 순서대로 imagemagick 명령어에 맞게 겹겹이 쌓아올리고 이미지 합성을 실행합니다.

 

 

그리고 앞서 만든 compositeImage함수에 imageName, imageList를 건내주며 생성하고자 하는 이미지 수 만큼 호출합니다.

 

 

BAYC의 경우 각 파츠의 생김새는 다양하지만, 원숭이 얼굴의 형태를 가진 베이스 이미지는 항상 동일하게 들어갑니다. 이러한 베이스 이미지도 이미지 합성시 빠지지 않도록 순서에 맞게 넣어주어야 합니다. 위 코드의 경우 imageList의 두 번째에 들어가는 face attribute입니다.

 

그리고 각 파츠 이미지들을 어떤 방식으로 준비했는지에 따라 합성 순서가 중요해질 수 있으므로 imageList생성시 이미지 파일명을 넣는 순서에 신경써야 합니다.

 

 

HAPEBEAST

 

 

HAPEBEAST NFT의 위 이미지처럼 원숭이의 귀가 모자를 뚫고 나오는 경우의 수를 생각하지 못하고 이미지를 합성하여 퀄리티 논란이 생겼던 적도 있었습니다. 파츠 제작이나 합성시 이런 경우의 수를 잘 따져봐야 합니다.

 

[
  {
    "background": "background_3.png",
    "hair": "hair_8.png",
    "earrings": "earrings_1.png",
    "mouth": "mouth_9.png",
    "eyes": "eyes_2.png",
    "clothes": "clothes_5.png"
  },
  {
    "background": "background_1.png",
    "hair": "hair_1.png",
    "earrings": "earrings_5.png",
    "mouth": "mouth_3.png",
    "eyes": "eyes_6.png",
    "clothes": "clothes_2.png"
  },
  ...
]

 

예시 코드에서 사용되는 compositeInfo의 형태는 위와 같습니다. 각 파츠 이미지 파일명의 prefix를 통일하고 뒤에 붙는 숫자로 이미지를 구분되게 하면, 랜덤 함수로 숫자만 붙여주는 간단한 스크립트로 JSON 파일을 생성하여 사용할 수 있습니다.

 

랜덤 함수를 통해 위와 같은 이미지 리스트를 생성하면서 Metadata JSON 파일 생성을 위한 스크립트도 동시에 생성하면 편리하게 Generative NFT를 만들어볼 수 있을 것입니다.