CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tensorflow--tfjs-node

TensorFlow backend for TensorFlow.js via Node.js - provides native TensorFlow execution in backend JavaScript applications under the Node.js runtime, accelerated by the TensorFlow C binary under the hood

Pending
Overview
Eval results
Files

image-processing.mddocs/

Image Processing

TensorFlow.js Node provides native image processing capabilities that allow you to decode various image formats directly into tensors and encode tensors back to image formats. These operations are optimized for performance using native implementations.

Capabilities

Image Decoding

Decode Any Image Format

Automatically detects and decodes BMP, GIF, JPEG, and PNG images.

/**
 * Decode an image from a buffer into a tensor
 * @param contents - Image data as Uint8Array
 * @param channels - Number of color channels (0=auto, 1=grayscale, 3=RGB, 4=RGBA)
 * @param dtype - Output tensor data type (currently only 'int32' supported)
 * @param expandAnimations - If true, return 4D tensor for animated images
 * @returns 3D tensor [height, width, channels] or 4D [frames, height, width, channels] for animations
 */
function decodeImage(
  contents: Uint8Array,
  channels?: number,
  dtype?: 'int32',
  expandAnimations?: boolean
): Tensor3D | Tensor4D;

Usage Example:

import * as tf from '@tensorflow/tfjs-node';
import * as fs from 'fs';

// Read image file
const imageBuffer = fs.readFileSync('path/to/image.jpg');
const imageArray = new Uint8Array(imageBuffer);

// Decode to tensor
const imageTensor = tf.node.decodeImage(imageArray, 3); // RGB channels
console.log('Image shape:', imageTensor.shape); // [height, width, 3]

// Process the tensor
const normalizedImage = imageTensor.div(255.0); // Normalize to [0,1]

Decode JPEG Images

Decode JPEG images with advanced options for quality and performance tuning.

/**
 * Decode JPEG image with advanced options
 * @param contents - JPEG image data as Uint8Array
 * @param channels - Number of color channels (0=auto, 1=grayscale, 3=RGB)
 * @param ratio - Downscaling ratio for performance (1=full resolution)
 * @param fancyUpscaling - Use slower but higher quality chroma upscaling
 * @param tryRecoverTruncated - Attempt to recover truncated images
 * @param acceptableFraction - Minimum fraction of lines required for truncated recovery
 * @param dctMethod - DCT decompression method ("INTEGER_FAST" or "INTEGER_ACCURATE")
 * @returns 3D tensor [height, width, channels]
 */
function decodeJpeg(
  contents: Uint8Array,
  channels?: number,
  ratio?: number,
  fancyUpscaling?: boolean,
  tryRecoverTruncated?: boolean,
  acceptableFraction?: number,
  dctMethod?: string
): Tensor3D;

Usage Example:

// High-quality JPEG decoding
const jpegTensor = tf.node.decodeJpeg(
  imageArray,
  3,  // RGB channels
  1,  // Full resolution
  true, // High-quality upscaling
  false, // Don't recover truncated
  1.0,   // Require 100% of lines
  "INTEGER_ACCURATE" // High-quality DCT
);

// Fast JPEG decoding for thumbnails
const thumbnailTensor = tf.node.decodeJpeg(
  imageArray,
  3,  // RGB channels
  4,  // 1/4 resolution (4x downscale)
  false, // Fast upscaling
  false, // Don't recover truncated
  1.0,   // Require 100% of lines
  "INTEGER_FAST" // Fast DCT
);

Decode PNG Images

Decode PNG images with support for various bit depths and transparency.

/**
 * Decode PNG image
 * @param contents - PNG image data as Uint8Array
 * @param channels - Number of color channels (0=auto, 1=grayscale, 3=RGB, 4=RGBA)
 * @param dtype - Output tensor data type
 * @returns 3D tensor [height, width, channels]
 */
function decodePng(
  contents: Uint8Array,
  channels?: number,
  dtype?: 'int32' | 'uint8' | 'float32'
): Tensor3D;

Decode BMP Images

