El primer paso que tomará para construir una Dapp de acuñación de NFT es preparar la obra de arte. Sin la obra de arte, no puede actualizar su proyecto NFT.
Otra razón para preprocesar sus obras de arte es generar metadatos para cada una de las imágenes. Sin estos metadatos, su NFT no se puede vender en ninguno de los grandes mercados secundarios, como Opensea.
Por ejemplo, la imagen a continuación es un NFT en el mercado de Opensea que contiene algunos metadatos que también se pueden ver a continuación.
La información anterior, incluida la obra de arte, sus detalles y características, se puede ver en la imagen de IPFS a continuación.
Abra su terminal y navegue hasta el directorio de su proyecto o cree una carpeta de proyecto en una ubicación específica. Por ejemplo, ejecutar **mkdir preprocessor**
en la terminal creará una carpeta llamada " preprocesador" en su ubicación especificada.
A continuación, ejecute los siguientes comandos en la terminal.
cd preprocessor npm init -y npm install sharp @faker.js/faker --save-dev
Los comandos anteriores instalarán las bibliotecas Sharp y Faker en su proyecto. La biblioteca faker nos ayudará a generar información aleatoria. Mientras que la biblioteca nítida nos ayudará a procesar la imagen a una determinada dimensión, calidad y formato.
A continuación, crea una carpeta en tu proyecto llamada arts
y otra llamada outputs
. En la carpeta "artes", coloque todas las imágenes para procesar dentro.
Una vez realizados los pasos anteriores, abra el proyecto en "código VS". La estructura del proyecto debe parecerse a la siguiente.
- preprocessor/ - arts/ - node_modules/ - outputs/ - package.json - package-lock.json
Genial, pasemos a codificar el motor encargado de procesar las imágenes.
Necesitará lo siguiente instalado en su computadora para completar este tutorial.
Cree un archivo en la raíz de su proyecto llamado **imagify.js**
y pegue el siguiente código
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++ } })
Los siguientes pasos lo ayudarán a comprender cómo funciona este motor de procesamiento de metadatos.
Importación de bibliotecas esenciales
const fs = require('fs') const path = require('path') const sharp = require('sharp') const { faker } = require('@faker-js/faker') const input = './arts' const output = './outputs'
El fs
representa el sistema de archivos, es un módulo incorporado que viene con NodeJs. Tiene la responsabilidad de administrar las actividades de lectura y escritura de archivos en su máquina.
La path
es otro módulo de nodo que lo ayuda a navegar a través de las estructuras de directorios en su máquina. Esto será fundamental para localizar dónde se guardan nuestras imágenes.
Sharp es el módulo que usamos para procesar la imagen, como cambiar el tamaño y transformar a un tipo de archivo diferente.
Usaremos el falsificador para generar un número aleatorio.
Por último, la variable de input
contiene la ubicación donde se encuentran las imágenes a procesar y la output
apunta a la ubicación donde se guardarán las imágenes procesadas.
Definición de variables esenciales
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()), }
Los códigos anteriores contienen variables importantes que se utilizarán en el curso de la generación de nuestros metadatos.
**Image_counter**
nos ayuda a numerar las imágenes de manera consistente con la iteración actual.**ImgSize**
define la dimensión del ancho y el alto de cada imagen a procesar.**Desired_ext**
habla del formato de archivo que desea que tengan sus imágenes procesadas.**Base_url**
especifica la ubicación donde se almacenarán las imágenes en el IPFS.**Attributes**
contiene más información sobre los metadatos de cada imagen.
Ejecutando Tarea Recursiva
fs.readdirSync(input).forEach((file) => { if(['.jpg', '.jpeg', '.png', '.gif', '.webp'].includes(orginal_ext)) { // Images and metadata tasks are recursively performed here... } })
En el bloque de código anterior, usamos la biblioteca del sistema de archivos (fs) para recorrer todas las imágenes en la ubicación de **input**
(artes). Y para cada una de las imágenes, nos aseguramos de que nuestro motor solo seleccione imágenes de una lista aprobada de extensiones.
Realización de la tarea de metadatos
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, }, ], }
En el bloque de código anterior, proporcionamos valores para cada espacio de metadatos. Por ejemplo, los entornos, las armas y todos los valores de los rasgos se proporcionan de forma aleatoria y dinámica.
Realización de la tarea de transformación de imagen
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++
En el fragmento anterior, usamos el módulo del sistema de archivos nuevamente para ubicar primero cada una de nuestras ilustraciones y cambiar su tamaño a nuestra dimensión especificada (500 x 500). Además, proporcionamos un nuevo nombre en línea con la iteración actual y le dimos la extensión deseada (webp).
Cambiar el tamaño y transformar las imágenes en webp
optimizó en gran medida nuestras obras de arte a una altura asombrosa.
Por ejemplo, donde sometí este motor de preprocesamiento de imágenes a 99
imágenes que suman un tamaño de 111MB
. El tamaño se redujo a .webp
MB para la extensión .png
y 4.5MB
para la extensión 62MB
. Esa enorme reducción de tamaño representa un gran salto en el tiempo de carga de un sitio web de Minting creado con mis imágenes.
Por último, a partir del bloque de código anterior, creamos metadatos JSON
para cada imagen procesada, con un nombre idéntico y una URL que apunta a la ubicación de la imagen. Estos metadatos son los que implementaremos en IPFS después de procesar las imágenes.
Ahora, ejecute el siguiente comando para transformar su imagen. Asegúrese de estar en la carpeta de su proyecto.
node imagify.js
En este punto, hemos terminado con nuestro motor de imágenes, nuestra carpeta de salida debería tener la siguiente estructura de archivos como resultado.
- output/ - images - 1.webp - 2.webp - ...... - metadata - 1.json - 2.json - ......
IPFS significa sistema de archivos interplanetarios, es peer-to-peer y descentralizado. No existe una manera fácil de extraer datos almacenados en IPFS y, como tal, es un par casi perfecto para usar junto con sus aplicaciones de cadena de bloques para almacenar contenido multimedia.
Para usar la forma fácil y menos confusa, diríjase a la página de instalación de la aplicación IPFS Desktop y siga las instrucciones especificadas allí.
Después de que la instalación sea exitosa, abra la aplicación IPFS y cargue PRIMERO, y repito, PRIMERO cargue la carpeta de imágenes.
Se generará una cadena CID (Identificación de contenido) única como parte del nombre de la carpeta, vea la imagen a continuación.
Ahora, copie el CID de la carpeta de imágenes como se puede ver en la imagen de arriba, y reemplácelo en su código **imagify.js**
. Vea el código a continuación.
const base_url = "https://ipfs.io/ipfs/REPLACE_WITH_IPFS_CID/" //old string const base_url = "https://ipfs.io/ipfs/QmY1zrFibpdHQ7qcqZqq7THsqTremZYepXNWR5Au3MF1ST/" //new string
Ahora, ejecute **node imagify.js**
nuevamente para incluir la ubicación precisa de cada imagen en sus metadatos JSON . Vea un ejemplo de los metadatos JSON generados antes y después del reemplazo del CID.
Puede ver este video para comprender cómo utilicé estas imágenes y metadatos en un proyecto completo de acuñación de NFT.
Antes del reemplazo de 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 } ] }
Después del reemplazo de 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 } ] }
Finalmente, como se muestra en la imagen a continuación, suba la carpeta de metadatos a IPFS junto con la carpeta de imágenes.
Fantástico, ahora fijémoslo en la web para que el mundo lo vea. Actualmente, ambas carpetas se encuentran en su nodo IPFS local (su computadora), para que sea accesible en todo el mundo, debe usar un servicio de fijación como Pinata .
Primero, dirígete al administrador de pines de Pinata y regístrate si no lo has hecho antes. Luego haga clic en el icono de la cuenta y seleccione Claves API. Vea la imagen a continuación.
En la página de creación de claves, haga clic en crear una nueva clave e ingrese el nombre de la clave. Observa la imagen de abajo.
Ahora copie la clave JWT en su portapapeles. Esto es lo que usaremos para vincular nuestro IPFS Desktop con nuestra cuenta de Pinata. Vea la imagen a continuación.
A continuación, abra su aplicación de escritorio IPFS, diríjase a la pestaña de configuración y agregue un nuevo servicio, seleccione Pinata y pegue su token JWT en el espacio proporcionado. Consulte la imagen a continuación.
Lo último que debe hacer es anclar sus carpetas a Pinata usando las instrucciones a continuación.
Dirígete a la pestaña de archivos, haz clic en la línea de puntos triples y selecciona establecer fijación. Esto aparecerá en la imagen de abajo.
Seleccione Pinata y aplique, al hacerlo, su carpeta de imágenes será accesible globalmente.
Diríjase a este sitio web, copie y pegue su CID en el campo de entrada de IPFS y haga clic en el botón de caché. Esto escanea todo el conjunto de puertas de enlace IPFS disponibles públicamente en busca de sus imágenes. Vea la imagen a continuación.
Los resultados de la imagen de arriba muestran que muchos nodos IPFS ahora tienen copias de la carpeta de imágenes disponibles y accesibles globalmente, incluso si eliminó la copia original en su nodo local.
Con los pasos claramente descritos para usted, también ancle la carpeta de metadatos para que estén disponibles públicamente en línea.
Ahora puede usar cualquiera de los enlaces en la imagen de arriba como su URL base para tokens ERC721 . Vea la imagen a continuación.
Y ahí lo tienes, así es como preparar y cargar tus obras de arte en IPFS.
Siempre encontrará la necesidad de comprender cómo preprocesar y cargar obras de arte en el IPFS a escala de lotes.
Una vez que comprenda cómo trabajar y procesar imágenes en IPFS, puede comenzar a usarlo en sus proyectos web3 especiales.
¡Hasta la próxima, sigue aplastándolo!
Vea el uso de demostración en vivo en mi proyecto NFT en la red de prueba de Goerli aquí . Vea la ubicación de Opensea aquí . Puedes ver la versión en video en mi canal de YouTube.
Soy un desarrollador de blockchain de pila completa con más de 6+
años de experiencia en la industria del desarrollo de software.
Al combinar el desarrollo de software, la escritura y la enseñanza, demuestro cómo crear aplicaciones descentralizadas en redes de cadena de bloques compatibles con EVM.
Mis pilas incluyen JavaScript
, React
, Vue
, Angular
, Node
, React Native
, NextJs
, Solidity
y más.
Suscríbete a mi canal de YouTube para aprender a crear una aplicación Web3 desde cero. También ofrezco clases privadas y especializadas para gente seria que quiere aprender uno a uno de un mentor.
Reserva aquí tus clases de Web3 .
Ahora, déjame mostrarte cómo representar la imagen y los metadatos anteriores en tu código.