Skip to content
Photo2Pattern

Free photo to ASCII converter

Photo to ASCII with the cell shape measured

This converter reads a photograph, resolves it onto a grid 40 to 200 columns wide and writes it out as characters — with the two things a photograph needs and a logo does not. The character cell is measured rather than assumed, so a face keeps its proportions instead of arriving a third too tall, and the tonal range is stretched or equalized so the ramp fills up instead of reaching a third of its levels. Color is optional and comes as ANSI escapes at 24-bit or 256, or as an HTML block. Free, no account, and the whole chain from decoding the file to assembling the escape sequences happens on your own machine.

  • 100% free
  • No signup
  • 40 to 200 columns
  • 3 tone mappings
  • 24-bit and 256-color ANSI

Press Ctrl+V anywhere on the page to drop in a photograph you copied from a gallery or a chat — no need to click the field first.

40 to 200. The row count is not yours to set — it comes out of the column count, the shape of the photograph and the cell ratio below, which is the only way a face keeps its proportions.

Measuring this browser's monospace advance and its normal line-height. Until that lands the list is computed from a 0.60 em advance.

Ten steps of plain 7-bit ASCII. The safest choice for anything that gets pasted rather than saved, and the one whose banding a photograph shows first — a gradient sky crosses ten hard edges.

% of cells clipped at each end of the scale

The darkest 2% of cells all become the densest glyph and the lightest 2% all become the blank, and everything between is stretched over the full ramp. This is what a photo editor calls auto levels.

Seven or eight distinguishable steps of density, and it pastes anywhere at all. Everything below adds color at the cost of a destination that has to understand it.

On a dark surface the glyph is the light, so the brightest part of the photograph gets the densest character. Transparency is flattened onto black.

How to get a photograph to survive as text

Geometry first, tone second, color last — in that order, because each one constrains the next.

  1. Say where the text is going, before anything else

    The cell ratio is the only setting that can ruin a conversion no matter how good everything else is, and it depends entirely on the destination. A terminal set solid and a blog template at 1.45 leading differ by a third, which is the difference between a face and a face pulled downward. Pick the entry that matches where you will paste it — the list is computed from this browser's own monospace advance, measured to three decimals — or type the ratio if you already know it. Get this right and the row count follows automatically.

  2. Stretch the tone until the histogram stops being a spike

    The bars under the result are the lightness of every cell before mapping. A photograph almost always shows one narrow hump rather than a spread, which is why straight-through conversion reaches four or five glyph levels out of ten and returns an even wash of the same two characters. Switch to the stretched mapping and the darkest and lightest few percent are pushed to the ends of the ramp and everything between is spread across it. Raise the clip figure for a hazy photograph and lower it for one that already has real blacks; the levels-reached count beside it says whether it worked.

  3. Choose a color format the destination can actually read

    Plain glyphs paste anywhere and carry about seven distinguishable steps. 24-bit ANSI carries the photograph's own colors and works in every terminal built since roughly 2016, at the cost of up to nineteen bytes an escape. 256-color ANSI snaps each cell to one of the 240 xterm entries that have a defined value, which halves the size and works further back. The HTML block is for a web page and needs no stylesheet. Whichever you pick, the byte cost of the color is printed beside the plain size so you know what you are pasting.

Technical specifications

Columns, and the depth that follows40 to 200 columns, 120 by default. Rows are the column count multiplied by the source proportions and by the cell ratio, rounded to a whole row — never a control of its own
Where the cell ratio comes fromThe monospace advance measured on a canvas in this browser's own face, and line-height: normal measured off a two-line box in the document, divided by a leading of 1.00, normal or 1.45 — or any figure from 0.20 to 1.50 typed in
Tone mappings3 — straight through, stretched between percentiles with a clip of 0 to 20% at each end, and rank equalization over a 256-bin histogram
Glyph ramps supplied3, chosen for tonal spacing rather than for looks: 10 ASCII levels, 70 ASCII levels, and the 5 Unicode shade blocks whose coverage is defined at quarter steps
Color formats4 — plain glyphs, ANSI 24-bit, ANSI 256 and an HTML pre block with inline hex spans and no stylesheet dependency
The 256-color palette240 entries generated from their own arithmetic: a 6x6x6 cube on 0, 95, 135, 175, 215 and 255, plus 24 grays at 8 + 10n. Matching is Oklab, the same search the bead and floss pages use
Escape economyOne escape per run of same-colored cells rather than one per cell, and a single reset at every line end. Line ends are not trimmed, so a column count is also a line length
UploadsNone. The file is decoded by createImageBitmap in this tab, and the escape sequences are assembled in the same place

Frequently asked questions

How do I work out the right cell ratio for where I am pasting?

Divide the font's advance width by its line-height, both in em. A monospace advance is usually near 0.60 em, so a terminal set solid gives about 0.60, a browser pre element left at line-height normal gives about 0.50, and a page styled at 1.45 leading gives about 0.41 — and the list on this page computes exactly those three from a live measurement of the face your browser is using rather than from the round numbers. If the destination uses a different font, the quickest check is to convert once, paste, and see whether a circle in the picture came out as an oval: taller than wide means the ratio you used was too high.

