Files
scrypted/plugins/tensorflow/src/jpeg.ts
2021-11-02 14:40:40 -07:00

60 lines
1.8 KiB
TypeScript

import * as jpeg from 'jpeg-js';
import { tensor3d, Tensor3D } from '@tensorflow/tfjs'
/**
* Decode a JPEG-encoded image to a 3D Tensor of dtype `int32`.
*
* ```js
* // Load an image as a Uint8Array
* const imageUri = 'http://image-uri-here.example.com/image.jpg'; *
* const response = await fetch(imageUri, {}, { isBinary: true });
* const imageDataArrayBuffer = await response.arrayBuffer();
* cosnt imageData = new Uint8Array(imageDataArrayBuffer);
*
* // Decode image data to a tensor
* const imageTensor = decodeJpeg(imageData);
* ```
*
* @param contents The JPEG-encoded image in an Uint8Array.
* @param channels An optional int. Defaults to 3. Accepted values are
* 0: use the number of channels in the JPG-encoded image.
* 1: output a grayscale image.
* 3: output an RGB image.
* @returns A 3D Tensor of dtype `int32` with shape [height, width, 1/3].
*
* @doc {heading: 'Media', subheading: 'Images'}
*/
export function decodeJpeg(
contents: Uint8Array, channels: 0 | 1 | 3 = 3): Tensor3D {
const { width, height, data } = jpeg.decode(contents, {
useTArray: true,
formatAsRGBA: false,
});
return tensor3d(data, [height, width, channels]);
}
export async function encodeJpeg(imageTensor: Tensor3D) {
const [height, width] = imageTensor.shape;
const buffer = await imageTensor.data();
const frameData = new Uint8Array(width * height * 4);
let offset = 0;
for (let i = 0; i < frameData.length; i += 4) {
frameData[i] = buffer[offset];
frameData[i + 1] = buffer[offset + 1];
frameData[i + 2] = buffer[offset + 2];
frameData[i + 3] = 0xFF;
offset += 3;
}
const rawImageData = {
data: frameData,
width,
height,
};
const jpegImageData = jpeg.encode(rawImageData);
return jpegImageData.data;
}