QR code encoding for the web
npm install @hazae41/visage"Visage" is a French noun meaning "face", elements are placed on specific places, and if something is slightly off, the whole face can't be recognized
- 100% TypeScript and ESM
- No external dependencies
- Rust-like patterns
const source = new Uint8Array(...)
const matrix = new QrEncoder("byte").encode(source)const source = new TextEncoder().encode("Hello world!")
const matrix = new QrEncoder("byte").encode(source)const matrix = new QrEncoder("alphanumeric").encode("HELLO WORLD 123")const matrix = new QrEncoder("numeric").encode("123456")const matrix = new QrEncoder("kanji").encode([...])Draw the matrix line by line using modulo two to convert bits into black or empty squares
const bitset = new Array(...matrix.array)
console.log()
for (let row = 0; row < matrix.width; row++)
console.log(bitset.slice(row * matrix.width, (row + 1) * matrix.width).map(b => b % 2 ? "██" : " ").join(""))
console.log()Something like this should be displayed
██████████████ ██ ██████████████
██ ██ ████ ████ ██ ██
██ ██████ ██ ████████ ██ ██████ ██
██ ██████ ██ ████ ██ ██████ ██
██ ██████ ██ ████ ████ ██ ██████ ██
██ ██ ██ ██ ██
██████████████ ██ ██ ██ ██████████████
██
██ ██████████████ ██ ██ ██ ██████
██ ████ ██ ████████ ████
██████████ ████████ ██████
██ ████ ██ ██████ ██ ████
██████ ████ ██████ ████ ██
██████ ██ ██ ██ ██
██████████████ ██ ██ ████████
██ ██ ██ ██ ████ ██ ██ ██
██ ██████ ██ ████████████ ██ ██
██ ██████ ██ ████ ██ ████
██ ██████ ██ ████ ████ ██████████
██ ██ ██████ ████ ████████
██████████████ ████ ██████
Create an image of width/height matrix.width, convert the bits to rgba using modulo two, and then put them on the image
const code = new OffscreenCanvas(matrix.width, matrix.width)
const rgba = new ImageData(matrix.width, matrix.width)
for (let i = 0; i < matrix.array.length; i++) {
rgba.data[i * 4 + 0] = matrix.array[i] % 2 ? 0 : 255
rgba.data[i * 4 + 1] = matrix.array[i] % 2 ? 0 : 255
rgba.data[i * 4 + 2] = matrix.array[i] % 2 ? 0 : 255
rgba.data[i * 4 + 3] = 255
}
code.getContext("2d").putImageData(rgba, 0, 0)Create a destination canvas of desired width/height, disable smoothing, and draw the image on the canvas
const canvas = document.createElement("canvas")
canvas.width = 300
canvas.height = 300
canvas.getContext("2d").imageSmoothingEnabled = false
canvas.getContext("2d").drawImage(code, 0, 0, matrix.width, matrix.width, 0, 0, canvas.width, canvas.width)
document.body.append(canvas)You can invert 0 and 255 in the rgba to invert colors for dark mode