Why does my photograph come back as an even wash of two or three characters?

Because its lightness is bunched and you converted straight through. A typical photograph puts most of its cells inside about a third of the scale — no true black, no true white — so a mapping that reads lightness at face value indexes into a third of the ramp and never touches the rest. The histogram under the result shows this as a single narrow hump. Switching to the stretched mapping fixes it by putting the black point at the low percentile and the white point at the high one; the levels-reached figure tells you how much of the ramp you recovered, and on a flat photograph it typically goes from four levels to all ten.

Will the ANSI escapes work in my terminal?

24-bit escapes work in essentially every terminal released since the mid-2010s, and 256-color escapes work considerably further back. The failure mode when they do not is unmistakable and harmless: the escape sequences print as visible text, so you get lines beginning with a bracket and a run of semicolons rather than a colored picture. If that happens, drop to the 256-color mode first and to plain glyphs second. Piping the file through anything that strips control characters — a chat box, a form field, most bug trackers — also removes the color and leaves the glyphs intact.

Why does the 256-color mode not use indices 0 to 15?

Because those sixteen have no fixed color. The first eight are the original terminal colors and the next eight their bright variants, and what they actually paint is whatever the terminal's own theme sets them to — the same escape gives one red in a Solarized profile and a different red in Dracula. Matching a photograph against them would be matching against a color that cannot be known in advance. The 240 that remain are defined by arithmetic rather than by taste: a 6x6x6 cube on the levels 0, 95, 135, 175, 215 and 255, and 24 grays at 8 plus 10 times the step.

What does equalization do that stretching does not?

Stretching moves the two ends of the range; equalization redistributes everything in between. It places each cell by its rank rather than by its value, so every glyph level ends up with roughly the same number of cells whatever shape the original histogram had. That rescues a photograph so flat that even a stretch leaves it bunched, and it does one thing you have to watch for: a large area of nearly uniform tone — a clear sky, a studio backdrop, a wall — gets its tiny variations pulled apart into visible banding, because the ranking has no way to know those differences were noise.

How much bigger does the file get with color turned on?

Between three and eight times, depending on the mode and how busy the picture is. Every run of cells that share a color costs one escape — up to nineteen bytes at 24-bit, up to eleven at 256 — and a photograph changes color often enough that runs are short, so the escapes outweigh the glyphs by a wide margin. Emitting one escape per run rather than one per character is what keeps it to that; the naive form is worse again. The exact figure for your picture is printed under the result as the difference between the glyph-only size and the size of what the copy button hands over.

About the two ways a photograph fails as text

The first failure is geometry, and it is the one people notice without being able to name it: the picture is right but the face is long. A character cell is not square. Monospace faces set an advance near 0.60 em and the software around them adds leading, so a cell ends up roughly twice as tall as it is wide — and every converter that keeps the source aspect ratio without dividing by that produces a portrait stretched vertically by a factor of two. The usual fix is to hardcode 0.50 and hope, which is right for a terminal set solid and wrong by a third for a page at 1.45 leading. This page measures instead: the advance comes off a canvas in the face your browser actually loaded, the resolved value of line-height normal comes off a two-line box in the document, and the presets are those two numbers divided by the leading you are pasting into.

The second failure is tonal, and it is why so many photographs come back looking like noise. Glyph density is a scale of about seven usable steps to the eye, and a photograph does not arrive spread across the range it is given: most cells sit in a narrow band with no true black and no true white, so a mapping that takes lightness at face value uses a third of the ramp and leaves the rest untouched. The histogram under the result is there so you can see the hump rather than guess at it. Stretching between percentiles is the same operation a photo editor calls auto levels; equalization goes further and places each cell by rank, which rescues the flattest images and exaggerates grain in anything uniform. That trade — more separation in exchange for noise promoted to detail — is exactly the trade posterizing an image makes when it flattens tones to a fixed number of levels, and it is worth trying both when the picture is stubborn.

What stays constant underneath is the same machinery every page here runs on. Cells are averaged in linear light rather than in sRGB bytes, because averaging encoded bytes darkens edges; the number that indexes the ramp is Oklab lightness, where 0.5 genuinely reads as halfway; and the 256-color mode snaps each cell with the same Oklab search that the Perler bead page uses to pick a bead — the only difference being that a terminal index is defined by arithmetic and a bead is defined by a factory. If you want the ramp itself to be the thing you argue with, rather than the geometry and the tone, the ASCII art generator exposes the character set, measures the ink each glyph puts down and lets you type your own.

Product and company names shown here are the trademarks of their respective owners. Photo2Pattern is an independent tool and is not affiliated with, sponsored by or endorsed by any of them.

Where the photograph turns into glyphs

Your picture is opened by JavaScript running in the tab you are reading this in. It is never uploaded, never sent to a server and never stored anywhere — there is no upload step to undo, because there is no upload. Close the tab and nothing of it remains.

The escape sequences are assembled here too. Nothing about the picture — not its colors, not its dimensions, not the file name the download is built from — is reported anywhere, and the copy button writes to your clipboard rather than through anything.