Image to ASCII Art
Turn any image into ASCII art — tune width, pick a character ramp, keep the colors. Every pixel stays in your browser.
Runs online in your browserNo installNo accountFree
How to use Image to ASCII Art
- Drop an image on the page or click "Choose image" — PNG, JPG, GIF, WebP, and SVG all work. The tool samples the bitmap (not the vector) for SVGs.
- Pick a width in columns — 80 looks like a classic terminal, 160 fills most wide screens, 200+ gives you photographic detail on big monitors.
- Pick a character ramp. Standard is a safe default; try Blocks or Pixel blocks for stylized looks, Detailed if you have the columns for it.
- Dial contrast up if your image looks muddy, or down if it looks cartoonish. Use brightness to rescue too-dark photos or over-exposed ones.
- Toggle Colored to paint each glyph in the average color of its region, or Plain for monochrome. Flip Invert for light-terminal output.
- Copy with "Copy text" for pure glyph output, or "Copy ANSI" in colored mode to get 24-bit ANSI escape codes ready to paste into a terminal.
Image to ASCII Art
A browser-side image → ASCII converter with tunable width, switchable character ramps, and full-color output. Drop a PNG, JPG, GIF, WebP, or SVG and watch it collapse into a character grid you can copy, paste, commit, or ship into a retro terminal. The image never leaves your tab — all downsampling, averaging, and ramp mapping happens on the client.
What ASCII art is, and why the ramp matters
ASCII art is a century-old typographic trick: pick a small alphabet of characters ordered by visual density, then replace regions of a source image with whichever character most closely matches the region's average brightness. The first modern implementations were teletype art in the 1960s, followed by BBS-era "ANSI art" in the 1980s and 90s, and then by the Linux tool aalib which shipped with everything from mplayer to links2 through the 2000s.
The art lives or dies on the character ramp. The classic Paul Bourke 10-character ramp — " .:-=+*#%@" — was reverse-engineered from real CRT measurements and is still the safe default today. Bourke also published a longer 70-character ramp (" .'",:;Il!i><~+_-?][}{1)(|/tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$"`) for high-fidelity renders, but you need at least 150-180 columns for the extra tones not to blur into noise. Each cell of the output gets quantized into one of these N characters, so more characters = more visible shading, but also more visual noise if the sampling resolution is too low.
The tool ships six ramps out of the box:
- Standard — 10 characters, a balanced Bourke-style ramp. Works everywhere.
- Detailed — 70 characters, for large canvases with photographic subjects.
- Blocks — 5 characters, strong silhouettes. Good for logos and single-subject photos.
- Pixel blocks — the Unicode
░▒▓█ramp. Nostalgic 8-bit games feel. - Matrix — 22 characters leaning toward vertical strokes — very terminal-y.
- Binary — just space and
@. Stark, stencil-like output for very bold subjects.
And a custom ramp slot: drop any string, dark → light, and the tool uses it as the look-up table.
Color, done right
"Colored ASCII" can mean two very different things, so this tool handles both:
- Colored for the browser — each cell's glyph is drawn in the average RGB of the region it covers, wrapped in
<span style="color: rgb(…)">. The output is a single<pre>with per-color runs collapsed into one span, so a 200-column render is still fewer than 10k DOM nodes and scrolls without jank. - Colored for the terminal — the same grid serialized as 24-bit ANSI foreground escapes (
\x1b[38;2;R;G;Bm). Paste that into iTerm2, Alacritty, WezTerm, Windows Terminal, or GNOME Terminal and you get a true-color rendering of the image in the shell. Every line ends with a reset (\x1b[0m) so partial output never leaks color state to the next prompt.
Transparent pixels (alpha < 8) map to a literal space and emit no color escape, so PNGs with cut-out backgrounds don't leak a dark blob where "nothing" should be.
Width, aspect, and why your output looks stretched
Monospace glyphs are not square. At normal line-heights a typical monospace character is about 0.5 to 0.55 as wide as it is tall. If you naively sample the image at width × width cells, rows compress 2× vertically and your picture ends up short and fat. The tool exposes a "Glyph aspect" slider (0.35-0.8) so you can dial this in for your particular rendering surface — 0.5 is a safe default for most browser monospace stacks, 0.65 is about right for Windows Terminal at default settings, and 0.4 works well for tmux at tight line-heights. You'll know you have it right when a circular subject stays circular in the output.
Width itself trades fidelity for line length. 80 columns is retro-terminal small; 120-160 fits most code editors and GitHub READMEs; 200+ is photograph-quality but won't wrap on phones. The tool caps at 300 columns because past that the glyphs stop being readable at any sensible zoom level — they're essentially subpixels of the image.
Contrast, brightness, and the gamma story
Real photos rarely use their full 0-255 luminance range. Indoor shots cluster in the 0.3-0.7 zone; outdoor shots skew bright. The ramp then bunches up in the middle of the range, which is why an un-tuned conversion looks muddy. The brightness slider shifts the mean luminance ± 0.4 before mapping, and the contrast slider (0.3 to 2.5) stretches the range around the 0.5 midpoint — exactly like the "Curves" tool in image editors but applied before ramp quantization rather than after.
There's no gamma correction knob because browsers decode to sRGB and Rec. 709 luminance already accounts for that. If you want a hand-tuned starting point for photographs, try contrast 1.4 + brightness -0.05; for screenshots of dark code try contrast 1.0 + brightness +0.1 and the Invert toggle.
Typical uses
- GitHub READMEs — embed a stylized ASCII logo in a fenced code block. Use the Blocks or Pixel blocks ramp + width 60 for something that renders fine on mobile.
- Terminal MOTD — drop the "Copy ANSI" output into
/etc/motdor your shell profile. Works great for monorepo welcome banners. - Commit messages — the Binary or Blocks ramp at width 40 makes a compact silhouette that survives
git log --onelinetruncation. - Signature files — Usenet-era style. Pick the Standard ramp, width 50, height ~10 rows, and you have a modern sigline.
- Pranking a junior dev — paste an animated-GIF frame into their terminal with a huge ANSI render. They'll ask how it works and you can say "oh you know, just a bit of linear algebra."
Privacy
The file picker reads your image with the browser's native FileReader, decodes it via the standard Image object, renders into an offscreen <canvas>, and downsamples to a 800×800-max buffer for the ramp math. Nothing is uploaded. The sample canvas, the pixel buffer, and the ASCII string all live in this page's JavaScript heap and are garbage-collected the moment you pick a new image or close the tab. There is no telemetry on what you convert, no thumbnail cache, and no "recent images" list. The only data we keep is an aggregate page-view count in Google Analytics (cookie-less by default, honoring Do Not Track / Global Privacy Control) — see the privacy page for the full breakdown.
Frequently asked questions
How does image-to-ASCII conversion actually work?
The tool downsamples your image into a grid — one character cell per region — and replaces each cell with a glyph whose visual density matches the cell's average brightness. Brightness is computed with the Rec. 709 luminance formula (0.2126·R + 0.7152·G + 0.0722·B), which matches how modern displays read perceived brightness. A character ramp like ` .:-=+*#%@` is the look-up table: dark regions get the sparse glyphs on the left, bright regions get the dense glyphs on the right. The result is a text-only mosaic that preserves the shape, contrast, and (in colored mode) the average RGB of the source.
What character ramp should I pick for my image?
Pick by how much detail you want and how big the canvas is. Standard (10 characters) is the safe default and works from 60-column ASCII up to 200+. Detailed (70 characters) shows subtle shading but only starts looking right at 180+ columns — below that the extra tones smear into noise. Blocks (5 characters) lean into stark silhouettes, so they work great for logos and high-contrast subjects. Pixel blocks (the Unicode ░▒▓█ ramp) give an 8-bit-games feel, especially paired with colored mode. Binary is just space and `@` — pure stencil art. For a light-background terminal, toggle the Invert option so heavy glyphs map to dark regions the way you'd expect.
How does colored ASCII work and where can I use it?
Colored mode averages the RGB of each cell and paints the chosen glyph in that color. In the browser we render as a `<pre>` with one `<span>` per color run — copy the 'Copy text' button output to get the glyphs without colors, or 'Copy ANSI' to get 24-bit ANSI escape codes that every modern terminal (iTerm2, Alacritty, WezTerm, Windows Terminal) renders as true color. Paste the ANSI string into your terminal and your cat photo lives in your shell. The ANSI output is also valid input for `echo -e` and most tmux / screen configs that have `term-256color` or better enabled.
Is my image uploaded to your server?
No. The picker reads the file via `FileReader` on the client, decodes it with the browser's native image codec, samples it into an offscreen `<canvas>`, and converts it to ASCII entirely on your machine. There is no backend for this tool — the only network request your browser makes for this page is the initial HTML and JavaScript bundle. If you are handling sensitive imagery (medical, identification, proprietary artwork) this is the right property: `view-source` this page to confirm there is no fetch / XHR / websocket call that touches your pixels.
Related tools
Data URL Parser & Builder
Parse, build, and inspect RFC 2397 data URLs — inline images, fonts, and text in your browser.
Color Converter
Convert a color between HEX, RGB, HSL, HSV, CMYK, OKLCH — with WCAG contrast and live swatches.
Base64 Encode / Decode
Encode and decode Base64 strings in your browser — UTF-8 safe, privately.