Image to ASCII Art
Turn any image into text-based ASCII art you can copy or download, with density ramps and the settings that decide whether it is readable.
Upload an image to start.
Why most ASCII art comes out stretched
A monospace character cell is roughly twice as tall as it is wide. So if you sample the source image in square blocks — one square block per character, which is the obvious thing to do — the result comes out about twice as tall as the original. This is the single most common defect in ASCII art converters, and it is pure arithmetic.
| Sampling a 400×400 image at 100 columns | Characters | Rendered shape |
|---|---|---|
| 4×4 pixel blocks (square) | 100 × 100 | 2× too tall |
| 4×8 pixel blocks (cell-shaped) | 100 × 50 | correct |
The fix is to make each sample block as many times taller than it is wide as the font's cell is. Two is the usual rule of thumb, but real monospace fonts vary, which is why art tuned for one terminal looks slightly squashed in another:
| Font | Cell height ÷ width | Error if you sample square |
|---|---|---|
| Rule of thumb | 2 | 2.00× too tall |
| Consolas | 1.64 | 1.64× too tall |
| Menlo | 1.66 | 1.66× too tall |
| Courier New | 1.67 | 1.67× too tall |
A ten-character ramp keeps four percent of the tones
The conventional density ramp is @%#*+=-:. — 10 characters, so the output
can express 10 brightness levels. The input has 256. That is a reduction
to under 4% of the tonal information, which is the real reason ASCII art needs
high-contrast source images: a photograph with subtle shading has essentially nothing left
after quantisation.
How you divide 256 values into 10 buckets is a genuine choice, and it is one most converters make without noticing they made it. Dividing the stored pixel values evenly and dividing the actual light evenly are different things, because sRGB is not proportional to light — and they disagree on 218 of the 256 possible values, 85% of every image.
| Pixel value | Share of the light | By value | By light |
|---|---|---|---|
| 0 | 0.0% | @ | @ |
| 32 | 1.4% | % | @ |
| 64 | 5.1% | # | @ |
| 96 | 11.7% | * | % |
| 128 | 21.6% | = | # |
| 160 | 35.2% | - | * |
| 192 | 52.7% | : | = |
| 224 | 74.5% | . | : |
| 255 | 100.0% | (space) | (space) |
Mid-grey is the clearest case. Value 128 sits exactly halfway along the scale and carries only
21.6% of the light, so it lands on
= one way and # the other.
Black and white agree under both schemes — it is the midtones that move, which is most of a
photograph.
Seen from the other side: dividing by value gives each character about 26 of the 256 values, near enough evenly. Dividing by light gives the darkest character 90 and the lightest only 12, because most of the numeric range represents very little actual light.
Neither is wrong exactly — it depends on whether you want the character density to track the stored numbers or the perceived brightness, and on how your terminal renders. The point is that it is a decision, and a converter that never considered it has made one anyway.
How to use
- Choose an image with strong contrast.
- Set the output width in characters.
- Adjust the character ramp and contrast.
- Copy the text, and use a monospaced font to display it.
Frequently asked questions
How does the conversion work?
The image is divided into a grid, each cell's average brightness is measured, and a character is chosen whose visual density matches — a space for the lightest areas, a dense character like a hash or an at-sign for the darkest. The result is a brightness map made of type.
Why does my output look wrong?
Usually the font. ASCII art only aligns in a monospaced font where every character is the same width, and a proportional font shears it into nonsense. The other common cause is character aspect ratio — text cells are taller than they are wide, so the image must be squashed vertically to compensate.
What images work best?
High contrast with a clear subject and a simple background. Portraits against plain backgrounds and bold graphic shapes convert well; busy scenes with subtle tonal variation turn to noise, because the character ramp has far fewer levels than the image does.
How wide should the output be?
Wide enough to carry the detail and narrow enough to display. Around 80 to 100 characters suits a terminal or a code block; much wider needs a large screen or a small font, and much narrower loses the subject entirely. It is the main quality control you have.
What is a density ramp?
The ordered set of characters from lightest to darkest that the converter draws from. A longer ramp gives more tonal steps and a smoother result; a short ramp gives a starker, more graphic look. Which characters read as dark depends on the font, so ramps are not universal.
What is it good for?
Terminal output, README files, email signatures, and the general pleasure of the form. It also has a genuine practical use in environments that can only display text, which is where the technique came from in the first place.
🔒 This tool runs entirely in your browser. Nothing you enter is uploaded, logged, or stored.