Generate NFT images using python and Jupyter Notebook
Let develop a nft image generator which generates a series of unique images using ...
For further actions, you may consider blocking this person and/or reporting abuse
Hello again!
Going off of your example above, if I just had the PNG of a blue circle in the center of my screen, is there any additional code I could write in order to position it in the top left section of the background automatically? If this isn't possible, what program could I use to make a new PNG in which the circle is in the right position?
Thanks so much! This is all very helpful for someone new to coding!
I recommend to keep everything simple by having all the png images in the same size.
You can center the object by right click => open with 3D paint => Choose select => move the object
this is the result
Oh thank you! Although I was looking to uncenter it. I have the letters "A", "B", "C" and "D" and I want it to be randomized between the four, but they're all centered and I want them to be randomized in the top left, top middle, top right, etc... (I drew a diagram to help) on a single background. Could this be done with coding or would it be easier to adjust each letter on it's own separate PDF file?
Oh in this case it's easier to set the image location then. You can use something like this to change the image location.
PUt these code into the generate images step
AH this is just what I was looking for! Thanks for all the help, like it seriously means a lot. Is there a way to stack this so it positions all 9 sets of images in a grid format?
I think you can make it work by manually set the position of these images like they are in a 2D array
2D will look something like
0------1----------2-------------3
|
1 image1 image2 image3
|
2 image 4 image5 image6
|
3 image7 image8 image9
PERFECT! Thanks so much!
One (maybe) last question: when uploading the generated NFTs to OpenSea via their “Create” button, will the 9 unique properties of each one show up on the Etherscan contract (i.e. if someone goes to the contract and reads it, will the property “Top Left = A”, “Top Middle = B”, etc… show up?)?
The metadata's attributes will be what they see
Cool! Is that embedded in the image or will I have to upload it to OpenSea manually somehow?
Well yes and no. You can create your own smart contract on Eth chain and host your NFTs on it. However, creating your own smart contract is quiet costly ( $700 or more on gas fee). This is a pro option.
Otherwise, you can use leapwork.com/ to set up automation flow to do this.
This is helpful!
I've actually been watching quite a few tutorials on making my own smart contract on Truffle Suite so I might give it a try for fun. I'm mainly going off of an article on Piñata's blog found here (medium.com/pinata/how-to-build-erc...), but I'm still not quite sure how to get the 8000+ images I generated using your code on-chain all at once, seeing as the article is describing how to do it one at a time. Plus, I'm still lost on how that could be directly listed on OpenSea. Any advice?
Edit: OpenSea itself has a tutorial on how to list your ERC-721 assets, so I think I'm covered there! I'm still confused on how to get all 8000+ images onto IPFS all at once, though.
Hey I have a question, I'm trying to run this portion of code
TOTAL_IMAGES = 30 # Number of random unique images we want to generate
all_images = []
def create_new_image():
Generate the unique combinations based on trait weightings
for i in range(TOTAL_IMAGES):
Except whenever this portion runs I get
an error saying RecursionError: maximum recursion depth exceeded in comparison. Any suggestions?
I hope you still check these forums.
May I know how many images you put into your background, circle and square folder? thanks
I just have two of each.
backgrounds (folder name)
-> blue.png
-> orange.png
circles
-> blue-circle.png
-> orange-circle.png
squares
-> blue-square.png
-> orange-square.png
Ok. Can you try to reduce the total images down to 8?
Reduce to 8? I only have 6 total images. blue.png, orange.png (background pics), two circles and two squares. Six total images.
Oh I see what you meant. I reduced it to 8 and It worked. What can I do to generate more images though? I mean the goal is generate a couple thousand images.
Could you explain the way the weights work?
You can add different colours and shapes (rectangle, star) to generate more images to get familiar. A good practice would be having different characters with a set of variation. For instance:
Furthermore, you can add more colours to create more images according to the following example.
[shape]_weights should be added up to 100 (optional) and the less the shape weights the less likely it will be populated.
`
background = ["Blue", "Orange"]
background_weights = [30, 40]
circle = ["Blue", "Orange"]
circle_weights = [30, 15]
square = ["Blue","Orange"]
square_weights = [30, 15]
turtle = ["Blue","Orange"]
turtle_weights = [30,15]
For example I added a new attribute called turtle above ^. But when the composite is formed the result images are only of the turtle and it doesn't include any of the orange or blue backgrounds or squares and circles.
Can you try to add a new composite? It will let the processor know which combination of shapes you want to generate.
for item in all_images:
`
You can use for statement to handle this process better. something like this
`
`
hi im having a little issue.
im really new this and i need some help. i change the background to png instead of jpg, because my file was a png. But i'm getting this error.would really appreciate some troubleshooting help
im1 = Image.open(f'./layers/background/{background_files[item["background"]]}.png').convert('RGBA')
4 im2 = Image.open(f'./layers/mouth/{mouth_files[item["mouth"]]}.png').convert('RGBA')
5 im3 = Image.open(f'./layers/spoon/{spoon_files[item["spoon"]]}.png').convert('RGBA')
/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/PIL/Image.py in open(fp, mode, formats)
2966
2967 if filename:
-> 2968 fp = builtins.open(filename, "rb")
2969 exclusive_fp = True
2970
FileNotFoundError: [Errno 2] No such file or directory: './layers/background/purple.png'
There're 2 places you need to declare the colour
`
If you have done it but still getting error, could you please let me have a look at your folder/file structure?
background_files = {"blue": "blue", "green":"green", "LG": "LG", "pink": "pink", "purple": "purple", "orange": "orange"}
eyes_files = {
"I1": "I1", "I2": "I2", "I3": "I3", "I4": "I4", "I5": "I5", "I6": "I6","I7": "I7","I8": "I8","I9": "I9", "I10": "I10","I11": "I11", "I12": "I12", "I13": "I13", "I14": "I14", "I15": "I15", "I16": "I16"}
mouth_files = {"M1": "M1", "M2": "M2","M3": "M3", "M4": "M4", "M5": "M5", "M6":"M6", "M7": "M7", "M8": "M8", "M9": "M9", "M10": "M10", "M11": "M11"}
spoon_files = {"S1":"S1", "S2":"S2", "S3": "S3", "S4": "S4", "S5": "S5", "S6": "S6", "S7":"S7", "S8": "S8", "S9": "S9", "S10": "S10", "S11": "S11", "S12": "S12", "S13": "S13", "S14": "S14", "S15": "S15", "S16":"S16"}
so did this to my files and intead of of layers,i changes it to images
m1 = Image.open(f'./images/background/{background_files[item["background"]]}.png').convert('RGBA')
this fixed my intial problem.but i now have anew one :
10 com2 = Image.alpha_composite(com1, im3)
11 com3 = Image.alpha_composite(com2, im4)
12
/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/PIL/Image.py in alpha_composite(im1, im2)
3042 im1.load()
3043 im2.load()
-> 3044 return im1._new(core.alpha_composite(im1.im, im2.im))
3045
3046
ValueError: images do not match
Looks like it cannot find the images with the given names. Can you show me the declaration of im2 im3 and im4 as well? Thanks
here they are, thank you so much for all your help. i really appreciate it
im1 = Image.open(f'./images/background/{background_files[item["background"]]}.png').convert('RGBA')
im2 = Image.open(f'./images/mouth/{mouth_files[item["mouth"]]}.png').convert('RGBA')
im3 = Image.open(f'./images/spoon/{spoon_files[item["spoon"]]}.png').convert('RGBA')
im4 = Image.open(f'./images/eyes/{eyes_files[item["eyes"]]}.png').convert('RGBA')
hi victor, thanks for all your help. I realised that one of my images was not the same dimension as the other. i think that created the error. i've since resolved it and managed to generate the little images! thanks so much for the speedy replies and all your help!
Congrats! You got it. Thanks for reading my blogs. I'm about to upload another post soon. Please consider to check it out. Thanks again
Thanks for sharing! Just what I needed!
How would I upload these to Opensea?
What do I do with the Png and the Json metadata? Do I need to upload both files to somewhere?
Furthermore, if I am creating a collection of 5,000 NFTs is there an automated way to upload each file to Opensea?
Look forward to your reply, thanks! :)
Hi Chris! Great questions.
How would I upload these to Opensea?
This is another blog of mine which will show you how to upload images to Opensea.
dev.to/victorquanlam/step-by-step-...
What do I do with the Png and the Json metadata? Do I need to upload both files to somewhere?
Yes you need to create new shapes folder and upload your png images there and you don't have to upload the Json metadata. It already be generated by the script below:
`
Furthermore, if I am creating a collection of 5,000 NFTs is there an automated way to upload each file to Opensea?
Yes and no. As right now, the opensea api doesn't support upload images YET. We will need to wait for the next version. This is their comment to the situation: "there isn't currently an option for that in your OpenSea profile, but we're constantly working on ways to improve user experience".
The only way for now is to create your own smart contract most likely on ETH chain. Then upload your images to IPFS server and connect your contract to opeasea. (I know! Yikes)
Thanks for your quick reply! :)
In response to my 2nd question, the Metadata will already be already included within the PNG files from that line of code you show? So I could just upload the image created onto Opensea and the metadata will also be uploaded too?
Ah okay! Still trying to wrap my head around the smart contracts, a lot more complicated than uploading each file one by one on Opensea :S
As you can see the metadata files will be generated under the metadata folder.
You can run this little javascript to update the meta data
`
Check this article out for more details about metadata
docs.opensea.io/docs/2-adding-meta...
Hope it helps.
Great thanks!
Sorry to keep asking questions! There is a lot to learn.
What do I put in here:
IMAGES_BASE_URI = "ADD_IMAGES_BASE_URI_HERE"
I'm still a little confused as to what to do after creating the PNG and Metadata files. Do I need to upload these onto IPFS and then upload that to Opensea? Or if I upload the PNG files directly to Opensea it would automatically do it for me?
This is where you store your images for public views. It can be used when creating your smart contract.
Hope this gives you enough hint. I'm working on a web app to generate pixelated nft arts at the moment so I don't have much time to explain things in much details. I would create a new blog post for creating ERC721 Token and nft in the near future.
I am new to python and coding in general and this is a great post and very easy to follow. I am almost there on this but am having issues with generating the metadata. The error I am receiving is as below.
--> 141 for i in metadata:
142 token_id = i['tokenId']
143 token = {
NameError: name 'metadata' is not defined
Can you try to create a new folder called metadata? I reckon it's missing.
I have one called metadata...where should it reside in the folder structure? I have it in the project folder
oh I think it supposed to be for i in data instead of for i in metada
Similar error but now as below....do I need a folder also called data and if so where does that reside?
139 "value": value
140 }
--> 141 for i in data:
142 token_id = i['tokenId']
143 token = {
NameError: name 'data' is not defined
This seems to be the area where it is failing
for i in data:
token_id = i['tokenId']
token = {
"image": IMAGES_BASE_URI + str(token_id) + '.png',
"tokenId": token_id,
"name": PROJECT_NAME + ' ' + str(token_id),
"attributes": []
}
Oddly enough I ran this again today and now a new error:
C:\Users\CHRIS~1.STA\AppData\Local\Temp/ipykernel_27868/3811645234.py in
139 "value": value
140 }
--> 141 for i in data:
142 token_id = i['tokenId']
143 token = {
TypeError: 'function' object is not iterable
hmm strange. I haven't got any problem like this.
Check the source code out. Hope it helps
github.com/victorquanlam/nft-creator
Hi Victor! Thank you for sharing such a great step by step instruction and answering queries here. I finished everything and have generated some examples. I was just wondering does it matter if the metadata that was generated for each image contains "ADD_IMAGES_BASE_URI_HERE0.png" and "ADD_PROJECT_NAME_HERE 0"? I forgot to add some details here. What if I want to upload into the marketplace like OpenSea? I have attached a screenshot for your reference.
Great question! This image URI only matter if you have your own smart contract and connect your smart contract onto Opensea. Otherwise, you just have to change the titles of your images to what ever you like (by updating the [ADD_IMAGES_BASE_URI_HERE]). Please note that creating your own smart contract is a bit tricky and costly as well due to the gas fee( lowest would be $700 on a less traffic day)
Got it! Correct me if I am wrong, I already have some NFTs on Opensea and I have initially paid the fees. If I upload it manually I will not be paying gas fees again correct? If I create a smart contract to bulk upload my NFTs then I need to pay those gas fees again?
If you store your nft on IPFS storage, you can change your image data whenever you wish. Yes that's right. If you mint (create) a new token aka (new nft) on your smart contract you will have to to pay the gas fee. Otherwise, you can change the metadata of your nft on the opensea nft website without any fees.
Very informative. Really enjoyed your articles and nice talking to you makes my head clear. Keep up the good job! 👍
Thanks for all the support.
Hi.
Thank you very much for the code
i was wondering if you could assist in the following error I'm getting .
Thanks
""
with open(METADATA_FILE_NAME, 'w') as outfile:
FileNotFoundError: [Errno 2] No such file or directory: './metadata/all-traits.json'
"
Could you double check if you have metadata folder created?
Hi,
Thank you for the quick reply,
i believe the folder was not in the right place =)
Thank you for the heads up.
hi victor, succed the code with my android phone, my questions is why the result image adding so much noise.? how to solve
Interesting! I didn't try it on my phone before tbh. Can you possibly send me your output files?
I don't think the problem is with the noise, but because the resulting image is half transparent and looks dark
com1 = Image.alpha_composite(im1, im2)
com2 = Image.alpha_composite(com1, im3)
and I need the image without making it half transparent just like pasting the image.
can you solve it.?
Original Background
Result Image
Thank you very much
Hmm interesting. Can you make sure that the second im2 or the im3 do not have any background noise?
solved, that because i have active filter in my photo editor. that make a result not completely transparent Lol...
thanks for your respons victor, this code is amazing 👍👍👍
You're welcome mate
Hi Victor, is it possible to create over 50 images at once? I can successfully create 50, but when I try to do anything over 50, I get an (Error: Sesson cannot generate requests). Is this something hardcoded in one of the files being used in the jupyter notebook (extension.js) or could this possibly be due to me not having enough layers/traits? Thank you for any direction. Below is the error I'm getting.
Error happens on this code block:
Returns true if all images are unique
def all_images_unique(all_images):
seen = list()
return not any(i in seen or seen.append(i) for i in all_images)
print("Are all images unique?", all_images_unique(all_images))
Error is:
Error: Session cannot generate requests
Error: Session cannot generate requests
at w.executeCodeCell (c:\Users\theja.vscode\extensions\ms-toolsai.jupyter-2021.8.2041215044\out\client\extension.js:52:301310)
at w.execute (c:\Users\theja.vscode\extensions\ms-toolsai.jupyter-2021.8.2041215044\out\client\extension.js:52:300703)
at w.start (c:\Users\theja.vscode\extensions\ms-toolsai.jupyter-2021.8.2041215044\out\client\extension.js:52:296367)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async t.CellExecutionQueue.executeQueuedCells (c:\Users\theja.vscode\extensions\ms-toolsai.jupyter-2021.8.2041215044\out\client\extension.js:52:311160)
at async t.CellExecutionQueue.start (c:\Users\theja.vscode\extensions\ms-toolsai.jupyter-2021.8.2041215044\out\client\extension.js:52:310700)
It is due to the lack of layers I reckon. You should try to add more layers and images.
Otherwise, you can try this nodejs app if you are familiar with Javascript. This code will generate more than 800,000 crypto punks without any problem. Check it out
dev.to/victorquanlam/generate-879-...
github.com/victorquanlam/cryptopun...
Thank you Victor. I ran the 800,000 crypto punk program and got it to work. Is there a way to lessen the number if wanted?
You are much welcome Jason. Normally people ask for more not less haha. I think you can delete a few inputs images/ layers to reduce the outputs.
However, I will add a new feature to manipulate the number of outputs for you shortly.
I have made changes to the code. You can now limit the outputs. Pull the latest code and run
node index.js 100
Hi!
I get to the step where it says: jupyter notebook and receive an error.
I attached the image of the error message I receive. I've updated everything, searched around, can't figure it out. I do get a path warning on one of the steps for installing, but other than that it says success for everything up to "jupyter notebook. Has anybody experienced this?
Thank you! Also new to coding. First Python project:
Steps I followed:
1 curl bootstrap.pypa.io/get-pip.py -o get-pip.py
2 python get-pip.py
3 Install Python Pillow: pip install pillow
4 Install Python display: pip install display
5 Install Jupyter Notebook: pip install jupyter
6 Set up developing folders similar to the following structure
7 Shift + right click => choose PowerShell
8 Run Jupyter in your generator folder
9 jupyter notebook .>>>>>>> error appears
hi, i have a question, so how would i go about making a certain layer have a 50/50 chance of appearing?
let's say i have a list of 50 "hats" and each of those hats has a certain weight (whatever weight, doesn't matter)
but i would also want the "hats" layer itself to have a weight (50/50 for example)
so when the hat layer DOES appear, THEN it would have a random chance of picking one of those hats from the list.
little help would be much appreciated.
Hey there Victor
First of let me start by saying thank you for your code, I have used it and I extended it to randomize how many features will be taken for each Picture.
For example some will only have a background or some will have a background and a circle.
The code works but im struggling with the last step of creating a picture. The problem is in your code all 3 attributes are always included in the dictionary so you know that the program needs to open all three layers and you will always have to stack them up the same way. Now in my code there are instances where only 2 attributes are used and therefore only those two layers need to be opened and and merged.
I have solved it with different if statements but I was wondering if there is a smoother way to do so.
Thank you for your answer in advance
You can use the filename reader to solve this issue. You can use it to read and the folder names and figure out the layers you want to draw onto your image.
Anyway, this is only a basic program which introduces people to images generator and Python. And yet you will have to manually add the layer names and bit of code for combination. For something a bit more advanced where all the layers get included themselves please check another blog of mine out.
dev.to/victorquanlam/generate-879-...
Hello Victor,
I've been using your tutorials and i have one question related to the tiny javascript that you provided to update the URI of the images.
I'm sitting with about 50 images, already uploaded the images folder to the ipfs, i now have the correct URI to paste into each json file, 0 to 49, still running your javascript it doesn't update the files.
This is the metadata of file 0.
{
"image": "gateway.pinata.cloud/ipfs/ccid/0.png",
"tokenId": 0,
"name": "",
"attributes": [.....
Should i run the script with: node vitor.js all-traits.json ?
Thank's for the help you provided and looking forward to follow your nexts projects.
Miguel,
Hey Victor, I have everything in there but keep getting an error message in relation to saving the images to a file. Can you please help out. New to the PIL function but is the f in Image.open(f'... the folder location or what does the f designate?
FileNotFoundError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_25676/1624990664.py in
1 for item in all_images:
2
----> 3 im1 = Image.open(f'./layers/backgrounds/{background_files[item["Background"]]}.jpg').convert('RGBA')
4 im2 = Image.open(f'./layers/circles/{circle_files[item["Circle"]]}.png').convert('RGBA')
5 im3 = Image.open(f'./layers/squares/{square_files[item["Square"]]}.png').convert('RGBA')
~\AppData\Roaming\Python\Python39\site-packages\PIL\Image.py in open(fp, mode, formats)
2966
2967 if filename:
-> 2968 fp = builtins.open(filename, "rb")
2969 exclusive_fp = True
2970
FileNotFoundError: [Errno 2] No such file or directory: './layers/backgrounds/orange.jpg'
Hi!
I get to the step where it says: jupyter notebook and receive an error.
I attached the image of the error message I receive. I've updated everything, searched around, can't figure it out. I do get a path warning on one of the steps for installing, but other than that it says success for everything up to "jupyter notebook. Has anybody experienced this?
Thank you! Also new to coding. First Python project:
Steps I followed:
1 curl bootstrap.pypa.io/get-pip.py -o get-pip.py
2 python get-pip.py
3 Install Python Pillow: pip install pillow
4 Install Python display: pip install display
5 Install Jupyter Notebook: pip install jupyter
6 Set up developing folders similar to the following structure
7 Shift + right click => choose PowerShell
8 Run Jupyter in your generator folder
9 jupyter notebook .>>>>>>> error appears
Ok I have searched through the comments, I searched the internet but found no answer. So here I am!
1= curl bootstrap.pypa.io/get-pip.py -o get-pip.py
2= python get-pip.py - I receive a warning (pasted at bottom)
3= Install Python Pillow: pip install pillow
4= Install Python display: pip install display
5= Install Jupyter Notebook: pip install jupyter
6= Set up developing folders similar to the following structure: (this is folder on desktop)
7= Shift + right click => choose PowerShell
8= Run Jupyter in your generator folder: jupyter notebook: I get this error:
8= jupyter : The term 'jupyter' is not recognized as the name of a cmdlet, function,
script file, or operable program. Check the spelling of the name, or if a path was
included, verify that the path is correct and try again.
At line:1 char:1
8= same error after downloading anaconda
I can't figure out what I'm doing wrong!
2= WARNING: The scripts pip.exe, pip3.9.exe and pip3.exe are installed in 'C:\Users\david\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\Scripts' which is not on PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
ValueError Traceback (most recent call last)
in
8 #Create each composite
9 com1 = Image.alpha_composite(im1, im2)
---> 10 com2 = Image.alpha_composite(com1, im3)
11
12 #Convert to RGB
~\anaconda3\lib\site-packages\PIL\Image.py in alpha_composite(im1, im2)
2962 im1.load()
2963 im2.load()
-> 2964 return im1._new(core.alpha_composite(im1.im, im2.im))
2965
2966
ValueError: images do not match
Can someone help i only replace one element in square
May I see your changes?
This is how we started, and it's a great way to create NFTs. However, for most users, this is too advanced. That's why we created a No-Code platform that is "grandma-proof."
Our main goal is to attract more users to the Web3 space. We make difficult Web3 tasks like creating NFTs affordable, fast, and simple. 😍
Our NFT Generator lets users No-Code generate images and create a smart contract to deploy on the blockchain.
Our website
imintify.com
Youtube:
youtube.com/@imintify
Hi Victor, can you message me please. Have an offer for you
I can't message you but what's your offer?
can you message me on instagram, talk there/ @shoeuzi
i send you a mail. I need some generated images created, want to pay you to do it
hi. how can i calculate population is there any formula for calculating with weightings. if possible an example will be perfect.
Hello,
Can you explain how rarity works on this code.
great work, I'm looking for a NFT sales bot bot twitter and discord, can u help wiz that!!
thanks in advance
does PIL image not work with osx? i keep getting an error
FileNotFoundError: [Errno 2] No such file or directory: './layers/backgrounds/blue.jpg'
actually figured out the issue.
i couldnt use this
im1 = Image.open(f'./layers/backgrounds/{background_files[item["Background"]]}.jpg').convert('RGBA')
instead of ./ in the fstring formatting i had to put the entire file location. any way i can shorten that?
Hello Victor,
May I have your permission to use your code for an Opensea NFT project I am working on?
yeah that's for sure. Could you please starred the repository on Github. That would mean a lot
Thank you so much! I starred this one along with your javascript cryptopunk repo on Github :)
Why does mine only output the last image? it creates all the metadata, but only image 7 is in the images folder!