Image to ASCII Art Converter

Turn any photo into character-based ASCII art with a live monospace preview. Free, fast, and your files never leave your device.

Drop an image here or click to choose a file

JPG, PNG or WebP.

Your ASCII art will appear here after you click "Convert to ASCII".

Luminance in, characters out

The conversion is simple enough to describe completely. Your image is drawn onto a hidden canvas that has been shrunk to exactly the number of columns you asked for. Each pixel of that shrunken canvas becomes one character.

For every pixel, the red, green and blue channels are collapsed into a single brightness value using the standard luminance weighting: 0.299 R + 0.587 G + 0.114 B. Those coefficients are not arbitrary. The eye is far more sensitive to green than to blue, so a pure green pixel reads as much lighter than a pure blue one of the same numeric value. Averaging the three channels equally would make blue skies and green foliage come out at the wrong tone entirely.

That brightness, now a number from 0 to 1, indexes into a ten step ramp:

@ % # * + = - : . (space)

The ramp is ordered by ink coverage. An @ fills most of its character cell, a full stop fills almost none, and a space fills nothing.

Why the default looks right on black and wrong on white

The preview here sits on a black panel with pale grey text, and the mapping is built for exactly that. Bright pixels get the densest characters, dark pixels get spaces. On a black background a space stays black and a dense @ glows pale, so the light and dark of the original are reproduced correctly.

Paste that same text into a white document and it flips: the areas that should be bright are now covered in dark ink and the shadows are blank white. That is what the "Invert brightness" toggle is for. Turn it on when the destination has a light background, such as a wiki page, a Word document or a printed page. Leave it off for a terminal, a dark themed code block, or anywhere with a dark background.

Characters are taller than they are wide

A monospace character cell is roughly twice as tall as it is wide. In Consolas at 8 pixels, a cell is about 4.4 pixels across and 8 pixels down. If you mapped one pixel to one character with no correction, every result would come out stretched to about double height, and faces would look like they had been pulled downwards.

To fix that, the row count is multiplied by 0.55 before sampling. So a 100 column render of a square image produces 55 rows, not 100. The 0.55 figure is a compromise that suits most common monospace fonts. If you paste into a font with unusually tight or loose line spacing, the proportions will drift slightly, and adjusting your line-height towards 1.0 usually brings it back.

Working through the numbers

Take a 1600 by 1200 photo and set the width slider to 100.

The scale factor is 100 divided by 1600, which is 0.0625. Rows come out as 1200 times 0.0625 times 0.55, rounded, which is 41. So the canvas is sampled at 100 by 41, giving 4,100 characters plus 41 line breaks. That file is about 4 KB.

Push the slider to 200 and you get 200 by 83, roughly 16,600 characters and about 16 KB. Four times the detail costs four times the size, and at 200 columns the text will overflow a standard 80 column terminal and wrap into an unreadable mess.

Picking a width

The slider runs from 40 to 200 and starts at 100. As a rough guide: 40 to 60 columns suits a signature block or a code comment and reduces a face to a suggestion. 80 columns is the classic terminal width and fits most places without wrapping. 100 to 120 is the sweet spot for recognisable portraits. 150 and above is for posters and wallpapers where nobody needs to read the file in a fixed width window.

High contrast, simple subjects survive downsampling far better than busy ones. A silhouette, a logo, a face on a plain background, or a pet against a wall will all read clearly at 80 columns. A crowd scene or a detailed landscape turns to noise because each character has to represent thousands of original pixels.

If your subject is lost in a busy background, run the image through Remove Background or Crop Image first. Tightening the crop onto the subject does more for legibility than any slider here.

Colour mode and the copying catch

Tick "Color mode (HTML)" and every character is wrapped in a span carrying the exact RGB of the pixel it came from, which renders as a tinted, photo-like block of text in the preview.

Be aware of one thing: the "Copy text" button and the .txt download always give you the plain, uncoloured version. That is deliberate, because a .txt file cannot hold colour. To keep the colours, select the art in the preview with your mouse and copy that selection, then paste into something that accepts rich text or HTML.

Related tools

For pixel-level effects that stay as images rather than text, try Pixelate Image. To sample the exact colours out of a photo before building a matching theme, use Colour Picker from Image. Everything runs in your browser, so your files never leave your device. Nothing is uploaded, not even in colour mode.

Questions about the ASCII output

Which formats can I drop in?

PNG, JPG and WebP. Other types are rejected with a message. Animated GIFs are not supported, and HEIC needs converting first.

Why does my art look like a negative?

The default mapping assumes a dark background. If you are pasting onto white, tick "Invert brightness" and the light and dark swap over to suit.

Why does it look stretched or squashed after pasting?

The row count is calculated for a character cell roughly twice as tall as it is wide. If the destination applies extra line spacing, the art stretches vertically. Setting line-height to 1 in a code block or CSS usually fixes it.

Can I paste it into a chat app or forum?

Only inside a code block or anywhere else that uses a fixed width font. In a proportional font the letters have different widths and every row ends up a different length, which destroys the picture.

Does a huge photo slow it down?

Barely. The image is scaled down to your chosen column count before any pixels are read, so a 6000 pixel wide photo at 100 columns does the same amount of ramp work as a 600 pixel one.