# ndarray-pixels [![Latest NPM release](https://img.shields.io/npm/v/ndarray-pixels.svg)](https://www.npmjs.com/package/ndarray-pixels) [![License](https://img.shields.io/badge/license-MIT-007ec6.svg)](https://github.com/donmccurdy/ndarray-pixels/blob/main/LICENSE) [![npm bundle size](https://img.shields.io/bundlephobia/minzip/ndarray-pixels)](https://bundlephobia.com/package/ndarray-pixels) [![CI](https://github.com/donmccurdy/ndarray-pixels/workflows/CI/badge.svg?branch=main&event=push)](https://github.com/donmccurdy/ndarray-pixels/actions?query=workflow%3ACI) Convert [ndarray](https://www.npmjs.com/package/ndarray) ↔ image data, on Web and Node.js. Designed to be used with [other ndarray-based packages](http://scijs.net/packages/). ## Supported Formats | Platform | JPEG | PNG | Other | |----------|------|-----|-------------------------------------------------------------------------------------------------------| | Node.js | ✅ | ✅ | Based on [sharp support](https://sharp.pixelplumbing.com/) | | Web | ✅ | ✅ | Based on [browser support](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob) | ### Known Bugs - [ ] Web implementation (Canvas 2D) premultiplies alpha. ## Quickstart ``` npm install --save ndarray-pixels ``` ### Web ```javascript import { getPixels, savePixels } from 'ndarray-pixels'; const bytesIn = await fetch('./input.png') .then((res) => res.arrayBuffer()) .then((arrayBuffer) => new Uint8Array(arrayBuffer)); // read const pixels = await getPixels(bytesIn, 'image/png'); // Uint8Array -> ndarray // modify const [width, height] = pixels.shape; for (let x = 0; x < width; ++x) { for (let y = 0; y < height; ++y) { pixels.set(x, y, 0, 255); // R pixels.set(x, y, 1, 0.0); // G pixels.set(x, y, 2, 0.0); // B pixels.set(x, y, 3, 255); // A } } // write const bytesOut = await savePixels(pixels, 'image/png'); // ndarray -> Uint8Array ``` ### Node.js ```javascript const fs = require('fs'); const { getPixels, savePixels } = require('ndarray-pixels'); const bufferIn = fs.readFileSync('./input.png'); // read const pixels = await getPixels(bufferIn, 'image/png'); // Uint8Array -> ndarray // modify const [width, height] = pixels.shape; for (let x = 0; x < width; ++x) { for (let y = 0; y < height; ++y) { pixels.set(x, y, 0, 255); // R pixels.set(x, y, 1, 0.0); // G pixels.set(x, y, 2, 0.0); // B pixels.set(x, y, 3, 255); // A } } // write const bufferOut = await savePixels(pixels, 'image/png'); // ndarray -> Uint8Array fs.writeFileSync('./output.png', bufferOut); ``` ## API ### Function: getPixels() > **getPixels**(`data`, `mimeType`): `Promise`\<`NdArray`\<`Uint8Array`\<`ArrayBufferLike`\>\>\> Defined in: [index.ts:17](https://github.com/donmccurdy/ndarray-pixels/blob/87aeb33fe959d1beb607fa057f581202c2f2f10a/src/index.ts#L17) Decodes image data to an `ndarray`. MIME type is optional when given a path or URL, and required when given a Uint8Array. Accepts `image/png` or `image/jpeg` in Node.js, and additional formats on browsers with the necessary support in Canvas 2D. #### Parameters ##### data `Uint8Array` ##### mimeType `string` `image/jpeg`, `image/png`, etc. #### Returns `Promise`\<`NdArray`\<`Uint8Array`\<`ArrayBufferLike`\>\>\> ### Function: savePixels() > **savePixels**(`pixels`, `typeOrOptions`): `Promise`\<`Uint8Array`\<`ArrayBufferLike`\>\> Defined in: [index.ts:37](https://github.com/donmccurdy/ndarray-pixels/blob/87aeb33fe959d1beb607fa057f581202c2f2f10a/src/index.ts#L37) Encodes an `ndarray` as image data in the given format. If the source `ndarray` was constructed manually with default stride, use `ndarray.transpose(1, 0)` to reshape it and ensure an identical result from getPixels(). For an ndarray created by getPixels(), this isn't necessary. Accepts `image/png` or `image/jpeg` in Node.js, and additional formats on browsers with the necessary support in Canvas 2D. #### Parameters ##### pixels `NdArray`\<`Uint8Array`\<`ArrayBufferLike`\> \| `Uint8ClampedArray`\<`ArrayBufferLike`\>\> ndarray of shape W x H x 4. ##### typeOrOptions object with encoding options or just the type `string` | \{ `quality?`: `number`; `type?`: `string`; \} object with encoding options or just the type ###### quality? `number` quality as a number from 0 to 1, inclusive ###### type? `string` target format (`image/jpeg`, `image/png`, `image/webp`, etc.) #### Returns `Promise`\<`Uint8Array`\<`ArrayBufferLike`\>\>