La première étape que vous franchirez pour créer une Dapp de frappe NFT consiste à préparer l'œuvre d'art. Sans l'illustration, vous ne pouvez pas actualiser votre projet NFT.
Une autre raison de prétraiter vos œuvres d'art est de générer des métadonnées pour chacune des images. Sans ces métadonnées, votre NFT ne peut être vendu sur aucun des grands marchés secondaires, comme Opensea.
Par exemple, l'image ci-dessous est un NFT sur le marché Opensea contenant des métadonnées qui peuvent également être vues ci-dessous.
Les informations ci-dessus, y compris l'illustration, ses détails et ses caractéristiques, peuvent être vues sur l'image IPFS ci-dessous.
Ouvrez votre terminal et accédez au répertoire de votre projet ou créez un dossier de projet à un emplacement spécifique. Par exemple, l'exécution de **mkdir preprocessor**
sur le terminal créera un dossier appelé « preprocessor » à l'emplacement spécifié.
Ensuite, exécutez les commandes suivantes sur le terminal.
cd preprocessor npm init -y npm install sharp @faker.js/faker --save-dev
Les commandes ci-dessus installeront les bibliothèques sharp et faker sur votre projet. La bibliothèque de faux nous aidera à générer des informations aléatoires. Alors que la bibliothèque pointue nous aidera à traiter l'image à une certaine dimension, qualité et format.
Ensuite, créez un dossier dans votre projet appelé arts
et un autre appelé outputs
. Dans le dossier "arts", placez toutes les images à traiter à l'intérieur.
Une fois les étapes ci-dessus accomplies, ouvrez le projet sur "Code VS". La structure du projet devrait ressembler à celle ci-dessous.
- preprocessor/ - arts/ - node_modules/ - outputs/ - package.json - package-lock.json
Super, passons au codage du moteur chargé de traiter les images.
Vous aurez besoin des éléments suivants installés sur votre ordinateur pour terminer ce didacticiel.
Créez un fichier à la racine de votre projet appelé **imagify.js**
et collez le code suivant
const fs = require('fs') const path = require('path') const sharp = require('sharp') const { faker } = require('@faker-js/faker') const input = './arts' const output = './outputs' let img_counter = 1 const imgSize = { width: 500, height: 500 } const desired_ext = '.webp' const base_url = 'https://ipfs.io/ipfs/REPLACE_WITH_IPFS_CID/' const attributes = { weapon: [ 'Stick', 'Knife', 'Blade', 'Clube', 'Ax', 'Sword', 'Spear', 'Gun', 'Craft', ], environment: [ 'Space', 'Sky', 'Desert', 'Forest', 'Grassland', 'Moiuntains', 'Oceans', 'Rainforest', ], rarity: Array.from(Array(10).keys()), } fs.readdirSync(input).forEach((file) => { const orginal_ext = path.extname(file) const orginal_file_name = path.basename(file).split('.')[0] if (['.jpg', '.jpeg', '.png', '.gif', '.webp'].includes(orginal_ext)) { const id = img_counter const metadata = { id, name: `Adulam NFT #${id}`, description: 'AI Arts NFTs Collection, Mint and collect the hottest NFTs around.', price: 1, image: base_url + id + desired_ext, demand: faker.random.numeric({ min: 10, max: 100 }), attributes: [ { trait_type: 'Environment', value: attributes.environment.sort(() => 0.5 - Math.random())[0], }, { trait_type: 'Weapon', value: attributes.weapon.sort(() => 0.5 - Math.random())[0], }, { trait_type: 'Rarity', value: attributes.rarity.sort(() => 0.5 - Math.random())[0], max_value: 10, }, { display_type: 'date', trait_type: 'Created', value: Date.now(), }, { display_type: 'number', trait_type: 'generation', value: 1, }, ], } if (fs.existsSync(`${input}/${orginal_file_name + orginal_ext}`)) { sharp(`${input}/${orginal_file_name + orginal_ext}`) .resize(imgSize.height, imgSize.width) .toFile(`${output}/images/${id + desired_ext}`, (err, info) => console.log(err), ) fs.writeFileSync(`${output}/metadata/${id}.json`, JSON.stringify(metadata), { encoding: 'utf-8', flag: 'w', }) } console.log(metadata) img_counter++ } })
Les étapes suivantes vous aideront à comprendre le fonctionnement de ce moteur de traitement des métadonnées.
Importation des bibliothèques essentielles
const fs = require('fs') const path = require('path') const sharp = require('sharp') const { faker } = require('@faker-js/faker') const input = './arts' const output = './outputs'
Le fs
représente le système de fichiers, c'est un module intégré fourni avec NodeJs. Il a la responsabilité de gérer les activités de lecture et d'écriture de fichiers sur votre machine.
Le path
est un autre module de nœud qui vous aide à naviguer dans les structures de répertoires de votre machine. Cela contribuera à localiser où nos images sont conservées.
Sharp est le module que nous utilisons pour traiter l'image, comme le redimensionner et la transformer en un type de fichier différent.
Nous utiliserons le faker pour générer un nombre aléatoire.
Enfin, la variable input
contient l'emplacement où se trouvent les images à traiter et la output
pointe vers l'emplacement où les images traitées seront enregistrées.
Définition des variables essentielles
let img_counter = 1 const imgSize = { width: 500, height: 500 } const desired_ext = '.webp' const base_url = 'https://ipfs.io/ipfs/REPLACE_WITH_IPFS_CID/' const attributes = { weapon: [ 'Stick', 'Knife', 'Blade', 'Clube', 'Ax', 'Sword', 'Spear', 'Gun', 'Craft', ], environment: [ 'Space', 'Sky', 'Desert', 'Forest', 'Grassland', 'Moiuntains', 'Oceans', 'Rainforest', ], rarity: Array.from(Array(10).keys()), }
Les codes ci-dessus contiennent des variables importantes à utiliser lors de la génération de nos métadonnées.
**Image_counter**
nous aide à numéroter les images de manière cohérente avec l'itération actuelle.**ImgSize**
définit la dimension de la largeur et de la hauteur de chaque image à traiter.**Desired_ext**
parle du format de fichier que vous voulez que vos images traitées portent.**Base_url**
spécifie l'emplacement où les images doivent être stockées sur l'IPFS.**Attributes**
contient des informations supplémentaires sur les métadonnées de chaque image.
Exécution d'une tâche récursive
fs.readdirSync(input).forEach((file) => { if(['.jpg', '.jpeg', '.png', '.gif', '.webp'].includes(orginal_ext)) { // Images and metadata tasks are recursively performed here... } })
Dans le bloc de code ci-dessus, nous avons utilisé la bibliothèque du système de fichiers (fs) pour parcourir toutes les images de l'emplacement **input**
(arts). Et pour chacune des images, nous nous sommes assurés que notre moteur ne sélectionne que des images à partir d'une liste approuvée d'extensions.
Exécution de la tâche de métadonnées
const id = img_counter const metadata = { id, name: `Adulam NFT #${id}`, description: 'AI Arts NFTs Collection, Mint and collect the hottest NFTs around.', price: 1, image: base_url + id + desired_ext, demand: faker.random.numeric({ min: 10, max: 100 }), attributes: [ { trait_type: 'Environment', value: attributes.environment.sort(() => 0.5 - Math.random())[0], }, { trait_type: 'Weapon', value: attributes.weapon.sort(() => 0.5 - Math.random())[0], }, { trait_type: 'Rarity', value: attributes.rarity.sort(() => 0.5 - Math.random())[0], max_value: 10, }, { display_type: 'date', trait_type: 'Created', value: Date.now(), }, { display_type: 'number', trait_type: 'generation', value: 1, }, ], }
Dans le bloc de code ci-dessus, nous avons fourni des valeurs pour chaque espace de métadonnées. Par exemple, les environnements, les armes et toutes les valeurs de trait sont fournies de manière aléatoire et dynamique.
Exécution de la tâche de transformation d'image
if (fs.existsSync(`${input}/${orginal_file_name + orginal_ext}`)) { sharp(`${input}/${orginal_file_name + orginal_ext}`) .resize(imgSize.height, imgSize.width) .toFile(`${output}/images/${id + desired_ext}`, (err, info) => console.log(err), ) fs.writeFileSync(`${output}/metadata/${id}.json`, JSON.stringify(metadata), { encoding: 'utf-8', flag: 'w', }) } console.log(metadata) img_counter++
Dans l'extrait ci-dessus, nous avons de nouveau utilisé le module de système de fichiers pour d'abord localiser chacune de nos illustrations et la redimensionner à notre dimension spécifiée (500 x 500). De plus, nous avons fourni un nouveau nom en ligne avec l'itération actuelle et lui avons donné l'extension souhaitée (webp).
Le redimensionnement et la transformation des images en webp
grandement optimisé nos œuvres d'art à une hauteur étonnante.
Par exemple, où j'ai soumis ce moteur de prétraitement d'images à 99
images totalisant une taille de 111MB
. La taille est descendue à 62MB
pour l'extension .png
et à 4,5 .webp
4.5MB
Cette énorme réduction de taille représente un grand bond dans le temps de chargement d'un site Web Minting construit avec mes images.
Enfin à partir du bloc de code ci-dessus, nous avons créé des métadonnées JSON
pour chaque image traitée, portant à la fois un nom identique et une URL pointant vers l'emplacement de l'image. Ces métadonnées sont ce que nous allons déployer sur IPFS après le traitement des images.
Maintenant, exécutez la commande ci-dessous pour transformer votre image. Assurez-vous d'être dans votre dossier de projet.
node imagify.js
À ce stade, nous en avons terminé avec notre moteur d'image, notre dossier de sortie devrait avoir la structure de fichier suivante comme résultat.
- output/ - images - 1.webp - 2.webp - ...... - metadata - 1.json - 2.json - ......
IPFS signifie le système de fichiers interplanétaire, il est peer-to-peer et décentralisé. Il n'existe pas de moyen simple d'extraire les données stockées sur l'IPFS et, en tant que tel, il s'agit d'un pair presque parfait à utiliser avec vos applications blockchain pour stocker le contenu multimédia.
Pour utiliser la méthode simple et moins déroutante, rendez-vous sur la page d'installation de l'application IPFS Desktop et suivez les instructions qui y sont spécifiées.
Une fois l'installation réussie, ouvrez l'application IPFS et téléchargez EN PREMIER, et je le répète, téléchargez EN PREMIER le dossier images.
Une chaîne CID (identification de contenu) unique sera générée dans le cadre du nom du dossier, voir l'image ci-dessous.
Maintenant, copiez le dossier d'images CID comme on peut le voir sur l'image ci-dessus, et remplacez-le dans votre code **imagify.js**
. Voir le code ci-dessous.
const base_url = "https://ipfs.io/ipfs/REPLACE_WITH_IPFS_CID/" //old string const base_url = "https://ipfs.io/ipfs/QmY1zrFibpdHQ7qcqZqq7THsqTremZYepXNWR5Au3MF1ST/" //new string
Maintenant, exécutez à nouveau le **node imagify.js**
pour inclure l'emplacement précis de chaque image dans vos métadonnées JSON . Voir un exemple des métadonnées JSON générées avant et après le remplacement du CID.
Vous pouvez regarder cette vidéo pour comprendre comment j'ai utilisé ces images et métadonnées sur un projet complet de frappe NFT.
Avant le remplacement du CID
{ id: 97, name: 'Adulam NFT #97', description: 'AI Arts NFTs Collection, Mint and collect the hottest NFTs around.', price: 1, image: 'https://ipfs.io/ipfs/REPLACE_WITH_IPFS_CID/97.webp', demand: '4', attributes: [ { trait_type: 'Environment', value: 'Forest' }, { trait_type: 'Weapon', value: 'Craft' }, { trait_type: 'Rarity', value: 4, max_value: 10 }, { display_type: 'date', trait_type: 'Created', value: 1664478034024 }, { display_type: 'number', trait_type: 'generation', value: 1 } ] }
Après le remplacement du CID
{ id: 97, name: 'Adulam NFT #97', description: 'AI Arts NFTs Collection, Mint and collect the hottest NFTs around.', price: 1, image: 'https://ipfs.io/ipfs/QmY1zrFibpdHQ7qcqZqq7THsqTremZYepXNWR5Au3MF1ST/97.webp', demand: '7', attributes: [ { trait_type: 'Environment', value: 'Moiuntains' }, { trait_type: 'Weapon', value: 'Clube' }, { trait_type: 'Rarity', value: 2, max_value: 10 }, { display_type: 'date', trait_type: 'Created', value: 1664478110287 }, { display_type: 'number', trait_type: 'generation', value: 1 } ] }
Enfin, comme indiqué dans l'image ci-dessous, téléchargez le dossier de métadonnées sur IPFS à côté du dossier d'images.
Fantastique, maintenant épinglons-le sur le Web pour que le monde le voie. Actuellement, les deux dossiers se trouvent sur votre nœud IPFS local (votre ordinateur), pour qu'il soit accessible dans le monde entier, vous devez utiliser un service Pinning tel que Pinata .
Tout d'abord, dirigez-vous vers le gestionnaire de broches Pinata et inscrivez-vous si vous ne l'avez pas encore fait. Cliquez ensuite sur l'icône du compte et sélectionnez Clés API. Voir l'image ci-dessous.
Sur la page de création de clés, cliquez sur créer une nouvelle clé et entrez le nom de la clé. Observez l'image ci-dessous.
Copiez maintenant la clé JWT dans votre presse-papiers. C'est ce que nous utiliserons pour lier notre bureau IPFS à notre compte Pinata. Voir l'image ci-dessous.
Ensuite, ouvrez votre application de bureau IPFS, accédez à l'onglet Paramètres et ajoutez un nouveau service, sélectionnez Pinata et collez votre jeton JWT dans l'espace prévu. Reportez-vous à l'image ci-dessous.
La dernière chose à faire est d'épingler vos dossiers sur Pinata en suivant les instructions ci-dessous.
Dirigez-vous vers l'onglet Fichiers, cliquez sur la ligne à trois pointillés et sélectionnez Définir l'épinglage. Cela apparaîtra dans l'image ci-dessous.
Sélectionnez Pinata et appliquez, ce faisant, votre dossier d'images sera accessible globalement.
Rendez-vous sur ce site Web, copiez et collez votre CID dans le champ de saisie IPFS et cliquez sur le bouton de cache. Cela analyse l'ensemble des passerelles IPFS accessibles au public à la recherche de vos images. Voir l'image ci-dessous.
Les résultats de l'image ci-dessus montrent que de nombreux nœuds IPFS ont désormais des copies du dossier images disponibles et accessibles globalement, même si vous avez supprimé la copie d'origine sur votre nœud local.
Avec les étapes clairement décrites pour vous, épinglez également le dossier de métadonnées pour les rendre accessibles au public en ligne.
Vous pouvez maintenant utiliser l'un des liens de l'image ci-dessus comme URL de base pour les jetons ERC721 . Voir l'image ci-dessous.
Et voilà, voilà comment préparer et télécharger vos œuvres sur l'IPFS.
Vous rencontrerez toujours le besoin de comprendre comment prétraiter et télécharger des œuvres d'art sur l'IPFS à l'échelle d'un lot.
Une fois que vous avez compris comment travailler et traiter les images sur l'IPFS, vous pouvez commencer à l'utiliser sur vos projets Web3 spéciaux.
Jusqu'à la prochaine fois, continuez à l'écraser!
Voir l'utilisation de la démonstration en direct sur mon projet NFT sur le testnet Goerli ici . Voir l'emplacement d'Opensea ici . Vous pouvez regarder la version vidéo sur ma chaîne YouTube.
Je suis un développeur blockchain complet avec plus de 6+
ans d'expérience dans l'industrie du développement de logiciels.
En combinant le développement de logiciels, l'écriture et l'enseignement, je montre comment créer des applications décentralisées sur des réseaux blockchain compatibles EVM.
Mes piles incluent JavaScript
, React
, Vue
, Angular
, Node
, React Native
, NextJs
, Solidity
, etc.
Abonnez-vous à ma chaîne YouTube pour apprendre à créer une application Web3 à partir de zéro. J'offre également des cours privés et spécialisés pour les personnes sérieuses qui souhaitent apprendre en tête-à-tête avec un mentor.
Maintenant, laissez-moi vous montrer comment représenter l'image et les métadonnées ci-dessus dans votre code.