gifenc

repository·main·Indexed 43 days ago

https://github.com/mattdesl/gifenc

A fast, lightweight JavaScript library for encoding GIF animations. Version 1.0.3 provides a streaming API via the GIFEncoder to build GIF files frame-by-frame, featuring support for color quantization, palette management, and both auto and manual encoding modes. Includes utility functions for color mapping such as prequantize, applyPalette, and snapColorsToPalette.

Tokens
2K
Snippets
7
Records
10
Agent score
6%

What's inside gifenc

  1. How GIFEncoder works in 'auto' vs 'manual' mode

    main

    The GIFEncoder behavior changes based on the auto option provided during initialization:

    Auto Mode (auto: true)

    This is the default. The encoder manages the GIF structure for you. When you call writeFrame for the first time, the encoder automatically:

    1. Writes the GIF header (GIF89a).
    2. Writes the Logical Screen Descriptor.
    3. Writes the Global Color Table (using the palette provided in the first frame's options).
    4. Writes the Netscape Application Extension (if repeat is provided).

    Requirement: In auto mode, the first call to writeFrame must include a palette in its options.

    Manual Mode (auto: false)

    You have full control over the GIF structure. The encoder will not automatically write headers or global descriptors. You are responsible for ensuring the stream contains the necessary GIF metadata before or during your frame writes.

  2. Use palettize functions for color management

    main

    The library exports several utility functions for handling color palettes and mapping colors to indices, which is essential for preparing the index array passed to writeFrame.

    Available Functions:

    • prequantize: Prepares colors for quantization.
    • applyPalette: Applies a palette to a set of colors.
    • nearestColor: Finds the closest color in a palette to a given color.
    • nearestColorIndex: Finds the index of the closest color in a palette.
    • nearestColorIndexWithDistance: Finds the index of the closest color and returns the distance.
    • snapColorsToPalette: Snaps a set of colors to the nearest colors in a provided palette.
  3. Snap colors to a palette

    main

    The snapColorsToPalette function attempts to update colors within a palette to match a set of knownColors, provided the difference is within a certain threshold.

    This is useful for ensuring that specific "important" colors are exactly represented in the generated palette.

    Parameters:

    • palette: The palette array to be modified in-place.
    • knownColors: An array of colors that should be present in the palette.
    • threshold (number, default: 5): The maximum Euclidean distance allowed for a color to be snapped.
  4. Find the nearest color in a palette

    main

    These functions allow finding the closest color in a collection based on a distance function (defaults to euclideanDistanceSquared).

    • nearestColor(colors, pixel, distanceFn): Returns the color from the colors array that is closest to the pixel.
    • nearestColorIndex(colors, pixel, distanceFn): Returns the index of the closest color.
    • nearestColorIndexWithDistance(colors, pixel, distanceFn): Returns an array [index, distance] where index is the index of the closest color and distance is the calculated distance.
    import { nearestColor } from './palettize.js';
    
    const palette = [[255, 0, 0], [0, 255, 0], [0, 0, 255]];
    const pixel = [240, 10, 5];
    
    const closest = nearestColor(palette, pixel);
    // closest will be [255, 0, 0]
  5. Initialize the GIFEncoder

    main

    The GIFEncoder function creates an encoder instance used to stream encoded GIF data into a buffer. You can configure the initial capacity of the internal stream.

    Options:

    • initialCapacity (number, default: 4096): The initial size of the internal buffer.
    • auto (boolean, default: true): If true, the encoder automatically writes the GIF header and global color table when the first frame is written. If false, you must manually manage the header and first frame details.
    import GIFEncoder from 'gifenc';
    
    const encoder = GIFEncoder({ initialCapacity: 8192, auto: true });
  6. Apply a palette to RGBA data

    main

    The applyPalette function maps an RGBA image to a color palette, returning an array of indices. This is used to convert high-color images into indexed-color images.

    Parameters:

    • rgba: A Uint8Array or Uint8ClampedArray containing RGBA data.
    • palette: An array of colors (up to 256). Each color is typically an array like [r, g, b] or [r, g, b, a].
    • format (string, default: 'rgb565'): The color packing format used for internal caching to speed up the process. Supported values:
      • 'rgb565'
      • 'rgb444'
      • 'rgba4444'

    Returns: A Uint8Array containing the palette indices for each pixel.

    Throws:

    • If rgba is not a Uint8Array or Uint8ClampedArray.
    • If palette.length is greater than 256.
    const indices = applyPalette(rgbaData, myPalette, 'rgb565');
  7. Write a frame with writeFrame()

    main

    The writeFrame method encodes a single frame of the GIF.

    Parameters:

    • index (Uint8Array): An array of color indices representing the pixels in the frame.
    • width (number): The width of the frame in pixels.
    • height (number): The height of the frame in pixels.
    • opts (object, default: {}): Frame-specific configuration.

    Frame Options (opts):

    • transparent (boolean, default: false): Whether to enable transparency.
    • transparentIndex (number, default: 0x00): The color index to treat as transparent.
    • delay (number, default: 0): The delay between frames in centiseconds (1/100th of a second).
    • palette (Array<[number, number, number]> | null, default: null): The color palette for this frame. Note: If auto mode is enabled, the first frame must include a palette.
    • repeat (number, default: 0): The loop count. -1 for once, 0 for forever, or >0 for a specific count.
    • colorDepth (number, default: 8): The bit depth of the color palette.
    • dispose (number, default: -1): The disposal method for the frame.
    encoder.writeFrame(pixelIndices, width, height, {
      delay: 5,
      palette: [[255, 255, 255], [0, 0, 0]],
      transparent: true,
      transparentIndex: 0
    });
  8. Prequantize RGBA data

    main

    The prequantize function modifies an existing Uint8Array or Uint8ClampedArray containing RGBA data in-place. It reduces color depth by rounding RGB and Alpha channels to specific steps, which can help in reducing noise or preparing data for quantization.

    Options:

    • roundRGB (number, default: 5): The step size for rounding Red, Green, and Blue channels.
    • roundAlpha (number, default: 10): The step size for rounding the Alpha channel.
    • oneBitAlpha (number | null, default: null): If provided, converts the alpha channel to a 1-bit value (0x00 or 0xff). If a number is provided, it acts as a threshold (defaulting to 127 if a boolean true is passed).
    // Example: Rounding RGB by 5 and forcing 1-bit alpha
    prequantize(rgbaData, {
      roundRGB: 5,
      oneBitAlpha: 128
    });
  9. Retrieve encoded GIF data from GIFEncoder

    main

    After writing all frames, use these methods to extract the encoded data from the encoder instance.

    • finish(): Writes the GIF trailer byte to the stream to finalize the file.
    • bytes(): Returns a Uint8Array containing the entire encoded GIF.
    • bytesView(): Returns a Uint8Array view of the encoded data.
    • get buffer: Returns the underlying ArrayBuffer used by the stream.
    • get stream: Returns the internal stream object.
    encoder.finish();
    const gifData = encoder.bytes();