Image to Unicode Quadrant ANSI: Principles, Implementation and a Browser Tool
Image to Unicode Quadrant ANSI: Principles, Implementation and a Browser Tool
Search
Ask the AI

Image to Unicode Quadrant ANSI: Principles, Implementation and a Browser Tool

I already had a truecolor half-block version: scale the image down to the terminal width, then use the upper and lower half-block characters to store the colours of two pixel rows. That approach is stable and widely compatible, but each character can only express two sample points. To make an image finer in the command line, the character cell has to be split further, which means moving to Unicode quadrant block characters.

This article explains how the new converter works. The entry point is on the Tools page: drop an image in, generate a preview, download the .ans file, then run cat filename.ans in a terminal that supports 24-bit truecolor.

1. Why four pixels cannot simply be packed into one character

An ANSI terminal cell normally carries one foreground colour and one background colour at a time. A Unicode quadrant character decides which quadrants of that cell show the foreground and which show the background, but it cannot give the upper-left, upper-right, lower-left and lower-right quadrants four independent colours.

So “quadrant full colour” works under a real constraint: every 2 x 2 pixel block can be compressed into at most two colours. The converter’s job is not to pretend nothing is lost, but to find the two-colour representation with the smallest error under that constraint.

2. How a quadrant character encodes 2 x 2 pixels

A character cell is treated as four positions: upper-left, upper-right, lower-left and lower-right. Each position belongs either to the foreground or to the background, which gives 16 combinations in total. The common characters include the space, upper half, lower half, left half, right half, diagonal blocks and the full block, for example ▘ ▝ ▀ ▖ ▌ ▞ ▛ ▗ ▚ ▐ ▜ ▄ ▙ ▟ █.

The converter first scales the source image onto a sampling grid sized for the target terminal width. If the output width is 180 terminal characters, the sampling grid is 360 pixels wide; every two horizontal and two vertical sample points combine into one terminal character. The height is computed automatically from the terminal font ratio, treating a terminal character as roughly 2:1 in height to width by default.

3. Choosing the foreground colour, background colour and character

For each 2 x 2 pixel block the converter enumerates all 16 quadrant masks. A given mask splits the four pixels into two groups: a foreground group and a background group. The foreground group takes its mean RGB as the foreground colour, the background group takes its mean RGB as the background colour, and the squared error between the four original pixels and the two representative colours is then computed.

The combination with the smallest error wins:

  1. Enumerate the 16 quadrant masks.
  2. Split the four sampled pixels into a foreground group and a background group according to the mask.
  3. Compute the mean RGB of each group.
  4. Compute the reconstruction error across the four pixels.
  5. Emit the Unicode character and the ANSI truecolor foreground/background pair with the smallest error.

This is finer than always using half-block characters, because it also preserves edge information in the horizontal direction. The cost is a larger file, and some terminal fonts render quadrant blocks less reliably than half blocks.

4. What is inside the generated .ans file

A .ans file is ordinary UTF-8 text that happens to contain ANSI escape sequences. Before each character the converter writes a control code such as ESC[38;2;R;G;B;48;2;R;G;Bm when needed, setting the foreground and background colours, and then writes one quadrant Unicode character. At the end of each line ESC[0m resets the style so the background colour does not bleed into the following shell prompt.

In terminals that support truecolor and Unicode block elements — macOS Terminal, iTerm2, Windows Terminal, GNOME Terminal and similar — you can run it directly:

cat image-quadrant-180x120-truecolor.ans

If the image is too wide, the terminal’s automatic line wrapping will break the picture. Either widen the terminal window or reduce the output width during conversion.

5. Why the tool page does not upload images to the server

Image conversion does not need a server. Browsers already decode the common image formats and can read scaled pixels through a Canvas. Running the conversion in the front end has three benefits:

  • Privacy is simpler: the image never leaves the user’s device.
  • Storage pressure is lower: the server stores no uploads and needs no scheduled cleanup of source images.
  • Feedback is faster: after dropping an image in you can preview it, adjust the width and regenerate immediately.

The page still applies a 30-minute expiry: the generated Blob download link, the preview HTML and the current image reference are released automatically within the page. A .ans file already downloaded to the user’s machine is unaffected.

6. Boundaries in the implementation

First, the browser can only handle the formats it can decode itself. PNG, JPEG, WebP, GIF, AVIF and SVG are usually fine, but HEIC, corrupted files and SVGs that reference external resources can fail.

Second, quadrant characters do not mean four times the resolution without loss. Each character still carries only a foreground and a background colour; complex texture, noise and high-frequency detail are compressed into two representative colours.

Third, the terminal font affects the result. A good font makes block elements sit flush against each other with no visible seams; if you see grid lines or uneven character widths, switch to a different monospace font or adjust the terminal line spacing.

7. Why this version suits detailed images better than half-block

The strength of half-block is that each character stores the colour of two stacked rows, which keeps colour reproduction stable. The strength of the quadrant version is that structure can appear in the horizontal direction within a single character, so hair, outlines, small highlights and diagonal edges come out clearer. For anime portraits, icons and illustrations with defined edges, quadrants usually preserve more shape information at the same terminal width.

If the goal is maximum compatibility, half-block is still a good choice. If the goal is as much detail as possible in a modern terminal with Unicode and truecolor support, quadrants plus minimum-error two-colour clustering is the better fit.

8. ANSI conversion strategies compared

Strategy Information per character Suited to Main limitation
Plain ASCII Approximates brightness through character density only, with no real colour. High-contrast black and white images, and cases with very strict terminal compatibility needs. Loses the most colour and fine edge detail.
Half-block truecolor One character stores two stacked sample points, each with its own colour. Photographs, gradients, and colour images that need broad compatibility. Weak horizontal structure; diagonals and small outlines thicken easily.
Quadrant truecolor One character covers 2 x 2 sample points, approximated by two minimum-error colours. Portraits, icons, illustrations and images with defined outlines. Each cell still has only a foreground and a background colour, not four independent quadrant colours.
Full image output Keeps the original pixels and lets an image viewer render them. Cases needing exact fidelity, printing or later processing. No longer plain terminal text, and cannot be embedded directly in command-line output.

9. Terminal compatibility checklist

After generating a .ans file, do not draw conclusions from the browser preview alone. The browser uses a Canvas and the page font, while a real terminal is also affected by its font, line height, colour configuration and line wrapping. A test record you can re-check should record at least the terminal name, font, font size, output column width, the composite background used for the image, and the exact command run.

Check Passing condition First thing to adjust on failure
Truecolor support Gradients and photographic colour areas have not degraded into a 256-colour approximation. Switch terminal, or confirm COLORTERM=truecolor.
Unicode block elements Quadrant characters render with no missing glyphs and no visible seams. Switch to a different monospace font, reduce line spacing, or fall back to half-block.
Output width A single line of ANSI content is not wrapped automatically by the terminal. Lower the conversion width, or widen the terminal window and test again.
Transparent background Transparent areas sit close to the terminal background and produce no odd border. Pick a composite colour close to the theme background and export again.

10. Practical suggestions

  • For a portrait or a tall image, try a width of 160 to 200 columns first.
  • If the terminal wraps lines, reduce the width rather than pushing for more detail.
  • For transparent PNGs, choose a composite colour close to the terminal background.
  • Complex photographs produce very large ANSI files; illustrations, icons and character portraits usually work better.

The full entry point is on the Tools page. The converter itself needs no account and no backend file storage; it simply puts image sampling, two-colour approximation and ANSI output into a single browser interface.

Leave a Reply

Scroll down