Basquiat, an IPFS-ready image resizing tool
Modern website designs have to be optimized for a wide range of devices. In order to minimize page load speed without sacrificing display quality, the size of the image is tailored to the device’s characteristics. In the centralized web, this is achieved on the server side by very fast image processing libraries such as libvips, the backbone of the popular imgproxy service.
How can we translate this functionality into the world of IPFS? In this article, I will give you a quick tour of basquiat, a new project which proposes a metadata spec and a simple implementation as first explorations of possible solutions to this emerging problem.
IPFS stores all data as a directed acyclic graph (DAG), which is essentially a tree in which a given node may have more than one parent. This tree structure is used to enable the partition of files into smaller and more manageable chunks. A node is pointed to through its content identifier (CID), a string of characters derived from the hash of its contents. This means that any CID references a static object. Each node is then a JSON-like dictionary possibly containing a
data attribute which stores raw data, as well as the CIDs of other nodes containing the rest of the data.
This JSON-like data structure is defined in detail by IPLD, which is a continuously evolving specification. At first JSON-like meant
protobuf, and finally
cbor. However, thanks to the IPLD spec, this difference in implementation can be abstracted away as we build our own spec on top of this data structure layer.
From very early on, IPFS has made use of an actual filesystem called UnixFS. Directories are implemented by adding named links to other resources within the node. For example, a
cat.jpg file within a directory
cid0 could be reached by the
cid0/cat.jpg URI in addition to its own CID.
basquiat is a CLI tool implemented in Rust and built on top of
go-ipfs and the
libvips library. As input, it takes a path to an image as well as a configuration file which describes the targeted image sizes. Then,
basquiat outputs a CID which points to the original image but contains named links to the generated versions.
$ basquiat -q ~/Pictures/yaks.jpg -c basquiat.cfg QmfPYe4JzhcG41bXNnGUfCDZMLJ74KdQtZzniSz56t6i4F
QmfPYe4JzhcG41bXNnGUfCDZMLJ74KdQtZzniSz56t6i4F is an example output of
basquiat. Directly opening this CID yields the original image. It is possible to explore the different generated versions by appending thumbnails.html to the CID.
For example, the given configuration generates a
601x400 version which can be reached in three ways :
QmfPYe4JzhcG41bXNnGUfCDZMLJ74KdQtZzniSz56t6i4F/601x400.jpg QmfPYe4JzhcG41bXNnGUfCDZMLJ74KdQtZzniSz56t6i4F/601x_.jpg QmfPYe4JzhcG41bXNnGUfCDZMLJ74KdQtZzniSz56t6i4F/_x400.jpg
_ wildcard character means that applications don’t have to know the dimensions or aspect ratio of the original image in order to request a particular size. Indeed,
basquiat is more than a CLI tool, it also proposes a flexible and extensible link naming schema in order to ensure eventual compatibility across different implementations.
basquiat's configuration parser is also an implementation of this specification.
For a quick start with
basquiat, please check out the README!
There are several different possible ways forward for the project :
basquiattakes a static configuration file that enumerates every required version. An important step in order to make it more usable would be to ease generation of configuration files from target device characteristics as well as relative image display size.
The metadata specification is extensible to different operations such as cropping. Implementing a plugin system for
basquiatwould allow for this extensibility to be reflected in the implementation.
Integration within Fission CLI.
Please don’t hesitate to request features by opening an issue on the