skip to content
Steve Simkins

Resizing IPFS Images with Pinata’s Image Optimization Tools

Learn how to use Pinata's Dedicated Gateway image optimization tools

Link to Medium Read this post on Medium

If you’re a developer in the NFT space, you have probably had to fetch IPFS content before, and depending what tools you use the experience is varied. Using a local IPFS node is not very practical or fast, and using a public gateway can be risky due to congestion. Dedicated Gateways on the other hand are much faster, and are great for app development. But what if you have to fetch an entire NFT project through IPFS? That could be 10,000 images at 5Mb each, awful for web page optimization, and you have to load every. single. one. How is that gonna work? And then what happens when you have another NFT project?

Pinata’s Dedicated Gateways already have a blazing fast global CDN (content delivery network) that caches content on the first load, so already you’re off to a good start, but that’s still a lot of data to pull through a webpage. With the rollout of our new pricing plan and features, we’ve released a new tool for everyone: Pinata Image Optimization.

Built on top of Pinata’s Dedicated Gateways, Pinata Image Optimization allows you to resize images on the fly with URL queries, all through your own gateway. Seriously. For faster web pages and reduced bandwidth, all you have to do is add a few text characters to the end of your image link. Let’s go through how it works with an example to show how you can use it to speed up your projects.

How To Use Pinata Image Optimization

Image Optimization works by adding queries to the end of our Dedicated Gateway urls. Here’s an example of a basic dedicated gateway url:

https://stevedsimkins.mypinata.cloud/ipfs/{CID}

The CID is the content identifier and how we stream IPFS content. Just for our example, I have a CID of an image I shot out west and uploaded to Pinata!

QmfKsRfqkWYuShSMDghMpLt8SQnWyPhDaEe8JUauM8E7Uz

Now if we add this file to our gateway, we get this:

https://stevedsimkins.mypinata.cloud/ipfs/QmfKsRfqkWYuShSMDghMpLt8SQnWyPhDaEe8JUauM8E7Uz/

If you click that link you’ll see our image. If that link took a few seconds to load, there’s a reason for that: it’s huge. Shot on an old medium format film camera and scanned at high resolution, this picture of the Badlands National Park is 10,000 x 10,000 pixels, coming in at around 38Mb. For context, your standard web images are under 300K.

While the dedicated gateway uses a global CDN to cache the content on the first load, it’s still a lot to load. Most websites are gonna struggle using this image, but if you’re building something like Foundation or SuperRare, or any project that relies on a lot of images, you might not want to give up that full size image. And you certainly don’t want to take the time resizing them one by one.

And that’s where our tool comes in. Let’s see Pinata Image Optimization in action.

To add on the image resizing query to the url, we simply need to add a “?” with the query itself. Here’s an example of changing the width of an image to 1080 pixels:

?img-width=1080

If we want to change the height too, we just need to use an ampersand (&) to add on another query:

?img-width=1080&img-height=1080

Now all we need to do is add this little snippet to our previous image url:

https://stevedsimkins.mypinata.cloud/ipfs/QmfKsRfqkWYuShSMDghMpLt8SQnWyPhDaEe8JUauM8E7Uz?img-width=1080&img-width=1080

Check that out. Instead of being a 10,000x10,000 resolution, it’s now 1080x1080 and only 266Kb. Doesn’t get any simpler than that — and this is only the beginning of what this tool can do. Here’s a small list of other things you can do:

  • DPR (Device Pixel Ratio)
  • Image Fit — for scaling down, image positions and more!
  • Image Quality — Set a scale from 1–100 to easily reduce a high quality image
  • Auto Image Formatting — Use Webp where supported, but then fall back to jpeg or png
  • Animation Still — Turn a gif into a still image
  • On Error Redirect — Redirect to a different image if there is a problem
  • Metadata Controls — Control what EXIF data is revealed with the image

Pinata Image Resizing really gives you control as a developer in the NFT space to handle IPFS images with ease. We highly recommend checking out our developer docs to see them all.

To really understand what’s possible with this tool, let’s look at a real world example.

Displaying a 10K PFP Project

When it comes to NFT projects, right now the classic 10,000 PFP project is the industry standard — it’s what everyone is trying to create. But if you’re an NFT marketplace trying to get up and running, you’re almost certainly going to run into some problems if you have to load an entire 10K project on a single webpage. The speed is going to suffer greatly, especially if you are pulling full sized large images from IPFS.