Decode Windows Bitmap (BMP) images.

/**
 * Decode BMP image
 * @param contents - BMP image data as Uint8Array
 * @param channels - Number of color channels (0=auto, 1=grayscale, 3=RGB)
 * @returns 3D tensor [height, width, channels]
 */
function decodeBmp(
  contents: Uint8Array,
  channels?: number
): Tensor3D;

Decode GIF Images

Decode GIF images, including animated GIFs.

/**
 * Decode GIF image (supports animation)
 * @param contents - GIF image data as Uint8Array
 * @returns 4D tensor [frames, height, width, channels] for animated GIFs
 */
function decodeGif(contents: Uint8Array): Tensor4D;

Usage Example with Animated GIF:

const gifBuffer = fs.readFileSync('animated.gif');
const gifArray = new Uint8Array(gifBuffer);

// Decode animated GIF
const gifTensor = tf.node.decodeGif(gifArray);
console.log('GIF shape:', gifTensor.shape); // [frames, height, width, channels]

// Process each frame
const frameCount = gifTensor.shape[0];
for (let i = 0; i < frameCount; i++) {
  const frame = gifTensor.slice([i, 0, 0, 0], [1, -1, -1, -1]).squeeze([0]);
  // Process individual frame...
}

Image Encoding

Encode JPEG Images

Encode tensors back to JPEG format with quality and format options.

/**
 * Encode tensor as JPEG image
 * @param image - Input tensor [height, width, channels]
 * @param format - Output format (''=auto, 'grayscale', 'rgb')
 * @param quality - JPEG quality 0-100 (default: 95)
 * @param progressive - Use progressive JPEG encoding
 * @param optimizeSize - Optimize file size over quality
 * @param chromaDownsampling - Enable chroma subsampling for smaller files
 * @param densityUnit - DPI unit ('in' or 'cm')
 * @param xDensity - Horizontal DPI
 * @param yDensity - Vertical DPI
 * @param xmpMetadata - XMP metadata string
 * @returns Promise resolving to JPEG data as Uint8Array
 */
function encodeJpeg(
  image: Tensor3D,
  format?: '' | 'grayscale' | 'rgb',
  quality?: number,
  progressive?: boolean,
  optimizeSize?: boolean,
  chromaDownsampling?: boolean,
  densityUnit?: 'in' | 'cm',
  xDensity?: number,
  yDensity?: number,
  xmpMetadata?: string
): Promise<Uint8Array>;

Usage Example:

// Create or process an image tensor
const imageTensor = tf.randomUniform([224, 224, 3], 0, 255).cast('int32');

// High-quality JPEG encoding
const highQualityJpeg = await tf.node.encodeJpeg(
  imageTensor,
  'rgb',     // RGB format
  95,        // High quality
  false,     // Not progressive
  false,     // Don't optimize size over quality
  false,     // No chroma downsampling
  'in',      // Inches
  300,       // 300 DPI horizontal
  300        // 300 DPI vertical
);

// Save to file
fs.writeFileSync('output-high-quality.jpg', Buffer.from(highQualityJpeg));

// Optimized JPEG for web
const webJpeg = await tf.node.encodeJpeg(
  imageTensor,
  'rgb',     // RGB format
  85,        // Good quality for web
  true,      // Progressive loading
  true,      // Optimize for size
  true       // Enable chroma downsampling
);

fs.writeFileSync('output-web.jpg', Buffer.from(webJpeg));

Encode PNG Images

Encode tensors as PNG images with compression options.

/**
 * Encode tensor as PNG image
 * @param image - Input tensor [height, width, channels]
 * @param compression - Compression level 0-9 (0=none, 9=max, default: 1)
 * @returns Promise resolving to PNG data as Uint8Array
 */
function encodePng(
  image: Tensor3D,
  compression?: number
): Promise<Uint8Array>;

Usage Example:

// Create or process an image tensor
const imageTensor = tf.randomUniform([224, 224, 4], 0, 255).cast('int32'); // RGBA

