Script Python pour générer des NFTs à partir de layers

Ces deux scripts permettent de générer des NFTs à partir de layers png.

Placez vos images dans des dossiers puis vos dossiers dans un dossier image puis executez Script 1.

Nommez les dossiers et les images selon les metadatas que vous souhaitez générer. Dans quelques jours je publierai un nouveau script pour générer des metadatas standard pour Solana.

Script 1 : permet de définir le nombre total de NFTs de la collection et la fréquence d’utilisation de chaque image. Le script va chercher un dossier « images » contenant vos dossiers.

Script 2 : génère des images uniques en empilant les layers. Les images générées sont enregistrées en format jpg dans le dossier « nft ».

Pour utiliser un script, il suffit de l’enregistrer dans un fichier txt puis changer l’extension par .py

Vous devez avoir Python installé dans votre environnement pour executer ces scripts. Ils doivent s’executer au même niveau que le dossier « images ».

Script 1

import os
import csv
import re

def explore_images_folder(images_folder):
    layers_groups = []

    # Trier les dossiers en fonction du numéro au début du nom de chaque dossier
    sorted_group_names = sorted(
        os.listdir(images_folder),
        key=lambda x: int(re.match(r"(\d+)", x).group()) if re.match(r"(\d+)", x) else float('inf')
    )

    for group_name in sorted_group_names:
        group_path = os.path.join(images_folder, group_name)
        
        if os.path.isdir(group_path):
            layers_info = []

            for image_name in os.listdir(group_path):
                if image_name.endswith(".png"):
                    image_path = os.path.join(group_path, image_name)
                    
                    while True:
                        try:
                            uses = int(input(f"Combien de fois voulez-vous utiliser l'image {image_name} dans le groupe {group_name}? "))
                            break
                        except ValueError:
                            print("Veuillez saisir un nombre entier.")
                    
                    layers_info.append({"path": image_path, "uses": uses})
            
            layers_groups.append({"group_name": group_name, "layers": layers_info})
    
    return layers_groups

def generate_report(layers_groups, total_images):
    num_groups = len(layers_groups)
    report = {
        "total_images": total_images,
        "num_groups": num_groups,
        "layers_info": []
    }

    for group in layers_groups:
        group_info = {
            "group_name": group["group_name"],
            "num_images": len(group["layers"]),
            "images": []
        }

        for layer_info in group["layers"]:
            group_info["images"].append({
                "image_name": os.path.basename(layer_info["path"]),
                "uses": layer_info["uses"]
            })
        
        report["layers_info"].append(group_info)
    
    return report

def save_report_to_csv(report, csv_filename):
    with open(csv_filename, mode='w', newline='') as file:
        writer = csv.writer(file)
        
        writer.writerow(["Total Images", report["total_images"]])
        writer.writerow(["Number of Groups", report["num_groups"]])
        writer.writerow([])

        for group in report["layers_info"]:
            writer.writerow([f"Group: {group['group_name']}"])
            writer.writerow(["Image Name", "Uses"])
            for image in group["images"]:
                writer.writerow([image["image_name"], image["uses"]])
            writer.writerow([])

def print_report(report):
    print(f"Total Images to Generate: {report['total_images']}")
    print(f"Number of Groups: {report['num_groups']}\n")

    for group in report["layers_info"]:
        print(f"Group: {group['group_name']}")
        print(f"Number of Images in Group: {group['num_images']}")
        for image in group["images"]:
            print(f"  Image Name: {image['image_name']}, Uses: {image['uses']}")
        print()

# Chemin du dossier contenant les images
images_folder = "images"

# Nombre total d'images à générer
while True:
    try:
        total_images = int(input("Combien d'images au total souhaitez-vous générer? "))
        break
    except ValueError:
        print("Veuillez saisir un nombre entier.")

# Explorer le dossier d'images pour récupérer les informations sur les groupes de layers
print("Exploration du dossier d'images...")
layers_groups = explore_images_folder(images_folder)
print("Exploration terminée.")