In our example, we’ll make a simple app that displays more images I took out West in the Badlands. First thing we need to do is spin up a React app by running the following in our terminal:

npx create-react-app ipfs-image-optimization

cd ipfs-image-optimization && npm start

Then we’ll delete the CSS files and boilerplate in App.js. We’ll also add in some structure for our image grid.

function App() {
	return (
		<div className="App">
			<div className="grid"></div>
		</div>
	);
}
export default App;

Usually a PFP project will be in a single folder, and each file inside will be named in sequential order such as “1.png, 2.png, 3.png,” etc. This makes our base URL very simple. The only thing that will be changing will be the ID of the image, so it looks like this:

https://stevedsimkins.mypinata.cloud/ipfs/QmTwDNr6LyRzW8H3XorFDArfKEH3GRV1SkF6bAEBF3P4GJ/${id}.jpg?img-width=1080&img-height=1080

Let’s break this down again so we know what’s going on.

We have our gateway url https://stevedsimkins.mypinata.cloud/ipfs/, then we have our CID QmTwDNr6LyRzW8H3XorFDArfKEH3GRV1SkF6bAEBF3P4GJ, then our dynamic image id ${id}.jpg and finally our image optimization ?img-width=1080&img-height=1080. Of course not all PFP projects are this simple, but with this formatting you can pass in multiple parameters with objects to adjust to your needs.

Our image folder only has 8 images, therefore we just need a simple for loop to generate an array that will hold the numbers 1 through 8. That way we can access it later to generate our image components. Just start with an empty array, then push the numbers into it with the for loop.

let imageIds = [];
for (let id = 1; id <= 8; id++) {
	imageIds.push(id);
}

Now the fun part: generating the images! We’ll take our imageId array and map over it.

{
	imageIds.map((id) => {});
}

Then we’ll declare our base URL with our dynamic image ID, as well as a name for the alt text later.

{
	imageIds.map((id) => {
		let url = `https://stevedsimkins.mypinata.cloud/ipfs/QmTwDNr6LyRzW8H3XorFDArfKEH3GRV1SkF6bAEBF3P4GJ/${id}.jpg?img-width=1080&img-height=1080`;
		let name = `nft ${id}`;
	});
}

Finally, we just need to create a component to hold the image, using the url as the image src and the name as the image alt!

{
	imageIds.map((id) => {
		let url = `https://stevedsimkins.mypinata.cloud/ipfs/QmTwDNr6LyRzW8H3XorFDArfKEH3GRV1SkF6bAEBF3P4GJ/${id}.jpg?img-width=1080&img-height=1080`;
		let name = `nft ${id}`;
		return (
			<div className="image-container">
				<img src={url} alt={name} />
			</div>
		);
	});
}

That leaves us with the final code for App.js. Add in a little CSS and we end up with a nice little image grid that loads FAST!

import "./App.css";

function App() {
	let imageIds = [];

	for (let id = 1; id <= 8; id++) {
		imageIds.push(id);
	}

	return (
		<div className="App">
			<div className="grid">
				{imageIds.map((id) => {
					let url = `https://stevedsimkins.mypinata.cloud/ipfs/QmTwDNr6LyRzW8H3XorFDArfKEH3GRV1SkF6bAEBF3P4GJ/${id}.jpg?img-width=1080&img-height=1080`;
					let name = `nft ${id}`;

					return (
						<div className="image-container">
							<img src={url} alt={name} />
						</div>
					);
				})}
			</div>
		</div>
	);
}

export default App;

gif of loading

Keep in mind, each one of these images is 10,000 x 10,000 resolution with over 35MB per file, and thanks to our dedicated gateway we loaded them like it was nothing. All of them dynamically resized to 1080 x 1080, still a decent size and high enough quality for most projects.

Now you’ve got an idea how IPFS Image Optimization with Pinata’s Dedicated Gateways can help streamline your NFT development, especially for marketplaces and other platforms that need to stream lots of IPFS content. Here are a few more articles that might be helpful as you’re building:

How To Create an NFT Marketplace on Flow With IPFS

How To Prevent NFT Trait Sniping In Your PFP Project

How to Offset Your NFT Project Carbon Emissions with Aerial

And if you haven’t heard, we’ve just released a ton of new features like token gating content and 4k video streaming, putting even more power into the hands of creators. Be sure to join our Discord community to connect with other creators and see all the amazing projects being built with Pinata. Happy pinning!