Generative JPEGs. Fully on-chain.

This project began with the question: what is a JPEG?

With a sufficiently deep understanding of the JPEG format, would it be possible to build an image wholly from binary?

Rather than translating an image into the JPEG format as a thoughtless final step in the creative process, could I learn to write JPEG natively?

128 total tokens in the collection

View another seed
ofoid PURE JPEG collection

Phase 1
Deep Dive

My initial investigation was focused on the ITU T.81 specification, which is the primary document outlining the JPEG format. The spec was helpful for getting a handle on the inner workings of the format, but I found it difficult to move from the paper to a functional implementation.

ITU T.81 specification docs

Example pages from ITU T.81 specification guidelines

Eventually I stumbled across an incredible video series by Daniel Harding. Many of my unanswered questions surrounding practical implementation were answered after watching (and re-watching!) the series.

A screenshot from “Everything You Need to Know About JPEG” by Daniel Harding

A screenshot from “Everything You Need to Know About JPEG” by Daniel Harding


Phase 2
Dirty Hands

My first prototype of the concept was a simple app running in the browser. The code would produce the JPEG binary, encode it to base64 and display it. A lot of reading and experimentation was required to eventually produce my first generative JPEG:

First prototype

With that complete, I started to further refine the output. I played with every major building block of JPEG: Huffman encodings, chroma subsampling, and quantization. The browser gave me the perfect iterative environment: simple changes to my code would immediately reload the image to determine if I had achieved the desired effect. I discovered myriad ways of producing corrupt JPEGs before eventually gaining adequate understanding.

Desired effect

Once I was able to reliably generate JPEG images from the ground up, I began to explore ideas around compressibility: What sort of image does the JPEG format excel at representing? By focusing on producing images that were naturally expressible in the JPEG format, I was able to produce high resolution images that occupied a remarkably small number of bytes.

After much experimentation, I arrived at a pattern-based method of image composition. Generating repeated blocks of varying lengths yielded visually interesting results, with the critical benefit of being trivial to copy to an output buffer. This approach allowed me to generate large, impactful images while keeping gas usage to a minimum.

Those patterns were then assembled into larger tiles and juxtaposed with other patterns to create images that felt organic and unpredictable, while also being native to the process of JPEG encoding.

Showcase of 4 early explorations

An early exploration of pattern compositions

Color gradient test pattern

A test of the pattern tiles & color gradient coming together to create a composition

Once a reference implementation was complete, the process of reimplementing the code in Solidity could begin.


Phase 3
Going on-chain

The generative, on-chain nature of the contract was not part of the initial project concept. My intent had been to explore the construction of a JPEG directly in code, and then use those tools to produce a small set of static images. However, as I gained more facility with JPEG generation the possibility of a generative, on-chain contract began to feel tantalizingly close.

As I began the task of reimplementing the logic in Solidity, I quickly encountered a litany of roadblocks. Stack level too deep. Gas limit reached. Eventually I had to learn Ethereum’s low-level assembly language Yul and rewrite large segments of the code to ensure I stayed within Ethereum’s computational limits.

Q: Is the NFT metadata on-chain?

A: Yes – the NFT metadata is produced directly by the contract.

Q: Is the JPEG on-chain?

Yes – the JPEG is constructed generatively via the EVM. It is recreated in its entirety upon every request to the contract. The token ID is the seed for a pseudorandom process that defines every aspect of the final image: the image patterns, the color gradient, and so on.

Storing every byte of each JPEG on-chain is unnecessary. Instead, the method to produce the image is stored on-chain, and the token ID is the only piece necessary to reconstruct it.

From another perspective, a compressed version of the image is stored on-chain and the act of requesting the token URI decompresses it for display.

Q: Are the JPEGs lossy?

No – they are lossless. The concept of lossy compression presumes the existence of an original image that has been encoded into the JPEG format, and asks how much detail has been lost when the original is compared to the compressed version.

In this case, however, the images are defined within the JPEG format itself. They are by definition lossless as they themselves are the “original image”.

Q: Can the image change after metadata refresh?

Highlights from the collection


PURE JPEG is an expression of the process and personal achievements described above.

A limited set of 128 tokens are available for minting to celebrate the conclusion of this journey and to give body to the collection.

My hope is that this work culminates in something more than personal satisfaction – that it is another milestone marking what is possible with generative, on-chain technology as a means to create interesting visual art.

Hopefully it provides inspiration to others who seek to push the boundaries of their own capacities and creations.

View collection