The image is scaled down so each character cell covers a block of pixels, the block's brightness is measured, then mapped onto a ramp of characters from dense (@) to sparse (.). Character cells are about twice as tall as wide, which the converter compensates for automatically. In HTML color mode each character also keeps the average color of its block.
Every step runs in your browser with the Canvas API — your photos never leave your machine. Related: text to ascii art · ascii table