- Notifications
You must be signed in to change notification settings - Fork5
Decode and encode png files in browsers/Node.js
License
lunapaint/png-codec
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
This is a PNG decoder and encoder library for JavaScript that runs in both the browser and in Node.js. It is used inLuna Paint (an image editor for VS Code) to work with PNG files.
You can try it out onvscode.dev
by installing the Luna Paint extension and opening a png file.
- Performance: Just like Luna Paint, performance is a priority. This includes code splitting such that code that parses optional chunks are only loaded as needed.
- Correctness: The library has > 97% code coverage via over 7500 tests, including full coverage ofPngSuite—the "official" test suite for PNG.
- Simple API: The API is a well documentedTypeScript declaration file.
- Metadata: All supported metadata is exposed on the API such as text, gamma, default background color, etc.
- Readable Codebase: A big part of this was a learning exercise for me so I put some effort in to make the code as readable as possible to help others on the same journey.
- Error tolerant: Images will still load with warnings unless a critical error is hit.
The supported way of installing the project is through npm:
npm install @lunapaint/png-codec
Alternatively, you could add the repo as a git submodule, or download the source from the GitHubreleases page.
Basic usage:
import{decodePng,encodePng}from'@lunapaint/png-codec';import*asfsfrom'fs/promises';asyncfunctiondecode(filepath){constdata=awaitfs.readFile(filepath);constdecoded=awaitdecodePng(data);console.log('decoded image',decoded.image.data);// [r, g, b, a, ...]}asyncfunctionencode(data,width,height,filepath){constencoded=awaitencodePng({ data, width, height});awaitfs.writeFile(filepath,encoded.data);console.log('encoded image',encoded.data);// [...binary data]}
The full API is documented as a TypeScript.d.ts
declaration file. The view the API:
- github.dev: View on the web in VS Code, which has symbol support out of the box. Try showing the Outline view and triggering the
Go to Symbol in Editor
command - github.com: View the raw file in github.com.
PNGs are made up of a fixed signature followed by a series of chunks. The following chunks can be decoded supported, with some notes provided where applicable:
Critical chunks:
Chunk | Name | Notes |
---|---|---|
IHDR | Image header | |
PLTE | Palette | |
IDAT | Image data | Full filtering and interlacing support for all bit depths (1, 2, 4, 8, 16) are supported. |
IEND | Image trailer |
Ancillary chunks:
Chunk | Name | Notes |
---|---|---|
bKGD | Background color | |
cHRM | Primary chromaticities and white point | |
eXIf | Exchangeable image file format | Approved 2017/7 |
gAMA | Image gamma | Gamma values are provided, but are not applied to the resulting image (see#11) |
hIST | Image histogram | |
iCCP | Embedded ICC profile | Exposes the profile as a byte array |
iTXt | International textual data | |
oFFs | Image offset | 🧪 Limited testing Extension to the PNG 1.2 Specification v1.2.0 |
pCAL | Calibration of pixel values | 🧪 Limited testing Extension to the PNG 1.2 Specification v1.2.0 |
pHYs | Physical pixel dimensions | |
sBIT | Significant bits | Since the decoded buffer uses a minimum of uint8, this is only when the significant bits are in the range of 9-15 |
sCAL | Physical scale of image subject | 🧪 Limited testing Extension to the PNG 1.2 Specification v1.2.0 |
sPLT | Suggested palette | |
sRGB | Standard RGB colour space | |
sTER | Indicator of stereo image | 🧪 Limited testing Extension to the PNG 1.2 Specification v1.3.0 |
tEXt | Textual data | |
tIME | Image last-modification time | |
tRNS | Transparency | Since this chunk modifies the resulting image, you cannot skip this chunk |
zTXt | Compressed textual data |
These are the main reasons:
- To deeply understand the format.
- To integrate better with Luna Paint and my other existing and future decoders that depend on the png format.
- The scope is limited, this project will eventually be "done" and need minimal maintenance.
- I didn't want to go the wasm route in Luna Paint (yet?).
- To have full control over how the code is loaded, for example Luna Paint uses dynamic imports extensively to reduce the amount of code loaded to combat slow startup times.
- As an educational resource.
- To have some fun.
The library has the single runtime dependencypako which provides the compression/decompression capabilities needed to read various png chunks.
About
Decode and encode png files in browsers/Node.js
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Uh oh!
There was an error while loading.Please reload this page.
Contributors3
Uh oh!
There was an error while loading.Please reload this page.