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.
Primer
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 json
, then 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
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
The _
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!
Future Development
There are several different possible ways forward for the project :
-
Right now,
basquiat
takes 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
basquiat
would allow for this extensibility to be reflected in the implementation. -
Integration within Fission CLI.
-
Browser-ready implementation using the pica library and js-ipfs.
Please don’t hesitate to request features by opening an issue on the basquiat
repo!.