How to create generative animated NFT art in under an hour!
Hi there! I’m James (aka Jalagar) and I am the developer for Fitness Friends. Here’s an article on how to created thousands of generated animated gif art in under an hour. This tool is 10x faster than the existing open source generative gif art tools out there, so hope you enjoy!
If you’re like me, and you have a short attention span, here’s a TLDR. Or here’s a walkthrough video.
TLDR:
What is generative art? Generative art is the programmatic way of creating art. For example in the collection above, I have 8 different backgrounds, 8 different colored balls, 6 hats, and 6 landscapes which using software can create 2304 unique gifs!
Problem: Current industry standard open source command line tools to generate art such as Hashlips’ art generative node don’t support animated images. Forked projects like MichaPipo’s Generative Art Engine utilize javascript image libraries which have issues such as; being slow, having bugs with pixel precision, and CPU usage.
Solution: I created a new generative gif engine command line tool which takes advantage of a well known Python library PIL to generate thousands of gifs 10x faster than other tools. You can generate a thousand gifs in under a hour! All you have to do is:
- Download the tool and install Python + Node.
- Export your art as separate .png layers and load them into the
layers
folder following the folder structure. - Change the default configurations
global_config.json
, and runmake all
. It will generate the gifs 10x faster than other tools out there and is completely free!
You can find the bouncing balls using this software on the production ETH chain on OpenSea. Follow me on Twitter for more updates on the tool and other tools I’m building for the NFT community. Feel free to DM me on Twitter, leave a comment on this post, or if it is related to the code, create a question on the discussion board or create an issue.
What is generative art?
Generative art refers to art that in whole or in part has been created with the use of an autonomous system. In the NFT space, it refers to using software to take individual layers and generate multiple possible combinations based on rarity.
For a simple example you could have two background layers:
Plus two transparent ball layers:
And the generative software would produce the following four images.
You can imagine with many attributes and many traits per attribute, things can get pretty crazy! You’ll see some more examples in a few sections.
Problem
At Fitness Friends, we wanted to create high quality animated NFTs depicting our fitness friends in action. I had already heard of Hashlips’ industry standard of generating static NFTs, and thought this can’t be hard.
But sadly, Hashlips’ software does not support gifs and animation. I looked far and wide, and was surprised to see the lack of established free open source generative art projects that support gifs. I didn’t want to use any websites where you had to upload your layers because the website could potentially leak the unfinished art. Plus uploading and downloading thousands of images seemed time consuming and lossy, and I didn’t want to pay. The only open source free project that looked promising was MichaPipo’s Generative Art Engine, which is forked from HashLips Generative Art Engine.
MichaPipo’s engine has two steps:
- Convert spritesheet layers to generative art spritesheet images.
- Convert spritesheet images to gifs.
But once I downloaded and got it working, I found a few issues:
- It had incredibly high CPU usage, especially during the gif generation step, and sometimes the software would run out of memory and crash.
- Sometimes certain pixels wouldn’t appear as the right color, even on the highest quality setting.
- It took about an hour to only generate a hundred gifs but my computer was almost unusable. I didn’t even try to generate a thousand gifs, let alone 10k.
I spent days trying to fix the software and played around with other javascript libraries, but could not fix any of the issues. I pinpointed that it was step 2 that was the culprit, and decided to start from scratch…
Solution
I honed in on optimizing the spritesheet to gifs step, and looked for open source tools, but only found websites that were more geared towards game development (nothing that scaled to thousands of images). I thought about using Python instead, and found Python Imaging Library (PIL) with almost 10k stars on Github. It worked perfectly.
After feedback from our artist that spritesheets were cumbersome to generate and create, I decided to add an additional step to convert .png frames directly to spritesheets so users of the program don’t even have to know about the underlying spritesheets.
Here is the new and improved generative art engine jalagar/Generative_Gif_Engine which has now three steps:
- [Python] Converts .png layers into spritesheet layers using PIL. This step can be skipped if you already have the spritesheet layers, but is useful if you want to start with png files and makes the artist’s life easier!
- [Node] Create generative spritesheets from the layers from step 1 using MichaPipo’s Generative Gif Engine.
- [Python] Convert spritesheets to gifs using PIL and also generate individual frames.
The entire process is:
.png layers -> spritesheet layers -> spritesheet generative art -> gifs
and can be run with one command make all
in the repo after the initial installation.
Step 1:
This step uses PIL to convert the layers into spritesheets to be used in step 2. Place your layers in the /layers
folder following the format in the README with the rarity weight and hit run.
Example input layers:
Two backgrounds:
The software is smart enough to know that if you only include one image, it will be duplicated to equal the total number of frames.
Two ball with individual frames:
Two hats:
and two landscapes:
Then the /output
will be the corresponding spritesheets needed in step 2.
Output:
Step 2:
This step is taken from MichaPipo’s Generative Art Engine and turns the spritesheet layers into generated sprite sheet sequences. I purposely kept this in Node instead of rewriting it in Python because most of the open source NFT generative art community writes code in javascript and I plan to continuously update the repo with the latest features.
This step takes in an ordering of layers, in this example it would be background -> landscape -> ball -> hat.
The resulting output looks something like (4 out of the 16 total):
Step 3:
This step was the culprit in MichaPipo’s repo, and is completely rewritten from scratch in Python using PIL. A process that used to take hours (if your CPU could even handle it), now takes under an hour with very limited CPU usage.
This step turns the generative spritesheets from step 2 into gifs. Example output (6 out of the 16)!
The sky really is the limit, and I added a few more layers to generate an entire collection. You can view all the different layers in the repo, and there are a total of 2304 combinations. Try running the program to see them for yourself (or check out the OpenSea collection for a subset of 1000 of them). A few can be seen at the top of the page too.
You can also add a flag saveIndividualFrames
which would export the individual frames separately so people can use them for profile pictures.
Some metrics:
MichaPipo’s Generative Gif Engine:
15 NFT — 5 minutes with sometimes incorrect pixels.
100 NFT — one hour (with the computer being almost unusable).
15 NFT — 30 seconds with no pixel issues.
100 NFT — 3 minutes and 17 seconds with no pixel issues.
1000 NFT — 45 minutes with no pixel issues and no CPU issues.
Just by switching languages and rewriting parts of the tool, I was able to get a 10x speed up!
More information on how to setup the repo, as well as set the initial configurations and how to run it can be found in the README. You will need to be familiar with downloading Github repos, installing Python and Node, and running terminal commands to get it to work, but it should work out of the box with the existing layers without any changes in configuration.
Production
(this section is only if you have experience with deploying smart contracts and are familiar with setting the metadata URI on smart contracts)
Once you have generated the gifs and corresponding json
metadata, you can now use this in your smart contract. Follow the following steps:
- Upload the gifs to Pinata or IPFS directly.
- Update the
global_config.json
with the new IPFS URL. Then runmake update_json
to update the URLs in the JSON files. - Upload the JSON files to Pinata or IPFS directly.
- Run
setBaseURI
on your contract to point to the JSON. The gifs should now appear on OpenSea after you click refresh metadata! You’re done!
Closing notes
Hope you enjoyed this article! The NFT generative art space is still very new so I would love to hear your thoughts! Huge shout out to MichaPipo’s Generative Art Engine and Hashlips’ art generative node for helping me learn and improve in this space. Check out Hashlips’ 📺 Youtube / 👄 Discord / 🐦 Twitter / ℹ️ Website for a more in depth explanation on how the generative process works.
Follow me on Twitter for more updates on the tool and other tools I’m building for the NFT community, I’ll be regularly updating the tool with extra features in the next few weeks. Feel free to DM me on Twitter, leave a comment on this post, or if it is related to the code, create a question on the discussion board or create an issue. Also follow my project Fitness Friends, we’ll be releasing soon…
If you want to support me in creating more of these articles, and if you want to own a bouncing ball yourself, you can put an offer on one of the balls that you like on OpenSea. Any offer is appreciated :).
Thank you for reading my first Medium post!