// Fast PNG encoding (low compression)
const fastPng = await tf.node.encodePng(imageTensor, 1);
fs.writeFileSync('output-fast.png', Buffer.from(fastPng));

// Maximum compression PNG
const compressedPng = await tf.node.encodePng(imageTensor, 9);
fs.writeFileSync('output-compressed.png', Buffer.from(compressedPng));

Image Format Detection

Get Image Type

Determine the format of image data from file headers.

/**
 * Detect image format from file header bytes
 * @param content - Image data as Uint8Array (first few bytes sufficient)
 * @returns Image format string ('jpeg', 'png', 'gif', 'bmp', or 'unknown')
 */
function getImageType(content: Uint8Array): string;

Usage Example:

const imageBuffer = fs.readFileSync('unknown-image.data');
const imageArray = new Uint8Array(imageBuffer);

const imageType = tf.node.getImageType(imageArray);
console.log('Detected format:', imageType);

// Use appropriate decoder based on format
let decodedTensor;
switch (imageType) {
  case 'jpeg':
    decodedTensor = tf.node.decodeJpeg(imageArray);
    break;
  case 'png':
    decodedTensor = tf.node.decodePng(imageArray);
    break;
  case 'gif':
    decodedTensor = tf.node.decodeGif(imageArray);
    break;
  case 'bmp':
    decodedTensor = tf.node.decodeBmp(imageArray);
    break;
  default:
    throw new Error('Unsupported image format: ' + imageType);
}

Types

enum ImageType {
  JPEG = 'jpeg',
  PNG = 'png',
  GIF = 'gif',
  BMP = 'BMP'
}

type ImageFormat = '' | 'grayscale' | 'rgb';
type DensityUnit = 'in' | 'cm';

Common Patterns

Image Preprocessing Pipeline

import * as tf from '@tensorflow/tfjs-node';
import * as fs from 'fs';

async function preprocessImage(imagePath: string): Promise<Tensor4D> {
  // Load image
  const imageBuffer = fs.readFileSync(imagePath);
  const imageArray = new Uint8Array(imageBuffer);
  
  // Decode image
  const imageTensor = tf.node.decodeImage(imageArray, 3); // RGB
  
  // Resize to model input size
  const resized = tf.image.resizeBilinear(imageTensor, [224, 224]);
  
  // Normalize to [0,1]
  const normalized = resized.div(255.0);
  
  // Add batch dimension
  const batched = normalized.expandDims(0);
  
  // Clean up intermediate tensors
  imageTensor.dispose();
  resized.dispose();
  normalized.dispose();
  
  return batched;
}

Image Augmentation

async function augmentAndSave(inputPath: string, outputPath: string) {
  const imageBuffer = fs.readFileSync(inputPath);
  const imageArray = new Uint8Array(imageBuffer);
  
  // Decode
  const original = tf.node.decodeImage(imageArray, 3);
  
  // Apply augmentations
  const flipped = tf.image.flipLeftRight(original);
  const rotated = tf.image.rot90(original);
  const brightened = tf.image.adjustBrightness(original, 0.2);
  
  // Encode and save variations
  const flippedJpeg = await tf.node.encodeJpeg(flipped.cast('int32'));
  const rotatedJpeg = await tf.node.encodeJpeg(rotated.cast('int32'));
  const brightenedJpeg = await tf.node.encodeJpeg(brightened.cast('int32'));
  
  fs.writeFileSync(`${outputPath}/flipped.jpg`, Buffer.from(flippedJpeg));
  fs.writeFileSync(`${outputPath}/rotated.jpg`, Buffer.from(rotatedJpeg));
  fs.writeFileSync(`${outputPath}/brightened.jpg`, Buffer.from(brightenedJpeg));
  
  // Clean up
  original.dispose();
  flipped.dispose();
  rotated.dispose();
  brightened.dispose();
}

Install with Tessl CLI

npx tessl i tessl/npm-tensorflow--tfjs-node

docs

callbacks.md

image-processing.md

index.md

io.md

savedmodel.md

tensorboard.md

tile.json