Skip to content

Image To Ascii

Decode a PNG, JPEG, GIF, or WebP locally and turn one still frame into bounded, copyable, downloadable ASCII art.

Privacy: your files never leave your device. All processing happens locally in your browser.

How to use

  1. 1.Choose one PNG, JPEG, GIF, or WebP file within the visible encoded and decoded limits.
  2. 2.Enter a whole output width from 10 through 200 characters and optionally reverse the fixed density ramp.
  3. 3.Generate the complete ASCII result, then copy the visible text or download the local TXT file.

About Image To Ascii

Image to ASCII converts the visible tones of one decoded bitmap into a grid of ordinary text characters. Choose a PNG, JPEG, GIF, or WebP image, set an output width from 10 through 200 characters, and generate a local preview plus a plain-text download. The fixed density ramp runs from @ through progressively lighter symbols to a space. Reverse mode flips that same ramp so light regions receive dense characters and dark regions receive sparse ones. This is visual ASCII art, not optical character recognition, transcription, captioning, or extraction of text already present in the image.

The browser must actually decode the file before conversion. A matching extension or MIME type only passes the initial format screen; malformed content and unsupported codec profiles still fail at decode time. createImageBitmap is used when available, and its ImageBitmap is closed on replacement, stale completion, or component unmount. If that decoder is unavailable for the file, a short-lived local Object URL loads an Image element and is revoked after load or failure. The fallback immediately snapshots the decoded frame to Canvas so an animated GIF does not continue changing while settings are edited.

Source dimensions are validated independently of output controls, so changing width while asynchronous decoding is in progress cannot make an old width decide whether the image is accepted. Encoded files may be at most 15 MiB. A decoded side may be at most 8,192 pixels, and decoded area may be at most 24 million pixels. Those limits protect the browser from unexpectedly large decoded memory even when a compressed file itself is small. Unsupported or over-limit images clear any previous ASCII and create no partial result.

Output rows preserve the source aspect ratio with an explicit character-cell correction. Ordinary monospace glyph cells are often roughly twice as tall as they are wide, so the row calculation multiplies image height divided by image width by output width and then by 0.5. The result is rounded to the nearest whole row with a minimum of one. This 1:2 assumption is a practical preview approximation, not a measurement of the user's eventual font. A different font, line height, terminal, editor, zoom, or letter spacing can make the downloaded art look taller or shorter.

The source frame is drawn into a small Canvas whose dimensions exactly match the planned ASCII columns and rows. The canvas is filled white first so transparent areas have a declared background. Browser high-quality image smoothing performs the resize, then getImageData returns one RGBA sample for each output character. Resampling quality is browser-implemented and can differ slightly across engines, especially for high-frequency patterns or very aggressive reductions. Golden tests therefore anchor the post-resize pixel-to-character algorithm rather than claiming every browser produces identical resampled pixels.

Each sampled sRGB channel is linearized with the W3C relative-luminance transfer function. Luminance is then calculated as 0.2126 red plus 0.7152 green plus 0.0722 blue. Alpha is composited over white before this formula. The resulting value from zero through one is multiplied by nine and rounded to choose one of ten ramp entries. Eight executable RGBA golden cases cover black, white, middle gray, all three sRGB primaries, full transparency, and half transparency. A 2 by 2 matrix additionally verifies row breaks, channel order, and reverse-ramp behavior.

Output is never silently shortened. The requested width must be a plain base-10 whole number with no sign, unit, whitespace, decimal point, leading zero form, or scientific notation. Width 10 and 200 are accepted; values outside that range fail instead of being clamped. The complete serialized output may contain at most 50,000 characters, including every newline separator between rows. Exact helper tests accept 50,000 and reject 50,001. Tall aspect ratios can exceed that budget even at an otherwise valid width, in which case the tool reports the limit and produces no preview or download.

Editing width, ramp direction, or source immediately revokes the old text download URL and clears the prior result, copy state, and error. Copy operations use generation and mounted-state guards so an older Clipboard promise cannot restore Copied after a later edit. Copy timers are identity-checked and canceled when replaced or unmounted. Download Object URLs are revoked on replacement and unmount. Source Object URLs exist only for fallback decoding and are also revoked on success, error, replacement, and unmount.

All decoding, Canvas work, luminance calculation, copying, and text download creation happen in the current browser tab. The image, pixels, generated text, and filename are not uploaded to Lizely. The TXT output contains only the ASCII characters and newline separators; it does not retain color, transparency, animation, metadata, camera information, layers, embedded profiles, or the original compressed image. Use a monospace font with a tight line height when displaying the result, and keep the original image when visual fidelity or archival information matters.

Methodology & sources

Validate one PNG, JPEG, GIF, or WebP by encoded size and real browser decode, then independently enforce 8,192-pixel sides and 24 million decoded pixels. Prefer createImageBitmap and close it on replacement, stale completion, or unmount; otherwise use a temporary revoked Object URL and snapshot the decoded still frame. Parse width as a strict integer from 10 through 200, compute rows as round(height/width × outputWidth × 0.5), calculate serialized size as width × rows plus rows − 1 newline characters, and reject total text above 50,000 without truncation. Draw onto a white, exact-output-size Canvas, read RGBA, composite alpha over white, linearize sRGB, calculate W3C relative luminance, and round luminance across the fixed ten-character ramp or its exact reverse. Copy and TXT Blob jobs use generation, timer-identity, mounted-state, and URL cleanup guards. Eight exact pixel goldens plus matrix and exact-limit tests cover formula, row serialization, reverse behavior, file, source-pixel, dimension, width, and output-character boundaries.

Frequently asked questions

Does this tool read text from an image?
No. It is not OCR. It maps resized pixel luminance to a fixed character ramp and does not recognize letters, words, objects, or meaning.
How is the output height calculated?
Rows are round(source height / source width × output width × 0.5), with at least one row. The 0.5 factor approximates a monospace cell that is about twice as tall as it is wide.
What happens to transparent pixels?
They are composited over white before relative luminance is calculated, so fully transparent regions map like white in the normal ramp.
Are my image and ASCII output uploaded?
No. Decoding, resizing, pixel reading, mapping, copying, and TXT creation all happen locally in the current browser tab.

Image Tools guides

View all