PngPong Image Manipulation Library

For the recent UK Elections the folks The Guardian wanted to show big images along with their push notifications. Being bandwidth-aware they wanted a solution in which they could use a template image (which could then be cached) and then draw some stuff onto it. Only problem: Service Workers don’t have access to the Canvas API.

Enter PngPong, an basic image manipulation library, they’ve created:

PngPong is a very, very basic replacement for the Canvas API in environments that do not support it – primarily, service workers. Instead, it manually manipulates the bytes of a PNG file to copy the contents of another image, or draw basic shapes (currently only rectangles).

Their code to handle push notifications looked something like this:

self.addEventListener('push', (e) => {
    e.waitUntil(
        caches.match('/notification_template.png')
        .then((res) => res.arrayBuffer())
        .then((arrayBuffer) => {
            addResultsToTemplate(arrayBuffer, e.data);
            return blobToDataURL(new Blob([arrayBuffer]))
        })
        .then((imageURL) => {
            return self.registration.showNotification("Title", {
                image: imageURL
            })
        })
    )
})

Inside addResultsToTemplate they heavy lifting would be done by PngPong, drawing some small rectangles onto the template pictured below, yielding a push notification as pictured at the top of this post.


The template used

Example PngPong usage:

import {
  PngPong,
  PngPongShapeTransformer,
  PngPongImageCopyTransformer
} from 'png-pong';

// Create new PngPong instance
const pngPong = new PngPong(imageArrayBuffer);

// Draw a 30px red square 10px from the top and 10px from the left
const shape = new PngPongShapeTransformer(pngPong);
shape.drawRect(10, 10, 30, 30, [255, 0, 0])

// Copy a 50x50 image 10px from the top left of the source image,
// and draw it 30px into our target image. 
const toCopyFrom = new ArrayBuffer();
const imageCopy = new PngPongImageCopyTransformer(toCopyFrom, pngPong);
imageCopy.copy(10, 10, 50, 50, 30, 30);

// Run the transforms
pngPong.run();

PngPong (GitHub) →
PngPong Use Case: Generating Images in JavaScript Without Using the Canvas API →

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.