npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@blecsd/media

v0.6.0

Published

Media rendering for blECSd - GIF/PNG parsers, ANSI rendering, image and video widgets

Readme

@blecsd/media

Media rendering for blECSd - GIF/PNG parsers, ANSI rendering, image and video widgets.

Installation

pnpm add @blecsd/media

Overview

@blecsd/media provides media rendering capabilities for terminal applications. It includes parsers for GIF and PNG image formats, ANSI-based rendering for terminal display, W3M overlay support for high-quality image rendering, and widgets for displaying images and videos.

Quick Start

import { createWorld } from 'blecsd';
import { parseGIF, parsePNG, createImage, renderToANSI } from '@blecsd/media';
import { readFileSync } from 'fs';

const world = createWorld();

// Load and display a PNG image
const pngData = readFileSync('image.png');
const png = parsePNG(pngData);

const image = createImage(world, {
  x: 0,
  y: 0,
  width: 40,
  height: 20,
  imageData: png
});

// Load and display an animated GIF
const gifData = readFileSync('animation.gif');
const gif = parseGIF(gifData);

const animatedImage = createImage(world, {
  x: 0,
  y: 21,
  width: 40,
  height: 20,
  imageData: gif,
  animate: true
});

// Convert image to ANSI cells for terminal rendering
const cells = renderToANSI(png, {
  width: 40,
  height: 20,
  dithering: true
});

Namespace Imports

The @blecsd/media package provides namespace objects that group related functions for media processing. These frozen objects make it easy to explore available functions via IDE autocomplete:

import { gif, png, ansiRender, imageWidget, videoWidget } from '@blecsd/media';

// GIF parsing with nested namespaces
const gifResult = gif.parse.parseGIF(buffer);
if (gifResult.success) {
  const rgba = gif.frame.frameToRGBA(gifResult.data.frames[0]);
  const decompressed = gif.lzw.decompressLZW(data, minCodeSize);
}

// PNG parsing with nested namespaces
const pngResult = png.parse.parsePNG(buffer);
if (pngResult.success) {
  const pixels = png.pixels.extractPixels(pngResult.data);
  const filtered = png.filters.reconstructFilters(scanlines);
}

// ANSI rendering
const bitmap = { width: 100, height: 50, data: new Uint8Array(...) };
const cellMap = ansiRender.renderToAnsi(bitmap, { mode: '256-color' });
const output = ansiRender.cellMapToString(cellMap);

// Image widget operations
const img = imageWidget.create(world, { width: 40, height: 20, imageData: png });
imageWidget.setFrame(eid, 0);
imageWidget.play(eid);

// Video widget operations
const video = videoWidget.create(world, { width: 40, height: 20, frames });
videoWidget.play(eid);
videoWidget.setFPS(eid, 30);

Available Namespaces

| Namespace | Purpose | Key Methods | |-----------|---------|-------------| | gif | GIF image parsing | Nested: parse (parseGIF, validateGIFSignature), lzw (decompressLZW, createBitReader), frame (frameToRGBA, deinterlace) | | png | PNG image parsing | Nested: parse (parsePNG, parseChunks, parseIHDR), filters (reconstructFilters, paethPredictor), pixels (extractPixels, parsePLTE) | | ansiRender | Terminal rendering from bitmaps | renderToAnsi, cellMapToString, scaleBitmap, rgbTo256Color, luminanceToChar | | imageWidget | Image widget operations | create, setImageData, setFrame, play, pause, stop | | videoWidget | Video widget operations | create, play, pause, stop, setFPS, seek | | w3m | W3M overlay support | createOverlay, showImage, hideImage, updatePosition |

Subpath Imports

For tree-shakeable imports, use subpath exports to import only the functions you need:

// Import specific parsers
import { parseGIF, frameToRGBA } from '@blecsd/media/gif';
import { parsePNG, extractPixels } from '@blecsd/media/png';

// Import rendering utilities
import { renderToAnsi, cellMapToString } from '@blecsd/media/render';

// Import widgets
import { createImage } from '@blecsd/media/widgets/image';
import { createVideo } from '@blecsd/media/widgets/video';

// Import W3M overlay
import { createW3MOverlay } from '@blecsd/media/overlay';

Available subpath exports:

  • @blecsd/media/gif - GIF parser and utilities
  • @blecsd/media/png - PNG parser and utilities
  • @blecsd/media/render - ANSI rendering functions
  • @blecsd/media/widgets/image - Image widget
  • @blecsd/media/widgets/video - Video widget
  • @blecsd/media/overlay - W3M overlay support

API

Image Parsers

| Function | Description | |----------|-------------| | parseGIF(buffer) | Parse GIF image data with LZW decompression and animation support | | parsePNG(buffer) | Parse PNG image data with filter handling and transparency |

Both parsers return image data structures with:

  • width, height - Image dimensions
  • pixels - RGBA pixel data
  • frames - Animation frames (GIF only)
  • delays - Frame delays in ms (GIF only)

Rendering

| Function | Description | |----------|-------------| | renderToANSI(imageData, options) | Convert image to ANSI colored cells for terminal display |

Render options:

  • width, height - Target dimensions
  • dithering?: boolean - Apply dithering for better color representation
  • background?: number - Background color (RGBA)
  • mode?: 'block' | 'halfblock' | 'braille' - Rendering mode

Widgets

| Widget | Description | |--------|-------------| | createImage(world, config) | Static or animated image widget | | createVideo(world, config) | Video playback widget with frame-by-frame rendering |

Image widget configuration:

{
  x: number;
  y: number;
  width: number;
  height: number;
  imageData: ImageData;
  animate?: boolean;        // Enable animation for GIFs
  loop?: boolean;           // Loop animation
  fps?: number;             // Override frame rate
  border?: BorderConfig;
  style?: StyleConfig;
}

Video widget configuration:

{
  x: number;
  y: number;
  width: number;
  height: number;
  frames: ImageData[];      // Array of video frames
  fps?: number;             // Playback frame rate (default: 30)
  loop?: boolean;           // Loop playback
  autoplay?: boolean;       // Start playing immediately
  controls?: boolean;       // Show playback controls
}

W3M Overlay Support

For high-quality image rendering in supported terminals:

import { createW3MOverlay } from '@blecsd/media';

const overlay = createW3MOverlay(world, {
  x: 0,
  y: 0,
  width: 80,
  height: 24,
  imagePath: '/path/to/image.png'
});

// W3M renders the image as an overlay on the terminal

Image Data Format

All parsers and renderers use a standard image data format:

interface ImageData {
  width: number;
  height: number;
  pixels: Uint8Array;        // RGBA format (4 bytes per pixel)
  frames?: ImageFrame[];     // For animations
}

interface ImageFrame {
  pixels: Uint8Array;
  delay: number;             // Frame delay in ms
  disposal?: number;         // Frame disposal method
}

Rendering Modes

  • block - Full cell blocks (2:1 aspect ratio, lower resolution)
  • halfblock - Half-block characters (1:1 aspect ratio, medium resolution)
  • braille - Braille patterns (high resolution, 2x4 pixels per cell)

Supported Formats

GIF

  • Animated and static GIFs
  • LZW decompression
  • Transparency
  • Frame disposal methods
  • Loop count

PNG

  • RGB and RGBA color
  • Grayscale and indexed color
  • Transparency (alpha channel)
  • Interlaced images
  • PNG filters (sub, up, average, Paeth)

Requirements

  • blecsd (peer dependency)
  • Node.js 18+

License

MIT