All Projects → gdnmobilelab → Png Pong

gdnmobilelab / Png Pong

An image manipulation library with a very specific set of skills.

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to Png Pong

Pwafire
Progressive Web Apps API of APIs
Stars: ✭ 137 (-27.89%)
Mutual labels:  service-worker
Deblurgan
Image Deblurring using Generative Adversarial Networks
Stars: ✭ 2,033 (+970%)
Mutual labels:  image-manipulation
Distancegan
Pytorch implementation of "One-Sided Unsupervised Domain Mapping" NIPS 2017
Stars: ✭ 180 (-5.26%)
Mutual labels:  image-manipulation
Focal Frequency Loss
Focal Frequency Loss for Generative Models
Stars: ✭ 141 (-25.79%)
Mutual labels:  image-manipulation
Wallgen
Generate HQ poly wallpapers
Stars: ✭ 153 (-19.47%)
Mutual labels:  image-manipulation
Learning Pwa
📱some samples and blogs about how to start with your first PWA
Stars: ✭ 162 (-14.74%)
Mutual labels:  service-worker
Gesturegan
[ACM MM 2018 Oral] GestureGAN for Hand Gesture-to-Gesture Translation in the Wild
Stars: ✭ 136 (-28.42%)
Mutual labels:  image-manipulation
Awesome Cloudflare
⛅️ Curated list of awesome Cloudflare worker recipes, open-source projects, guides, blogs and other resources.
Stars: ✭ 186 (-2.11%)
Mutual labels:  service-worker
Deep Smile Warp
DeepWarp for Facial Expression Manipulation
Stars: ✭ 153 (-19.47%)
Mutual labels:  image-manipulation
Pwatter
Angular Progressive Web App using Workbox
Stars: ✭ 167 (-12.11%)
Mutual labels:  service-worker
Tsit
[ECCV 2020 Spotlight] A Simple and Versatile Framework for Image-to-Image Translation
Stars: ✭ 141 (-25.79%)
Mutual labels:  image-manipulation
Genegan
GeneGAN: Learning Object Transfiguration and Attribute Subspace from Unpaired Data
Stars: ✭ 142 (-25.26%)
Mutual labels:  image-manipulation
Notes
Offline-first notepad PWA
Stars: ✭ 163 (-14.21%)
Mutual labels:  service-worker
Generator Jekyll Starter Kit
🚀 Jekyll Progressive Web App Generator.
Stars: ✭ 139 (-26.84%)
Mutual labels:  service-worker
Fetch Progress Indicators
Progress indicators/bars using Streams, Service Workers, and Fetch APIs
Stars: ✭ 181 (-4.74%)
Mutual labels:  service-worker
Avir
High-quality pro image resizing / scaling C++ library, image resize
Stars: ✭ 135 (-28.95%)
Mutual labels:  image-manipulation
Php Legofy
Transform your images as if they were made out of LEGO bricks.
Stars: ✭ 161 (-15.26%)
Mutual labels:  image-manipulation
Pycloudinary
Python package for cloudinary
Stars: ✭ 189 (-0.53%)
Mutual labels:  image-manipulation
Deep white balance
Reference code for the paper: Deep White-Balance Editing, CVPR 2020 (Oral). Our method is a deep learning multi-task framework for white-balance editing.
Stars: ✭ 184 (-3.16%)
Mutual labels:  image-manipulation
Nohost
A web server in your web browser
Stars: ✭ 164 (-13.68%)
Mutual labels:  service-worker

PngPong

An image manipulation library with a very specific set of skills. Take a look at a writeup of how we used it.

What is it?

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).

This leads to a lot of restrictions. Although PngPong does use PNG files, it requires that they be a very specific kind of PNG file:

  • Indexed-color type (type 3) with an optional tRNS chunk for alpha transparency
  • Compressed at ZLib compression level 0 (i.e. not actually compressed at all)

To ensure your users don't incur a massive bandwidth cost, I recommend GZipping any PNG assets you pre-create for use with PngPong - although it normally doesn't make a difference with PNGs, it will compress the final file size considerably.

Why these restrictions?

  • Indexed-color: to try to reign in the amount of memory PngPong uses. Right now it has to load the entire image into memory in order to edit it, and the data for Truecolor with Alpha (type 6) images take up nearly 4x as much space.
  • Compression level 0:
    • Because the JS to decompress ZLib is not insigificant.
    • The file has to be uncompressed anyway to edit raw data, and that will mean even more memory usage (compressed file + uncompressed data)
    • Browsers can handle uncompression of anything that we GZip without needing any extra client code, so the bandwidth requirement does not increase.

How do I use it?

You can create a base PNG file using one of two methods, createFromRGBAArray or createWithMetadata. Both methods are available from the package directly:

import { createFromRGBAArray, createWithMetadata } from 'png-pong';

Tip: to convert an existing PNG image into one PngPong can process client-side, use a library like PNGJS to get the RGBA array, then run createfromRGBAArray.

Once you have your source image ArrayBuffer, create a new instance of PngPong with it:

import { PngPong } from 'png-pong';
const pngPong = new PngPong(imageArrayBuffer);

PngPong currently has two transformers available:

ShapeTransformer

The shape transformer allows you to draw rectangles onto an image. Like so:

import { PngPongShapeTransformer } from 'png-pong';

const shape = new PngPongShapeTransformer(pngPong);

// draw a 30px red square 10px from the top and 10px from the left
shape.drawRect(10, 10, 30, 30, [255, 0, 0])

ImageCopyTransformer

The image copy transformer allows you take portions of one image, and draw them onto another. Like so:

import { PngPongImageCopyTransformer } from './src';

const toCopyFrom = new ArrayBuffer();

const imageCopy = new PngPongImageCopyTransformer(toCopyFrom, pngPong);

// copy a 50x50 image 10px from the top left of the source image,
// and draw it 30px into our target image. 
imageCopy.copy(10, 10, 50, 50, 30, 30);

The ImageCopyTransformer also has a color mask option to allow you to recolour the source image.

Running the transforms

Once you have your transforms set, just run:

pngPong.run();

and the source ArrayBuffer will be modified.

Making your own transformer

An instance of PngPong has a series of hooks available to transformers - onHeader, onPalette and onData.

An example of a custom transformer that draws a blue line across an image at 10px high, 10px from both the left and right edges of the image.

const pngPong = new PngPong(arrayBuffer);

let lineStartX, lineEndX;
let paletteIndex;

pngPong.onHeader((header) => {
    lineStartX = 10;
    lineEndX = header.width - 10;
})

pngPong.onPalette((palette) => {
    paletteIndex = palette.addColor([0, 0, 255]);
})

pngPong.onData((array, readOffset, x, y, length) => {
    if (y != 10) return;
    for (let i = Math.max(lineStartX, x); i < Math.min(lineEndX, length); i++) {
        array[readOffset + i] = paletteIndex;
    }
})

Important: the data callback specifies an offset and a length. Do not edit the data beyond that length, as you will overwrite block headers or something else that will result in an invalid PNG file.

Also, while the data callback will usually start with an X of zero, it won't always. So be sure you are calculating the correct start position.

Running tests/demos

To spin up a server showing you the demo page at demo/demo.ts just run:

npm run demo

And go to http://localhost:8080. To run the test suite in Node, run

npm run tests-node

, and in the browser:

npm run tests-web

And go to http://localhost:8080 again.

What's next

Loading the ArrayBuffer of an entire image is still very memory intensive. I'm working on a version that uses ReadableStreams (currently available in Chrome) to reduce the amount of memory being used at once.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].