Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

ndarray-pixels

Package Overview
Dependencies
Maintainers
1
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ndarray-pixels - npm Package Compare versions

Comparing version 2.0.1 to 2.0.2

dist/common.d.ts

5

dist/browser-get-pixels.d.ts
import type { NdArray } from 'ndarray';
export type GetPixelsCallback = (err: string | Event | null, pixels?: NdArray) => void;
export default getPixels;
declare function getPixels(path: string, callback: GetPixelsCallback): void;
declare function getPixels(path: string | Uint8Array, type: string, callback: GetPixelsCallback): void;
export declare function getPixelsInternal(buffer: Uint8Array, mimeType: string): Promise<NdArray<Uint8Array>>;

14

dist/browser-save-pixels.d.ts
import type { NdArray } from 'ndarray';
export interface SavePixelsOptions {
export interface EncoderOptions {
quality?: number;
}
export default savePixels;
declare function savePixels(array: NdArray, type: 'canvas'): HTMLCanvasElement;
declare function savePixels(array: NdArray, type: 'png'): Readable;
declare function savePixels(array: NdArray, type: 'jpeg' | 'jpg', options?: SavePixelsOptions): Readable;
declare class Readable {
private _promise;
constructor(_promise: Promise<Uint8Array>);
on(event: 'data' | 'error' | 'end', fn: (res?: Uint8Array | Error) => void): this;
static from(promise: Promise<Uint8Array>): Readable;
}
export declare function savePixelsInternal(pixels: NdArray<Uint8Array | Uint8ClampedArray>, mimeType: string): Promise<Uint8Array>;
export declare function savePixelsInternal(pixels: NdArray<Uint8Array | Uint8ClampedArray>, mimeType: string, options?: EncoderOptions): Promise<Uint8Array>;

@@ -14,3 +14,3 @@ import type { NdArray } from 'ndarray';

*/
declare function getPixels(data: string | Uint8Array, mimeType?: string): Promise<NdArray>;
declare function getPixels(data: Uint8Array, mimeType: string): Promise<NdArray<Uint8Array>>;
/**

@@ -30,3 +30,3 @@ * Encodes an `ndarray` as image data in the given format.

*/
declare function savePixels(pixels: NdArray, mimeType: string): Promise<Uint8Array>;
declare function savePixels(pixels: NdArray<Uint8Array | Uint8ClampedArray>, mimeType: string): Promise<Uint8Array>;
export { getPixels, savePixels };

@@ -1,2 +0,134 @@

import e from"ndarray";import t from"ndarray-ops";function a(e,t,a={}){const i=document.createElement("canvas");i.width=e.shape[0],i.height=e.shape[1];const o=i.getContext("2d"),h=o.getImageData(0,0,i.width,i.height);try{n(e,h.data)}catch(e){return s.from(Promise.reject(e))}o.putImageData(h,0,0);const p=a.quality?a.quality/100:void 0;switch(t){case"canvas":return i;case"jpg":case"jpeg":return r(i,"image/jpeg",p);case"png":return r(i,"image/png");default:throw new Error("[ndarray-pixels] Unsupported file type: "+t)}}function r(e,t,a){const r=new Promise((r,n)=>{e.toBlob(async e=>{e?r(new Uint8Array(await e.arrayBuffer())):n(new Error("[ndarray-pixels] Failed to canvas.toBlob()."))},t,a)});return s.from(r)}function n(a,r,s=-1){if(4===a.shape.length)return n(a.pick(s),r,0);if(3===a.shape.length)if(3===a.shape[2])t.assign(e(r,[a.shape[0],a.shape[1],3],[4,4*a.shape[0],1]),a),t.assigns(e(r,[a.shape[0]*a.shape[1]],[4],3),255);else if(4===a.shape[2])t.assign(e(r,[a.shape[0],a.shape[1],4],[4,4*a.shape[0],1]),a);else{if(1!==a.shape[2])throw new Error("[ndarray-pixels] Incompatible array shape.");t.assign(e(r,[a.shape[0],a.shape[1],3],[4,4*a.shape[0],1]),e(a.data,[a.shape[0],a.shape[1],3],[a.stride[0],a.stride[1],0],a.offset)),t.assigns(e(r,[a.shape[0]*a.shape[1]],[4],3),255)}else{if(2!==a.shape.length)throw new Error("[ndarray-pixels] Incompatible array shape.");t.assign(e(r,[a.shape[0],a.shape[1],3],[4,4*a.shape[0],1]),e(a.data,[a.shape[0],a.shape[1],3],[a.stride[0],a.stride[1],0],a.offset)),t.assigns(e(r,[a.shape[0]*a.shape[1]],[4],3),255)}return r}class s{constructor(e){this._promise=void 0,this._promise=e}on(e,t){return"data"===e?this._promise.then(t):"error"===e?this._promise.catch(t):"end"===e&&this._promise.finally(t),this}static from(e){return new s(e)}}async function i(t,a){return t instanceof Uint8Array&&"undefined"!=typeof Buffer&&(t=Buffer.from(t)),new Promise((r,n)=>{!function(t,a,r){if(r=r||a,t instanceof Uint8Array){if("string"!=typeof a)throw new Error("[ndarray-pixels] Type must be given for Uint8Array image data");const e=new Blob([t],{type:a});t=URL.createObjectURL(e)}const n=new Image;n.crossOrigin="anonymous",n.onload=function(){URL.revokeObjectURL(t);const a=document.createElement("canvas");a.width=n.width,a.height=n.height;const s=a.getContext("2d");s.drawImage(n,0,0);const i=s.getImageData(0,0,n.width,n.height);r(null,e(new Uint8Array(i.data),[n.width,n.height,4],[4,4*n.width,1],0))},n.onerror=e=>{URL.revokeObjectURL(t),r(e)},n.src=t}(t,a,(e,t)=>{t&&!e?r(t):n(e)})})}async function o(e,t){return new Promise((r,n)=>{const s=[],i=t.replace("image/","");a(e,i).on("data",e=>s.push(e)).on("end",()=>r(function(e){let t=0;for(const a of e)t+=a.byteLength;const a=new Uint8Array(t);let r=0;for(const t of e)a.set(t,r),r+=t.byteLength;return a}(s))).on("error",e=>n(e))})}export{i as getPixels,o as savePixels};
import ndarray from 'ndarray';
import ops from 'ndarray-ops';
function getPixelsInternal(buffer, mimeType) {
// Warn for Data URIs, URLs, and file paths. Support removed in v3.
if (!(buffer instanceof Uint8Array)) {
throw new Error('[ndarray-pixels] Input must be Uint8Array or Buffer.');
}
const blob = new Blob([buffer], {
type: mimeType
});
const path = URL.createObjectURL(blob); // Decode image with Canvas API.
return new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = 'anonymous';
img.onload = function () {
URL.revokeObjectURL(path);
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const context = canvas.getContext('2d');
context.drawImage(img, 0, 0);
const pixels = context.getImageData(0, 0, img.width, img.height);
resolve(ndarray(new Uint8Array(pixels.data), [img.width, img.height, 4], [4, 4 * img.width, 1], 0));
};
img.onerror = err => {
URL.revokeObjectURL(path);
reject(err);
};
img.src = path;
});
}
function putPixelData(array, data, frame = -1) {
if (array.shape.length === 4) {
return putPixelData(array.pick(frame), data, 0);
} else if (array.shape.length === 3) {
if (array.shape[2] === 3) {
ops.assign(ndarray(data, [array.shape[0], array.shape[1], 3], [4, 4 * array.shape[0], 1]), array);
ops.assigns(ndarray(data, [array.shape[0] * array.shape[1]], [4], 3), 255);
} else if (array.shape[2] === 4) {
ops.assign(ndarray(data, [array.shape[0], array.shape[1], 4], [4, array.shape[0] * 4, 1]), array);
} else if (array.shape[2] === 1) {
ops.assign(ndarray(data, [array.shape[0], array.shape[1], 3], [4, 4 * array.shape[0], 1]), ndarray(array.data, [array.shape[0], array.shape[1], 3], [array.stride[0], array.stride[1], 0], array.offset));
ops.assigns(ndarray(data, [array.shape[0] * array.shape[1]], [4], 3), 255);
} else {
throw new Error('[ndarray-pixels] Incompatible array shape.');
}
} else if (array.shape.length === 2) {
ops.assign(ndarray(data, [array.shape[0], array.shape[1], 3], [4, 4 * array.shape[0], 1]), ndarray(array.data, [array.shape[0], array.shape[1], 3], [array.stride[0], array.stride[1], 0], array.offset));
ops.assigns(ndarray(data, [array.shape[0] * array.shape[1]], [4], 3), 255);
} else {
throw new Error('[ndarray-pixels] Incompatible array shape.');
}
return data;
}
async function savePixelsInternal(pixels, mimeType, options = {}) {
// Create HTMLCanvasElement and write pixel data.
const canvas = document.createElement('canvas');
canvas.width = pixels.shape[0];
canvas.height = pixels.shape[1];
const context = canvas.getContext('2d');
const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
putPixelData(pixels, imageData.data);
context.putImageData(imageData, 0, 0);
const quality = options.quality ? options.quality / 100 : undefined; // Encode to target format.
switch (mimeType) {
case 'image/jpeg':
return streamCanvas(canvas, 'image/jpeg', quality);
default:
return streamCanvas(canvas, mimeType);
}
}
/** Creates readable stream from given HTMLCanvasElement and options. */
function streamCanvas(canvas, mimeType, quality) {
return new Promise((resolve, reject) => {
canvas.toBlob(async blob => {
if (blob) {
resolve(new Uint8Array(await blob.arrayBuffer()));
} else {
reject(new Error('[ndarray-pixels] Failed to canvas.toBlob().'));
}
}, mimeType, quality);
});
}
/**
* 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.
*
* @param data
* @param mimeType `image/jpeg`, `image/png`, etc.
* @returns
*/
async function getPixels(data, mimeType) {
return getPixelsInternal(data, mimeType);
}
/**
* 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.
*
* @param pixels ndarray of shape W x H x 4.
* @param mimeType `image/jpeg`, `image/png`, etc.
* @returns
*/
async function savePixels(pixels, mimeType) {
return savePixelsInternal(pixels, mimeType);
}
export { getPixels, savePixels };
//# sourceMappingURL=ndarray-pixels-browser.modern.js.map

