ascii cam
<div id="ascii_div"></div>
<script type="module">
// git camera stream, with options object
const stream = await navigator.mediaDevices.getUserMedia ({
audio: false,
video: true,
facingMode: `user`,
})
// get video tracks
const videoTracks = await stream.getVideoTracks ()
console.log (`Using video device: ${ videoTracks[0].label }`)
// make video html element
const video = document.createElement (`video`)
// assign stream to video source
video.srcObject = stream
await video.play ()
// make canvas html element
const cnv = document.createElement (`canvas`)
// small size
cnv.width = 64
// with aspect ratio from video html element
cnv.height = cnv.width * video.videoHeight / video.videoWidth
// grab the ascii div from DOM
const div = document.getElementById (`ascii_div`)
// set font to be monospace
div.style.fontFamily = `monospace`
// center aligned
div.style.textAlign = `center`
// get canvas context
const ctx = cnv.getContext (`2d`)
// string of characters from dark - bright
const chars = "¶Ñ@%&∆∑∫#Wߥ$£√?!†§ºªµ¢çø∂æåπ*™≤≥≈∞~,.…_¬“‘˚`˙"
// defining a function for animation
const draw_frame = async () => {
// tranformation save point
ctx.save ()
// flip horizontally
ctx.scale (-1, 1)
// draw image from video onto wrong side
ctx.drawImage (video, -cnv.width, 0, cnv.width, cnv.height)
// flip back
ctx.restore ()
// get pixel data
const pixels = await ctx.getImageData (0, 0, cnv.width, cnv.height).data
// start empty ascii string
let ascii_img = ``
for (let y = 0; y < cnv.height; y += 2) {
for (let x = 0; x < cnv.width; x++) {
// get pixel position
const i = (y * cnv.width + x) * 4
// get rgb values
const r = pixels[i]
const g = pixels[i + 1]
const b = pixels[i + 2]
// calculate brightness
const br = (r * g * b / 16581376) ** 0.1
// use brightness to select character
const char_i = Math.floor (br * chars.length)
// add character to ascii string
ascii_img += chars[char_i]
}
// new line
ascii_img += `\n`
}
// add ascii string to innerText of div
div.innerText = ascii_img
// wait and then call next frame
requestAnimationFrame (draw_frame)
}
// start recursive animation
draw_frame ()
</script>
Inspired by this p5 sketch.