Some Saturday mornings you do not want to be useful. You want to build something dumb. That is roughly the entire origin story of ascii.ondra-vlasek.cz: you drop in a photo, you pick a set of characters, and the tool spits the picture back out drawn entirely from those characters. ASCII art, but with masks you choose. No deadline, no client, no roadmap. Just a thing I wanted to see exist by lunch.
This is the build story. Not a tutorial, more a small love letter to throwaway tools and why I keep making them.
The itch
ASCII art is old as dirt and that is exactly why it is fun. Everyone has seen a photo turned into a wall of @#% symbols. The twist I wanted was control: let me feed in my own characters and have the image rebuilt from those shapes. Your initials. A single emoji. The word "ahoj" repeated forever. The picture is still recognizable, but it is wearing a costume made of whatever you handed it.
That is the kind of idea that is too small to plan and too fun to ignore. So I did not plan it. I opened an editor.
The technical bit, at altitude
The whole thing is embarrassingly simple, which is the point. Two ingredients do all the work:
- PIL (Pillow) for the image side. Open the photo, shrink it down to a sensible grid, read brightness per cell. Darker cells get denser characters, lighter cells get airier ones. The "mask" is just me mapping your chosen characters onto that brightness ramp instead of the usual fixed set. That is genuinely most of the magic: brightness in, character out.
- Gradio for the web UI. This is the part that turns a script into a thing other people can touch. I had a function that took an image and some text and returned a result. Gradio wraps that in an upload box, a text field and an output pane almost for free. I did not write a single line of HTML, CSS or JavaScript. I wrote a Python function and handed it to Gradio, and suddenly it was a web app.
That second point is the whole reason this got deployed instead of dying as a .py file in a folder. The distance between "works in my terminal" and "works in your browser" used to be a project. With Gradio it is an afternoon, and most of that afternoon is fiddling with character ramps, not plumbing.
Where the time actually went
The logic was the easy 80%. The fun, fiddly 20% was making the output look good instead of just correct:
- Aspect ratio. Characters are taller than they are wide, so a naive grid squishes your photo into a funhouse mirror. You have to cheat the vertical sampling to compensate. Obvious in hindsight, invisible until you see your own face stretched like taffy.
- Character order. If your mask characters are not sorted from "visually light" to "visually dark," the image turns to mush. A space and a
@are not the same weight, and the tool has to know that. Getting a pleasing ramp out of arbitrary user input was the actual puzzle. - Resolution sweet spot. Too few cells and it is unreadable abstract noise. Too many and it stops reading as ASCII and just looks like a slightly broken photo. There is a narrow band where it clicks, and you only find it by staring at outputs.
None of this is hard. All of it is the kind of thing you only catch by using the thing, which is exactly why I build first and theorize never.
Why bother with toys
Here is my honest pitch for small throwaway tools, the ones with no business case and no future.
They keep you fluent. A weekend toy is a low-stakes excuse to touch a library you have been meaning to try. I had not used Gradio in anger before this. Now I have shipped something with it, found its rough edges, and know exactly when I would reach for it again. That knowledge cost me one Saturday and zero risk. No production system, no on-call, nobody waiting on me.
They are also finishable, which most of my real work is not. Big projects live for months. A toy you can start and ship in a day, and that loop of "idea, build, done" is genuinely good for morale. It reminds you that shipping is a muscle, and tiny projects are how you keep it warm between the big lifts.
And honestly? It is just nice to make something useless and watch it work. I typed my name into a photo of a coffee cup and the cup came back written in my name. Nobody needed that. I grinned anyway.
Go break it
It is live at ascii.ondra-vlasek.cz. Throw a weird photo at it, feed it ridiculous characters, see what falls out. It is a toy. That is the whole point.
The bigger takeaway is the same one I keep landing on: the cost of building a small idea has quietly collapsed. So stop saving your dumb little ones for later. Open the editor. Build the thing. Worst case, you learned a library. Best case, a coffee cup says your name.