@@ -1,4 +0,58 @@

import getPixelsInternal from 'get-pixels';
import savePixelsInternal from 'save-pixels';
import ndarray from 'ndarray';
import sharp from 'sharp';
import ops from 'ndarray-ops';
async function getPixelsInternal(buffer, _mimeType) {
// Warn for Data URIs, URLs, and file paths. Support removed in v3.
if (!(buffer instanceof Uint8Array)) {
throw new Error('[ndarray-pixels] Input must be Uint8Array or Buffer.');
}
const {
data,
info
} = await sharp(buffer).ensureAlpha().raw().toBuffer({
resolveWithObject: true
});
return ndarray(new Uint8Array(data), [info.width, info.height, 4], [4, 4 * info.width | 0, 1], 0);
}
function putPixelData(array, data, frame = -1) {
if (array.shape.length === 4) {
return putPixelData(array.pick(frame), data, 0);
} else if (array.shape.length === 3) {
if (array.shape[2] === 3) {
ops.assign(ndarray(data, [array.shape[0], array.shape[1], 3], [4, 4 * array.shape[0], 1]), array);
ops.assigns(ndarray(data, [array.shape[0] * array.shape[1]], [4], 3), 255);
} else if (array.shape[2] === 4) {
ops.assign(ndarray(data, [array.shape[0], array.shape[1], 4], [4, array.shape[0] * 4, 1]), array);
} else if (array.shape[2] === 1) {
ops.assign(ndarray(data, [array.shape[0], array.shape[1], 3], [4, 4 * array.shape[0], 1]), ndarray(array.data, [array.shape[0], array.shape[1], 3], [array.stride[0], array.stride[1], 0], array.offset));
ops.assigns(ndarray(data, [array.shape[0] * array.shape[1]], [4], 3), 255);
} else {
throw new Error('[ndarray-pixels] Incompatible array shape.');
}
} else if (array.shape.length === 2) {
ops.assign(ndarray(data, [array.shape[0], array.shape[1], 3], [4, 4 * array.shape[0], 1]), ndarray(array.data, [array.shape[0], array.shape[1], 3], [array.stride[0], array.stride[1], 0], array.offset));
ops.assigns(ndarray(data, [array.shape[0] * array.shape[1]], [4], 3), 255);
} else {
throw new Error('[ndarray-pixels] Incompatible array shape.');
}
return data;
}
async function savePixelsInternal(pixels, mimeType) {
const [width, height, channels] = pixels.shape;
const data = putPixelData(pixels, new Uint8Array(width * height * channels));
const format = mimeType.replace('image/', '');
return sharp(data, {
raw: {
width,
height,
channels
}
}).toFormat(format).toBuffer();
}
/**

@@ -18,16 +72,3 @@ * Decodes image data to an `ndarray`.

async function getPixels(data, mimeType) {
// In Node.js, get-pixels needs a Buffer and won't accept Uint8Array.
if (data instanceof Uint8Array && typeof Buffer !== 'undefined') {
data = Buffer.from(data);
}
return new Promise((resolve, reject) => {
getPixelsInternal(data, mimeType, (err, pixels) => {
if (pixels && !err) {
resolve(pixels);
} else {
reject(err);
}
});
});
return getPixelsInternal(data);
}

@@ -51,28 +92,6 @@ /**

async function savePixels(pixels, mimeType) {
return new Promise((resolve, reject) => {
const chunks = [];
const internalType = mimeType.replace('image/', '');
savePixelsInternal(pixels, internalType).on('data', d => chunks.push(d)).on('end', () => resolve(concat(chunks))).on('error', e => reject(e));
});
return savePixelsInternal(pixels, mimeType);
}
function concat(arrays) {
let totalByteLength = 0;
for (const array of arrays) {
totalByteLength += array.byteLength;
}
const result = new Uint8Array(totalByteLength);
let byteOffset = 0;
for (const array of arrays) {
result.set(array, byteOffset);
byteOffset += array.byteLength;
}
return result;
}
export { getPixels, savePixels };
//# sourceMappingURL=ndarray-pixels-node.modern.js.map
{
"name": "ndarray-pixels",
"version": "2.0.1",
"description": "ndarray-pixels",
"type": "module",
"sideEffects": false,
"types": "./dist/index.d.ts",
"main": "./dist/ndarray-pixels-node.cjs",
"module": "./dist/ndarray-pixels-browser.modern.js",
"exports": {
"types": "./dist/index.d.ts",
"node": {
"require": "./dist/ndarray-pixels-node.cjs",
"default": "./dist/ndarray-pixels-node.modern.js"
},
"default": {
"require": "./dist/ndarray-pixels-browser.cjs",
"default": "./dist/ndarray-pixels-browser.modern.js"
}
},
"repository": "github:donmccurdy/ndarray-pixels",
"author": "Don McCurdy <dm@donmccurdy.com>",
"license": "MIT",
"scripts": {
"dist": "yarn dist:node && yarn dist:browser",
"dist:node": "microbundle build --raw --target node --format modern,cjs src/index.ts --output dist/ndarray-pixels-node.js",
"dist:browser": "microbundle build --raw --target web --format modern,cjs src/index.ts --output dist/ndarray-pixels-browser.js --alias get-pixels=./browser-get-pixels.ts,save-pixels=./browser-save-pixels.ts",
"clean": "rm -rf dist/*",
"test": "yarn test:node && yarn test:browser",
"test:node": "tape test/node.test.cjs | tap-spec",
"test:browser": "browserify test/browser.test.cjs | tape-run | tap-spec",
"docs": "typedoc src/index.ts --plugin typedoc-plugin-markdown --out ./docs --hideBreadcrumbs && cat docs/modules.md | tail -n +12 | replace-between --target README.md --token API && rm -rf docs",
"preversion": "yarn dist && yarn test",
"version": "yarn dist && yarn docs && git add -u",
"postversion": "git push && git push --tags && npm publish"
},
"dependencies": {
"@types/ndarray": "^1.0.10",
"get-pixels": "^3.3.3",
"ndarray": "^1.0.19",
"ndarray-ops": "^1.2.2",
"save-pixels": "^2.3.6"
},
"devDependencies": {
"@types/get-pixels": "3.3.2",
"@types/ndarray-ops": "1.2.4",
"@types/node": "18.14.0",
"@types/save-pixels": "2.3.2",
"@types/tape": "4.13.2",
"@typescript-eslint/eslint-plugin": "5.53.0",
"@typescript-eslint/parser": "5.53.0",
"browserify": "17.0.0",
"eslint": "8.34.0",
"microbundle": "0.15.1",
"regenerator-runtime": "0.13.11",
"replace-between": "0.0.8",
"source-map-support": "0.5.21",
"tap-spec": "5.0.0",
"tape": "5.6.3",
"tape-run": "10.0.0",
"typedoc": "0.23.25",
"typedoc-plugin-markdown": "3.14.0",
"typescript": "4.9.5"
},
"files": [
"dist/",
"src/",
"README.md",
"LICENSE",
"package.json"
]
"name": "ndarray-pixels",
"version": "2.0.2",
"description": "ndarray-pixels",
"type": "module",
"sideEffects": false,
"types": "./dist/index.d.ts",
"main": "./dist/ndarray-pixels-node.cjs",
"module": "./dist/ndarray-pixels-browser.modern.js",
"exports": {
"types": "./dist/index.d.ts",
"node": {
"require": "./dist/ndarray-pixels-node.cjs",
"default": "./dist/ndarray-pixels-node.modern.js"
},
"default": {
"require": "./dist/ndarray-pixels-browser.cjs",
"default": "./dist/ndarray-pixels-browser.modern.js"
}
},
"repository": "github:donmccurdy/ndarray-pixels",
"author": "Don McCurdy <dm@donmccurdy.com>",
"license": "MIT",
"scripts": {
"dist": "yarn dist:node && yarn dist:browser",
"dist:node": "microbundle build --raw --no-compress --target node --format modern,cjs src/index.ts --output dist/ndarray-pixels-node.js",
"dist:browser": "microbundle build --raw --no-compress --target web --format modern,cjs src/index.ts --output dist/ndarray-pixels-browser.js --alias ./node-get-pixels=./browser-get-pixels.ts,./node-save-pixels=./browser-save-pixels.ts",
"clean": "rm -rf dist/*",
"test": "yarn test:node && yarn test:browser",
"test:node": "tape test/node.test.cjs | tap-spec",
"test:browser": "browserify test/browser.test.cjs | tape-run | tap-spec",
"docs": "typedoc src/index.ts --plugin typedoc-plugin-markdown --out ./docs --hideBreadcrumbs && cat docs/modules.md | tail -n +12 | replace-between --target README.md --token API && rm -rf docs",
"preversion": "yarn dist && yarn test",
"version": "yarn dist && yarn docs && git add -u",
"postversion": "git push && git push --tags && npm publish"
},
"dependencies": {
"@types/ndarray": "^1.0.11",
"ndarray": "^1.0.19",
"ndarray-ops": "^1.2.2",
"sharp": "^0.32.1"
},
"devDependencies": {
"@types/ndarray-ops": "1.2.4",
"@types/node": "20.3.1",
"@types/sharp": "^0.32.0",
"@types/tape": "5.6.0",
"@typescript-eslint/eslint-plugin": "5.59.11",
"@typescript-eslint/parser": "5.59.11",
"browserify": "17.0.0",
"eslint": "8.42.0",
"microbundle": "0.15.1",
"regenerator-runtime": "0.13.11",
"replace-between": "0.0.8",
"source-map-support": "0.5.21",
"tap-spec": "5.0.0",
"tape": "5.6.3",
"tape-run": "10.0.0",
"typedoc": "0.24.8",
"typedoc-plugin-markdown": "3.15.3",
"typescript": "5.1.3"
},
"files": [
"dist/",
"src/",
"README.md",
"LICENSE",
"package.json"
]
}

@@ -12,10 +12,8 @@ # ndarray-pixels

In Node.js, this package uses [get-pixels](https://www.npmjs.com/package/get-pixels) and [save-pixels](https://www.npmjs.com/package/save-pixels). While both packages could be used on the web, they require polyfills for Node.js builtins. Browserify handles that automatically, but more modern bundlers do not. Moreover, the polyfills increase package size significantly. To avoid these problems, web builds of `ndarray-pixels` reimplement the same functionality with the more portable Canvas API.
## Supported Formats
| Platform | JPEG | PNG | Other |
|----------|------|-----|-------|
| Node.js | ✅ | ✅ | ❌ |
| Web | ✅ | ✅ | Based on [browser support](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob) |
| 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) |

@@ -85,3 +83,3 @@ ### Known Bugs

▸ **getPixels**(`data`, `mimeType?`): `Promise`<`NdArray`\>
▸ **getPixels**(`data`, `mimeType`): `Promise`<`NdArray`<`Uint8Array`\>\>

@@ -99,12 +97,12 @@ Decodes image data to an `ndarray`.

| :------ | :------ | :------ |
| `data` | `string` \| `Uint8Array` | |
| `mimeType?` | `string` | `image/jpeg`, `image/png`, etc. |
| `data` | `Uint8Array` | |
| `mimeType` | `string` | `image/jpeg`, `image/png`, etc. |
#### Returns
`Promise`<`NdArray`\>
`Promise`<`NdArray`<`Uint8Array`\>\>
#### Defined in
[index.ts:17](https://github.com/donmccurdy/ndarray-pixels/blob/6f5efcc/src/index.ts#L17)
[index.ts:17](https://github.com/donmccurdy/ndarray-pixels/blob/41a0530/src/index.ts#L17)

@@ -130,3 +128,3 @@ ___

| :------ | :------ | :------ |
| `pixels` | `NdArray`<`Data`<`number`\>\> | ndarray of shape W x H x 4. |
| `pixels` | `NdArray`<`Uint8Array` \| `Uint8ClampedArray`\> | ndarray of shape W x H x 4. |
| `mimeType` | `string` | `image/jpeg`, `image/png`, etc. |

@@ -140,3 +138,3 @@

[index.ts:48](https://github.com/donmccurdy/ndarray-pixels/blob/6f5efcc/src/index.ts#L48)
[index.ts:35](https://github.com/donmccurdy/ndarray-pixels/blob/41a0530/src/index.ts#L35)
<!--- API END --->
import ndarray from 'ndarray';
import type { NdArray } from 'ndarray';
export type GetPixelsCallback = (err: string | Event | null, pixels?: NdArray) => void;
export function getPixelsInternal(
buffer: Uint8Array,
mimeType: string
): Promise<NdArray<Uint8Array>> {
// Warn for Data URIs, URLs, and file paths. Support removed in v3.
if (!(buffer instanceof Uint8Array)) {
throw new Error('[ndarray-pixels] Input must be Uint8Array or Buffer.');
}
export default getPixels;
const blob = new Blob([buffer], { type: mimeType });
const path = URL.createObjectURL(blob);
function getPixels(path: string, callback: GetPixelsCallback): void;
function getPixels(path: string | Uint8Array, type: string, callback: GetPixelsCallback): void
function getPixels(path: string | Uint8Array, typeOrCallback: string | GetPixelsCallback, callback?: GetPixelsCallback): void {
callback = callback || typeOrCallback as GetPixelsCallback;
// Construct a Blob URL for Uint8Array inputs.
if (path instanceof Uint8Array) {
if (typeof typeOrCallback !== 'string') {
throw new Error('[ndarray-pixels] Type must be given for Uint8Array image data');
}
const blob = new Blob([path], {type: typeOrCallback});
path = URL.createObjectURL(blob);
}
// Decode image with Canvas API.
const img = new Image();
img.crossOrigin = 'anonymous';
img.onload = function() {
URL.revokeObjectURL(path as string);
return new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = 'anonymous';
img.onload = function () {
URL.revokeObjectURL(path as string);
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const context = canvas.getContext('2d')!;
context.drawImage(img, 0, 0);
const pixels = context.getImageData(0, 0, img.width, img.height)
callback!(null, ndarray(new Uint8Array(pixels.data), [img.width, img.height, 4], [4, 4*img.width, 1], 0));
}
img.onerror = (err) => {
URL.revokeObjectURL(path as string);
callback!(err);
};
img.src = path;
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const context = canvas.getContext('2d')!;
context.drawImage(img, 0, 0);
const pixels = context.getImageData(0, 0, img.width, img.height);
resolve(
ndarray(
new Uint8Array(pixels.data),
[img.width, img.height, 4],
[4, 4 * img.width, 1],
0
)
);
};
img.onerror = (err) => {
URL.revokeObjectURL(path as string);
reject(err);
};
img.src = path;
});
}

@@ -1,21 +0,26 @@

import ndarray from 'ndarray';
import type { NdArray } from 'ndarray';
import ops from 'ndarray-ops';
import { putPixelData } from './common';
export interface SavePixelsOptions {quality?: number}
export interface EncoderOptions {
quality?: number;
}
export default savePixels;
function savePixels(array: NdArray, type: 'canvas'): HTMLCanvasElement;
function savePixels(array: NdArray, type: 'png'): Readable;
function savePixels(array: NdArray, type: 'jpeg' | 'jpg', options?: SavePixelsOptions): Readable;
function savePixels(
array: NdArray, type: 'canvas' | 'png' | 'jpeg' | 'jpg',
options: SavePixelsOptions = {}
): Readable | HTMLCanvasElement {
export async function savePixelsInternal(
pixels: NdArray<Uint8Array | Uint8ClampedArray>,
mimeType: string
): Promise<Uint8Array>;
export async function savePixelsInternal(
pixels: NdArray<Uint8Array | Uint8ClampedArray>,
mimeType: string,
options?: EncoderOptions
): Promise<Uint8Array>;
export async function savePixelsInternal(
pixels: NdArray<Uint8Array | Uint8ClampedArray>,
mimeType: string,
options: EncoderOptions = {}
): Promise<Uint8Array> {
// Create HTMLCanvasElement and write pixel data.
const canvas = document.createElement('canvas');
canvas.width = array.shape[0];
canvas.height = array.shape[1];
canvas.width = pixels.shape[0];
canvas.height = pixels.shape[1];

@@ -25,9 +30,3 @@ const context = canvas.getContext('2d')!;

try {
handleData(array, imageData.data);
} catch (e) {
// Pass errors to stream, to match 'save-pixels' behavior.
return Readable.from(Promise.reject(e));
}
putPixelData(pixels, imageData.data);
context.putImageData(imageData, 0, 0);

@@ -38,12 +37,7 @@

// Encode to target format.
switch (type) {
case 'canvas':
return canvas;
case 'jpg':
case 'jpeg':
switch (mimeType) {
case 'image/jpeg':
return streamCanvas(canvas, 'image/jpeg', quality);
case 'png':
return streamCanvas(canvas, 'image/png');
default:
throw new Error('[ndarray-pixels] Unsupported file type: ' + type);
return streamCanvas(canvas, mimeType);
}

@@ -53,117 +47,20 @@ }

/** Creates readable stream from given HTMLCanvasElement and options. */
function streamCanvas(canvas: HTMLCanvasElement, mimeType: string, quality?: number): Readable {
const promise = new Promise<Uint8Array>((resolve, reject) => {
canvas.toBlob(async (blob) => {
if (blob) {
resolve(new Uint8Array(await blob.arrayBuffer()));
} else {
reject(new Error('[ndarray-pixels] Failed to canvas.toBlob().'));
}
}, mimeType, quality);
function streamCanvas(
canvas: HTMLCanvasElement,
mimeType: string,
quality?: number
): Promise<Uint8Array> {
return new Promise<Uint8Array>((resolve, reject) => {
canvas.toBlob(
async (blob) => {
if (blob) {
resolve(new Uint8Array(await blob.arrayBuffer()));
} else {
reject(new Error('[ndarray-pixels] Failed to canvas.toBlob().'));
}
},
mimeType,
quality
);
});
return Readable.from(promise);
}
function handleData(
array: NdArray,
data: Uint8Array | Uint8ClampedArray,
frame = -1
): Uint8Array | Uint8ClampedArray {
if (array.shape.length === 4) {
return handleData(array.pick(frame), data, 0);
} else if (array.shape.length === 3) {
if (array.shape[2] === 3) {
ops.assign(
ndarray(
data,
[array.shape[0], array.shape[1], 3],
[4, 4 * array.shape[0], 1]
),
array
);
ops.assigns(
ndarray(
data,
[array.shape[0] * array.shape[1]],
[4],
3
),
255
);
} else if (array.shape[2] === 4) {
ops.assign(
ndarray(
data,
[array.shape[0], array.shape[1], 4],
[4, array.shape[0] * 4, 1]
),
array
);
} else if (array.shape[2] === 1) {
ops.assign(
ndarray(
data,
[array.shape[0], array.shape[1], 3],
[4, 4 * array.shape[0], 1]
),
ndarray(
array.data,
[array.shape[0], array.shape[1], 3],
[array.stride[0], array.stride[1], 0],
array.offset
)
);
ops.assigns(
ndarray(
data,
[array.shape[0] * array.shape[1]],
[4],
3
),
255
);
} else {
throw new Error('[ndarray-pixels] Incompatible array shape.');
}
} else if (array.shape.length === 2) {
ops.assign(
ndarray(data,
[array.shape[0], array.shape[1], 3],
[4, 4 * array.shape[0], 1]),
ndarray(array.data,
[array.shape[0], array.shape[1], 3],
[array.stride[0], array.stride[1], 0],
array.offset)
);
ops.assigns(
ndarray(data,
[array.shape[0] * array.shape[1]],
[4],
3),
255
);
} else {
throw new Error('[ndarray-pixels] Incompatible array shape.');
}
return data;
}
class Readable {
constructor (private _promise: Promise<Uint8Array>) {}
on(event: 'data' | 'error' | 'end', fn: (res?: Uint8Array | Error) => void): this {
if (event === 'data') {
this._promise.then(fn);
} else if (event === 'error') {
this._promise.catch(fn)
} else if (event === 'end') {
this._promise.finally(fn);
}
return this;
}
static from (promise: Promise<Uint8Array>): Readable {
return new Readable(promise);
}
}

@@ -1,4 +0,4 @@

import getPixelsInternal from 'get-pixels';
import type { NdArray } from 'ndarray';
import savePixelsInternal from 'save-pixels';
import { getPixelsInternal } from './node-get-pixels';
import { savePixelsInternal } from './node-save-pixels';

@@ -17,17 +17,4 @@ /**

*/
async function getPixels (data: string | Uint8Array, mimeType?: string): Promise<NdArray> {
// In Node.js, get-pixels needs a Buffer and won't accept Uint8Array.
if (data instanceof Uint8Array && typeof Buffer !== 'undefined') {
data = Buffer.from(data);
}
return new Promise((resolve, reject) => {
getPixelsInternal(data, mimeType!, (err: Error | null, pixels: NdArray) => {
if (pixels && !err) {
resolve(pixels);
} else {
reject(err);
}
});
});
async function getPixels(data: Uint8Array, mimeType: string): Promise<NdArray<Uint8Array>> {
return getPixelsInternal(data, mimeType);
}

@@ -49,30 +36,9 @@

*/
async function savePixels (pixels: NdArray, mimeType: string): Promise<Uint8Array> {
return new Promise((resolve, reject) => {
const chunks: Uint8Array[] = [];
const internalType = mimeType.replace('image/', '') as 'png' | 'gif';
savePixelsInternal(pixels, internalType)
.on('data', (d: Uint8Array) => chunks.push(d))
.on('end', () => resolve(concat(chunks)))
.on('error', (e: Error) => reject(e));
});
async function savePixels(
pixels: NdArray<Uint8Array | Uint8ClampedArray>,
mimeType: string
): Promise<Uint8Array> {
return savePixelsInternal(pixels, mimeType);
}
function concat (arrays: Uint8Array[]): Uint8Array {
let totalByteLength = 0;
for (const array of arrays) {
totalByteLength += array.byteLength;
}
const result = new Uint8Array(totalByteLength);
let byteOffset = 0;
for (const array of arrays) {
result.set(array, byteOffset);
byteOffset += array.byteLength;
}
return result;
}
export {getPixels, savePixels};
export { getPixels, savePixels };

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc