Sixel
Sixel is a bitmap graphics format and terminal control protocol developed by Digital Equipment Corporation (DEC) in the 1980s for rendering images on text-based terminals and printers.[1] It encodes pixel data using sequences of printable ASCII characters, where each character represents six vertical pixels in a single-pixel-wide column, enabling efficient inline image display without requiring dedicated graphics hardware.[1] Originally introduced with the VT300 series terminals, such as the VT330 for monochrome graphics and the VT340 for up to 16 colors, Sixel uses a device control string (DCS) to initiate transmission, followed by data characters from '?' (hex 3F) to '~' (hex 7E) that map binary pixel states (1 for on, 0 for off).[1] The protocol supports key features like color specification in basic palettes or HLS/RGB models, pixel aspect ratio adjustments (default 2:1 for terminals), and control functions for repeating pixels ('!'), setting raster attributes ('"'), selecting colors ('#'), and line advances ('-' for newline, '$' for carriage return).[1] Background color handling can retain the current terminal background or map it to a specific color, and scrolling modes allow images to either scroll within bottom margins or be clipped.[1] Designed for DEC's ecosystem, including compatibility with printers for tasks like font design, Sixel's compact, character-based encoding made it suitable for low-bandwidth serial connections typical of early computing environments.[1] In modern contexts, Sixel has seen renewed interest for terminal-based applications, with libraries like libsixel providing encoders, decoders, and conversion tools (e.g.,img2sixel) to support image formats such as PNG, JPEG, and GIF animations on contemporary terminal emulators.[2] This library, originally inspired by earlier implementations and released under the MIT License, enables features like high-quality color quantization, compression improvements, and integration with tools for video streaming (via FFmpeg-SIXEL) and GUI elements in terminals like mlterm or XTerm with Sixel enabled.[2] Support extends to platforms including Unix-like systems, Windows via MinGW, and even legacy hardware, facilitating uses in remote desktop virtualization, web browsing (e.g., with w3m), and lightweight gaming via SDL.[2] Despite its age, Sixel remains notable for its efficiency in paletted bitmap rendering, influencing terminal graphics standards and ongoing emulator implementations.[2]
History and Development
Origins in DEC Terminals
Sixel was introduced by Digital Equipment Corporation (DEC) in the early 1980s as a bitmap graphics format designed specifically for its VT200-series video terminals and compatible printers, including the LA100 series. The format debuted around 1983–1984, coinciding with the launch of the VT240 terminal model in late 1983. This innovation allowed DEC's text-oriented hardware to handle graphical output efficiently, marking an early step in integrating simple imaging capabilities into terminal-based computing environments.[3][4] The primary purpose of Sixel was to enable the inline display and printing of bitmap images within text-based terminals and printers, eliminating the need for dedicated graphics hardware. By encoding images as vertical strips of six pixels high—hence the name "sixel"—the format optimized transmission over serial connections typical of the era, supporting compact representation of plots and diagrams directly in character streams. This approach was particularly suited to DEC's ecosystem, where terminals connected to minicomputers via asynchronous serial interfaces. Sixel originated as a protocol for DEC printers like the LA100 and LA50 series around 1982–1984, before its adoption in terminals such as the VT240.[3][1] Developed to enhance graphical output from DEC's PDP-11 minicomputers and VAX superminicomputers, Sixel facilitated applications such as data graphing, simple plotting, and image printing in environments running operating systems like RSX-11 and VMS. These systems, prevalent in scientific, engineering, and business computing during the 1980s, benefited from Sixel's ability to render visuals without interrupting text workflows, thereby supporting tasks like chart generation in programming or report printing. The format's integration with VT200-series terminals extended the utility of DEC hardware for users requiring occasional graphics alongside primary text operations.[4][1] The first documented implementation of Sixel appears in the VT240 Series Programmer's Pocket Guide, published by DEC in September 1983, which details its use for bitmap graphics alongside other features like ReGIS vector graphics. Later DEC hardware, such as the VT340 terminal introduced in 1987, expanded Sixel to include color support, building on its monochrome foundations.[3][1]Evolution and Standards
Following its initial proprietary implementation by Digital Equipment Corporation (DEC) in the VT200 series terminals during the early 1980s, the Sixel format transitioned toward broader standardization through the adoption of its underlying control mechanism in international standards for terminal control functions. The Device Control String (DCS) introducer, which encapsulates Sixel data as ESC P ... ST sequences, was formally defined in the ECMA-48 standard (5th edition, 1991), subsequently adopted as ISO/IEC 6429:1992, enabling interoperability for device-specific extensions like Sixel across compatible systems.[5] This inclusion positioned Sixel within a framework for coded character sets and control functions, though the bitmap encoding details remained DEC-specific.[5] In the 1980s and early 1990s, DEC enhanced Sixel capabilities in the VT300 series terminals, notably the VT340 color model introduced in 1987, by integrating palette-based color support. The VT340 allowed selection of up to 16 colors from a 4096-color palette for Sixel images, marking a significant upgrade from the four-color limit in earlier VT200-series devices like the VT240.[6][6] The Sixel format itself was designed to accommodate up to 256 color registers, providing scalability for future hardware while aligning with the six-pixel-high core structure originated in DEC's earlier terminals.[7] Sixel's development paralleled DEC's ReGIS (Remote Graphics Instruction Set), a vector graphics protocol introduced in 1979 for terminals like the VT125, but the two formats diverged in purpose: ReGIS emphasized scalable line drawings and geometric primitives, whereas Sixel prioritized compact bitmap representation for raster images.[8] This distinction influenced DEC's terminal ecosystem, with Sixel filling the niche for pixel-based output in text-oriented environments.[7] By the late 1990s, native hardware support for Sixel waned as graphical user interfaces (GUIs) like those in Microsoft Windows and X Window System dominated computing, reducing demand for character-cell terminals and their specialized graphics modes. However, the format persisted in software emulators, such as xterm, ensuring compatibility for legacy applications and preserving Sixel's role in terminal-based graphics.[9]Technical Specification
Basic Structure and Encoding
Sixel graphics represent images as a bitmap encoded in a series of vertical strips, each six pixels high and one pixel wide. This structure leverages the fixed dimensions of terminal character cells, where each cell typically accommodates six pixels vertically to align with the height of a single row of sixel data. The format ensures that the entire image height is a multiple of six pixels, allowing complete coverage without partial rows.[1] Each vertical strip, known as a sixel, is encoded using a single 7-bit ASCII character from the range '?' (0x3F) to '~' (0x7E), which provides 64 possible values (0 to 63), each representing a unique 6-bit pattern where each bit corresponds to one pixel in the vertical column: a '1' indicates a pixel on, and '0' indicates off, with the least significant bit at the top pixel. This mapping allows direct representation of binary pixel states within printable characters suitable for terminal transmission.[1][10] Images are constructed by sequencing these sixel strips horizontally from left to right within each row, forming a complete horizontal scan line of six pixels high. To advance to the next row, a graphics newline character is used, progressing the raster top-to-bottom. The image width, measured in pixels, is typically a multiple of six to maintain aspect ratio and align with terminal character cell widths, where six horizontal pixels span one character cell for square pixel rendering. This organization results in a compact, row-major raster format optimized for sequential character-stream output.[1] In the binary-to-sixel mapping, each 6-bit pattern of a vertical pixel column is converted to its corresponding character by adding the pattern value (0 to 63) to 0x3F. For instance, a column with all pixels on (binary 111111, decimal 63) maps to '~' (0x7E), while all pixels off (binary 000000, decimal 0) maps to '?' (0x3F). This scheme enables efficient encoding of monochrome bitmaps directly into text streams.[1][10]Color and Palette Handling
Sixel utilizes a palette-based color system in which a set of color registers is defined prior to the transmission of the pixel data, allowing each vertical strip of six pixels to reference a palette index for uniform coloring. In the original DEC VT series terminals, the color-capable VT340 supports up to 16 palette entries that can be set using the HLS or RGB models with parameters as integers from 0 to 100 (percentages for RGB/lightness/saturation) or 0-360 for hue; the monochrome VT330 is limited to 4 intensity levels for shades of gray. These intensity levels allow for varying brightness in monochrome images on the VT330.[1] Color assignment occurs by selecting a palette index (ranging from 0 to the maximum supported by the terminal) for each strip, enabling efficient encoding where the six pixels in a column share the same color without per-pixel specification. Initial DEC implementations provided limited color support, starting with monochrome in earlier models like the VT240 and expanding to these small palettes in color-capable terminals, which relied on the terminal's hardware for rendering.[1] Modern extensions of the Sixel format, as implemented in libraries like libsixel and terminal emulators such as xterm and mlterm, expand the palette to a maximum of 256 colors to accommodate more complex images while maintaining compatibility. These implementations typically define palette entries using 6-bit RGB values per channel (0-63), yielding up to 262,144 distinct colors, though the palette itself remains indexed to 256 slots; the dynamic nature of the palette allows entries to be redefined via control sequences at any point before or between strips, facilitating adaptive color mapping without resetting the entire image.[2][7] Notably, Sixel lacks native support for an alpha channel, preventing per-pixel transparency, and dithering is not inherent to the format, requiring external tools or preprocessors to approximate gradients or reduce higher-color-depth images to the palette.[2]Control Sequences
Sixel graphics are initiated by transmitting a Device Control String (DCS), which in 7-bit environments is represented as the escape sequence ESC P (decimal 27 followed by 80), or directly as the 8-bit DCS control character (decimal 144). This is followed by up to three optional numeric parameters separated by semicolons—P1 for pixel aspect ratio (e.g., omitted or 0 for 2:1, 7 for 1:1), P2 for background color handling (0 or 2 to use the current background, 1 to retain the previous Sixel background), and P3 for horizontal grid size in centimeters (often 0 and ignored in VT300-series terminals)—then the protocol selector 'q' (decimal 113), marking the start of the Sixel data stream.[1][9] Within the DCS string, initial control sequences configure image attributes before the pixel data. For instance, the raster attribute introducer '"' (decimal 34), known as DECGRA in DEC documentation, sets parameters such as pan/pad positioning (Pa), horizontal pixel size (Ph in cm), and vertical pixel size (Pv in cm), allowing dynamic adjustment of image dimensions and aspect ratio independent of the initial DCS parameters.[1][11] The repeat introducer '!' (decimal 33) enables efficient encoding by repeating a subsequent sixel character n times (where n is a decimal number up to 65535), which can be used initially to fill or initialize areas, including palette-related patterns if combined with color definitions.[1][7] Color and palette configuration occur via the graphics color introducer '#' (decimal 35), or DECGCI, which assigns a color to a specific index Pc (0-255) or selects a predefined color; in extended form, it uses '#' Pc ; Pu ; Px ; Py ; Pz, where Pu specifies the color space (1 for HLS with hue, lightness, and saturation values 0-360 and 0-100, or 2 for RGB with red, green, and blue values 0-100).[1][11] Palette initialization typically involves defining colors from index 0 onward at the start of the data stream, resetting to defaults by re-specifying all entries or relying on the terminal's initial state.[9] Positioning within the graphics is managed by the graphics carriage return '$' (decimal 36), which returns to the left margin on the current line, and the graphics new line '-' (decimal 45), which advances to the next line.[1] The Sixel mode is terminated by the String Terminator (ST), represented as ESC \ (decimal 27 followed by 92) in 7-bit environments or the 8-bit ST control character (decimal 156), which ends the graphics stream and resumes text processing at the cursor position following the image.[1][9] DEC-specific extensions include private modes like CSI ? 80 h to enable Sixel Display Mode (DECSDM), which controls scrolling behavior during graphics rendering.[9] These sequences ensure compatibility with DEC VT-series terminals while allowing flexible configuration of graphics attributes.[12]Implementation and Usage
Terminal Support
Sixel graphics were originally supported in hardware by Digital Equipment Corporation (DEC) terminals starting from the VT220 model introduced in 1983, which included built-in decoding for Sixel data primarily for defining soft character sets, though it lacked bitmap screen memory for direct on-screen rendering.[10] The VT240, also released in 1983, extended this capability with bitmap screen memory, enabling direct writing and display of Sixel graphics on the terminal screen.[10] Similarly, the VT320 from 1987 supported Sixel decoding for soft character sets but, like the VT220, did not feature bitmap memory for full graphics display.[10] Printer integration for Sixel output was provided by DEC's LA210 letter-quality printer, which accepted Sixel format data for high-speed bitmap printing, including support for multiple typefaces and print modes compatible with VT-series terminals. This printer enabled hardcopy reproduction of Sixel graphics directly from terminal sessions, providing emulation for IBM-compatible printers alongside native Sixel handling.[13] In Unix and Linux environments, emulation of Sixel support began with xterm in the 1990s, initially offering partial implementation that required specific compilation flags like --enable-sixel-graphics and terminal type settings such as -ti vt340 to enable decoding and basic rendering. Modern configurations, including terminfo entries like xterm-256color, provide fuller support when compiled appropriately, allowing Sixel graphics to integrate with extended color palettes and improved rendering.[2] One notable challenge in Sixel display across both hardware and emulated terminals involves interactions between graphics rendering and text operations, particularly cursor positioning and scrolling; for instance, when the Sixel active position reaches the bottom margin, scrolling may occur, and upon exiting Sixel mode, the text cursor repositions to the active graphics location, potentially disrupting ongoing text output.[1] Activation typically relies on DEC private mode sequences, such as DCS to initiate Sixel mode, which must be handled precisely to avoid such conflicts.[1]Image Conversion and Tools
Software utilities for converting common image formats to Sixel enable the display of graphics in compatible terminals. One of the primary tools is ImageMagick'sconvert command, which supports output in Sixel format via the -format sixel option, allowing conversion from formats such as PNG and JPEG.[14] This feature was added in ImageMagick version 6.8.9-9.[15] For example, users can execute convert input.png -format sixel output.sixel to generate Sixel data from a PNG file.[16]
An alternative is the libsixel library, a lightweight C implementation for encoding and decoding Sixel graphics, which includes the command-line tool img2sixel for converting images like PNG, JPEG, GIF, and BMP to Sixel format.[17] The img2sixel utility supports options for specifying output files, color reduction, and dithering methods to optimize the resulting Sixel stream.[18]
The conversion process typically begins with preprocessing the input image: resizing dimensions to multiples of 6 pixels where necessary for efficient encoding, followed by palette quantization to limit colors to a maximum of 256, often using techniques like dithering for quality preservation.[19] The quantized image is then encoded into horizontal strips of 6 pixels high, where each vertical column within a strip is represented by 6 bits.[1]
Generated Sixel output can be handled by piping directly to a terminal for immediate rendering, such as img2sixel input.jpg | cat, or saved to files with a .sixel extension for later use or transfer.[2] This flexibility supports both interactive terminal sessions and scripted workflows.[20]
Example Encoding Process
To illustrate the Sixel encoding process, consider a simple monochrome image consisting of a 6x6 pixel square where all pixels are set to on, forming a solid block.[1] The encoding begins by dividing the image into horizontal strips, each 6 pixels high, as Sixel operates on vertical columns of 6 pixels known as sixels.[1] For this 6-pixel-high image, it comprises exactly one such strip. This strip is then subdivided into 6 vertical sixels, each 1 pixel wide and representing the full height; with all pixels on, the binary pattern for each sixel is 111111 (decimal 63).[1] Next, each 6-bit sixel value is converted to a printable ASCII character by adding hexadecimal 3F (decimal 63) to the bit pattern's value, yielding characters in the range from '?' (0x3F, for 000000) to 'When this sequence is processed by a Sixel-compatible terminal emulator, it renders the data as a filled 6x6 pixel square, with each '~' producing a vertical column of 6 lit pixels.[1]\x90 0 ; 0 ; 0 ; q ~~~~~~ \x9C\x90 0 ; 0 ; 0 ; q ~~~~~~ \x9C
Modern Relevance and Extensions
Current Terminal Emulators
In the 21st century, several terminal emulators have implemented Sixel support to enable bitmap graphics rendering within text-based environments, with varying degrees of completeness and performance. Mlterm, first released in the early 2000s, provides full Sixel compatibility starting from version 3.1.9, supporting up to 256 colors via a dynamic palette that allows for efficient rendering of images without requiring full 24-bit color depth per pixel.[21] Xterm, a longstanding X Window System emulator, enhanced its Sixel capabilities in the 2010s, with full support enabled by default since patch #359 in 2018, including dynamic palette management for 24-bit color reproduction and compatibility with VT340 emulation mode.[22] These emulators prioritize protocol fidelity, allowing seamless display of Sixel-encoded images in applications like plotting tools and image viewers. WezTerm, a cross-platform GPU-accelerated terminal introduced in 2020, offers full Sixel support from its initial stable release, handling dynamic palettes and 256+ effective colors through palette optimization, which contributes to smooth performance in modern workflows.[23] In contrast, Kitty, launched in 2017, does not natively support Sixel but provides superior graphics via its proprietary Terminal Graphics Protocol, which supports multiple image formats and GPU acceleration for higher efficiency in image rendering.[24] For emulators with partial or experimental implementations, Alacritty relies on community forks like alacritty-sixel for Sixel decoding, enabling basic palette-based rendering but lacking official integration and optimized dynamic palette handling as of 2025.[25] Rio, a Rust-based terminal focused on hardware acceleration since the early 2020s, implemented full Sixel support around 2024, providing dynamic palette handling and production-ready performance for image rendering, including support for GIF animations and custom character sets.[26] Microsoft's Windows Terminal introduced Sixel support in preview version 1.22 in September 2024, with full integration in stable releases by 2025, supporting dynamic palettes and efficient rendering on Windows systems.[27] Compatibility across these emulators varies in color depth, palette flexibility, and rendering efficiency, as tracked by the "Are We Sixel Yet?" resource, which monitors Sixel adoption in open-source terminals as of late 2025. The following table summarizes key aspects for prominent examples:| Terminal Emulator | Support Level | Color Support | Dynamic Palettes | Performance Notes |
|---|---|---|---|---|
| Mlterm | Full | 256 colors | Yes | Efficient for images up to 1024x768 resolution, suitable for real-time plotting without lag.[28] |
| Xterm | Full | 24-bit via palette | Yes | Handles large palettes reliably in VT340 mode, with minimal overhead for standard bitmap displays.[22] |
| WezTerm | Full | 256+ effective | Yes | GPU acceleration ensures smooth rendering of dynamic content, outperforming CPU-bound alternatives.[29] |
| Kitty | None (alternative protocol) | N/A | N/A | Relies on custom protocol for faster, format-agnostic graphics; Sixel incompatible.[24] |
| Alacritty (fork) | Partial/Experimental | 256 colors | Limited | Fork enables basic decoding but may introduce rendering artifacts in complex palettes.[30] |
| Rio | Full | 256+ colors | Yes | Functional support with demos for image and GIF rendering, suitable for production use on hardware-accelerated systems.[31] |
| Windows Terminal | Full | 24-bit via palette | Yes | GPU-accelerated rendering for smooth image display on Windows platforms as of stable releases in 2025.[27] |