/TOOL · PHOTO TO ASCII ART
Drop a photo, a picture or any image and it comes back as ASCII art: characters on a flat background, nothing showing through, real text you can select and copy. Set the width, ramp, contrast and character colour, then copy it or download it as .txt or PNG.
Nothing is uploaded. The image is decoded and sampled by a canvas inside this page, so it never leaves your device. Load the page, disconnect from the network, and the converter still works. For per pixel colour taken from the photo, plus video, dither, halftone, pixel art and voxel, open the full ASCII Magic studio.
/HOW TO USE IT
The whole thing takes under a minute, and the only setting most people ever change is the width.
Drag a photo onto the converter, click Choose image, or paste one from the clipboard. It is decoded in the page, nothing is uploaded.
Choose how many characters wide the output should be. Eighty to one hundred and twenty suits most uses, and the height follows the aspect ratio of the image.
Pick a character ramp, push contrast up if the result looks flat, choose a character colour, and set the background to black, white or transparent so the polarity matches where the art is going.
Copy the ASCII as text, download it as a .txt file, or export it as a PNG.
/THE RAMP
The converter never looks at your picture as a picture. It lays a grid over it, one cell per character, and asks a single question of each cell: how bright is it, on a scale from black to white. That one number decides which character gets printed there.
Brightness is not the average of red, green and blue. Human vision weights green far more heavily than blue, so the standard luminance formula does the work instead: 0.2126 of the red channel, 0.7152 of the green, 0.0722 of the blue. A saturated green square and a saturated blue square with the same numeric value read as very different brightnesses to the eye, and averaging the channels would flatten them into the same character.
The character ramp is an ordered list sorted by how much of its cell each character fills. @ covers nearly the whole cell. % and # cover slightly less. + and = sit around the middle. : and . are almost nothing, and a space is nothing at all. Feed a brightness in, read a character out, print it, move to the next cell. That is the entire algorithm, and it has not changed since people were doing it on line printers in the 1960s.
The mapping flips depending on where the text is going to sit. As black text on white paper, the darkest part of the photo needs the heaviest character. As light text on a black background, the characters are the light, so the brightest part of the photo needs the heaviest character and the shadows need spaces. The background control above performs that flip for you, which is why black-background output pasted into a white document comes out looking like a negative. Switch the background to White before you copy, or use Invert if the negative is the point.
Ramp length is a taste decision more than a quality one. The seventy character ramp gives the smoothest gradients on paper and mush in practice, because so many of its characters are visually alike at small sizes. Ten levels reads as cleaner and more deliberate. Four levels turns a photograph into something closer to a poster print. Contrast usually matters more than ramp length: most photographs live in the middle of the brightness range, so pushing contrast up spreads them across more of the ramp and the result stops looking flat and grey.
| Ramp | Characters | Levels | Best for |
|---|---|---|---|
| Standard | @%#*+=-:. | 10 | Photographs, portraits, the safe default |
| Detailed | $@B%8&WM#*oahkbdpq… | 70 | Large output where the extra steps are visible |
| Blocks | █▓▒░ | 5 | Logos, silhouettes, anything that needs even weight |
| Terminal | @#o=-. | 7 | README banners and CLI splash screens |
| Minimal | #+. | 4 | Poster prints and hard graphic looks |
| Binary | 10 | 3 | The code-rain look, high contrast sources only |
/CHARACTER COLOUR
The Character colour control sets one colour for every character in the output. It is a single flat colour, not per pixel colour sampled from the photo, and that distinction is the whole design of this page: one colour keeps the result real selectable text rather than a picture of text.
Auto is the default and the safest choice, because it follows the background. On a black ground the characters come out white, on a white ground they come out black, so the art stays legible whichever way you flip the polarity. Change the background and Auto changes with it, which is one fewer thing to get wrong before you export.
The presets exist for the looks people actually ask for. Terminal green and amber are the phosphor colours of a CRT monitor and read as retro instantly, which is why they suit a CLI splash screen or a landing page hero. Cyan and magenta sit at the two ends of the synthwave palette and hold up well at small sizes because both are bright. Mint is the accent used across ASCII Magic. Black and white are there for when Auto is not what you want, usually because you are exporting a PNG that will sit on a background you have not chosen yet.
Custom takes any hex value, either from the swatch picker or by typing it into the field beside it. The two stay in sync, so you can paste a brand hex straight in. Anything you type in the three digit shorthand is expanded, and anything that is not a valid colour is ignored rather than applied, so the output never goes blank while you are half way through typing.
The one thing worth watching is contrast against the background. A dark colour on a black ground, or a pale one on white, produces output that is technically correct and completely unreadable. The converter checks the brightness distance between your colour and the ground and warns you under the control when the two are too close, but it does not stop you, because low contrast art on a transparent background is a legitimate thing to want.
Colour applies to the preview and to the PNG export, and it does not apply to the copied text or the .txt file. That is not a limitation of the tool, it is what plain text is: a .txt file stores characters and nothing else, so the art takes whatever colour the thing displaying it uses. If you need coloured characters in a document, paste the text and then set the text colour there, or wrap it in a <pre> element with a color rule. If you need the colour to travel with the art, export the PNG.
/MONOSPACE
ASCII art is a grid, and the grid is the only thing holding the picture together. Every character is assumed to occupy exactly the same width as every other one.
In a proportional font, i is roughly a third the width of M. A row full of thin characters comes out short, a row full of wide ones comes out long, and the picture shears apart line by line into noise. Nothing is wrong with the conversion when that happens. The font is wrong.
That is why a paste which looked perfect in the preview can fall apart the moment it lands somewhere else. Anywhere the text renders monospaced is safe: a terminal, a code block, a GitHub README inside a fence, a Discord or Slack message wrapped in triple backticks, a code comment, a plain text file, a CSS pre element. Anywhere the text renders in a normal interface font is not: a social post, an email body, a word processor document, a form field, a chat message without a code block. If the destination cannot be made monospaced, export the PNG instead and paste an image.
Line height matters just as much as character width. A monospaced character cell is roughly twice as tall as it is wide, so this converter samples about twice as many pixels vertically as horizontally for every cell to compensate. Get that ratio wrong and the output is a squashed or stretched version of the original, which is the single most common reason converted photos look subtly off. If you paste into a container with unusually tight or loose line spacing, the art will stretch to match, and the fix is the container's line height, not the conversion.
/WIDTH
Width is the only setting that changes the resolution of the result. Everything else changes its look. It is measured in characters rather than pixels, and it is the number of columns across, so the height follows from the aspect ratio of your image and you never set it yourself.
Under about 60 columns, only silhouettes survive. Faces stop being recognisable, logos lose their counters, and text inside the image is gone. That range is right for a small badge, a signature or an avatar, and wrong for anything with detail worth keeping.
Between 80 and 120 columns is where most output should live. Eighty is the width of a classic terminal and still the wrap column in plenty of code editors, so 80 columns drops into a README or a source file without wrapping. One hundred to one hundred and twenty is the comfortable maximum for something a person will read on a laptop screen.
Above 200 columns you are producing an image rather than text. It will not fit any normal text container, it wraps the instant it lands somewhere narrower, and it is really only useful when the destination is the PNG export or a print. Detail does keep improving up there, so if the plan is a poster, go wide and export the PNG.
The other constraint is the source. A conversion cannot invent detail that is not in the photo. Three hundred columns from a 200 pixel wide thumbnail just gives you a blurry thumbnail rendered in characters, at great length. Start from the largest version of the image you have.
/SOURCE IMAGES
Character art has one channel: brightness. You pick the colour the characters are drawn in, but the photo's own colours are gone, and with them everything you were relying on colour to communicate. That makes the choice of source image most of the work.
High contrast subjects survive. A face lit hard from one side, a silhouette against a bright sky, a logo, a building, a single object on a plain ground, anything whose shape already reads in black and white. Picture the photo in greyscale first, and if it still reads then, it will convert.
Busy subjects do not. Foliage, crowds, patterned fabric and fine repeating texture all collapse into an even grey mush, because every cell averages out to roughly the same value and the ramp has nothing left to distinguish. If you must convert something busy, raise the contrast hard and drop to a four or five level ramp so the mid tones are forced to pick a side.
Tight crops beat wide shots. A grid of 100 columns spends all 100 of them on whatever is in the frame, so a portrait cropped to the head keeps far more of the face than the same portrait at full length. Crop before you convert, not after.
The photo's tones are bunched in the middle of the range, so most cells land on the same few characters.
FixRaise Contrast to 150 or more, then nudge Brightness to keep the highlights from clipping to spaces.
The polarity is set for the other background. Light-on-black output looks inverted on a white page and the other way round.
FixSwitch Background to match where the text is going, or tick Invert to flip it back.
The destination is rendering the output in a proportional font, so every row is a different length.
FixWrap it in a code block or triple backticks, or use the PNG export instead of the text.
Too few columns for the amount of detail, or a source image that was busy to begin with.
FixCrop tighter, raise the width to 120 or more, and switch to the Standard or Detailed ramp.
/FAQ
/DO MORE WITH ASCII MAGIC
The studio behind this page keeps the colour, takes video as well as stills, and adds dither, halftone, pixel art, mosaic, LEGO and voxel on top. Export PNG, GIF or MP4, all in the browser.
Open the editor →/RELATED
This page converts one still image into plain text. To turn a word into a large banner, use the text to ASCII generator. For colour, video and the other 13 style engines, open the full studio, or browse all the tools.