# Générer le rapport
report = generate_report(layers_groups, total_images)

# Sauvegarder le rapport dans un fichier CSV
csv_filename = "report.csv"
save_report_to_csv(report, csv_filename)

# Imprimer le rapport
print_report(report)

print(f"Le rapport a été sauvegardé dans le fichier {csv_filename}.")

Script 2

import csv
import os
import re
from PIL import Image
from collections import defaultdict
from itertools import product
import hashlib

# Lire le fichier CSV et obtenir les informations nécessaires
def read_report(csv_filename):
    with open(csv_filename, mode='r') as file:
        reader = csv.reader(file)
        report = {
            "total_images": 0,
            "num_groups": 0,
            "layers_info": []
        }
        
        group_info = None
        for row in reader:
            if row and row[0] == "Total Images":
                report["total_images"] = int(row[1])
            elif row and row[0] == "Number of Groups":
                report["num_groups"] = int(row[1])
            elif row and row[0].startswith("Group:"):
                if group_info:
                    report["layers_info"].append(group_info)
                group_info = {
                    "group_name": row[0].split(": ")[1],
                    "images": []
                }
            elif row and row[0] == "Image Name":
                continue
            elif row and len(row) == 2:
                group_info["images"].append({
                    "image_name": row[0],
                    "uses": int(row[1])
                })
        
        if group_info:
            report["layers_info"].append(group_info)
    
    return report

# Générer les images en respectant les priorités et les occurrences
def generate_images(report, images_folder, output_folder):
    total_images = report["total_images"]
    layers_info = report["layers_info"]

    # Préparer les données pour la génération des images
    layers_paths = defaultdict(list)
    for group in layers_info:
        group_name = group["group_name"]
        for image_info in group["images"]:
            image_name = image_info["image_name"]
            uses = image_info["uses"]
            image_path = os.path.join(images_folder, group_name, image_name)
            layers_paths[group_name].extend([image_path] * uses)

    # Assurer que le dossier de sortie existe
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    # Collecter toutes les combinaisons possibles
    all_combinations = []
    for group_name in sorted(layers_paths.keys(), key=lambda x: int(re.match(r"(\d+)", x).group())):
        all_combinations.append(layers_paths[group_name])

    unique_combinations = set()
    for combination in product(*all_combinations):
        # Utiliser un hash pour assurer l'unicité
        hash_value = hashlib.md5("".join(combination).encode()).hexdigest()
        unique_combinations.add((hash_value, combination))

        if len(unique_combinations) >= total_images:
            break

    # Générer les images uniques
    for i, (_, combination) in enumerate(unique_combinations):
        base_image = None
        for layer_path in combination:
            layer_image = Image.open(layer_path).convert("RGBA")
            if base_image is None:
                base_image = Image.new("RGBA", layer_image.size)
            base_image = Image.alpha_composite(base_image, layer_image)

        # Sauvegarder en PNG puis convertir en JPG
        png_path = os.path.join(output_folder, f"x{i+1}.png")
        jpg_path = os.path.join(output_folder, f"x{i+1}.jpg")
        base_image.save(png_path)
        print(f"Image saved as PNG: {png_path}")

        # Convertir en JPG
        with Image.open(png_path) as img:
            rgb_image = img.convert('RGB')
            rgb_image.save(jpg_path)
            print(f"Image converted to JPG: {jpg_path}")

        # Supprimer le fichier PNG
        os.remove(png_path)

# Chemin du dossier contenant les images
images_folder = "images"

# Chemin du fichier CSV
csv_filename = "report.csv"

# Chemin du dossier pour sauvegarder les images finales
output_folder = "nft"

# Lire le rapport CSV
report = read_report(csv_filename)

# Générer les images selon les informations du rapport
generate_images(report, images_folder, output_folder)

print(f"{report['total_images']} images ont été générées avec succès dans le dossier {output_folder}.")

Ces deux scripts seront mis à jour sous peu avec quelques nouvelles fonctionnalités. Have fun et partagez, ces scripts sont freeware !

Retour en haut