/* Blurhash toolkit. base83 decoder/encoder is copied from https://github.com/woltapp/blurhash/blob/master/TypeScript/src/base83.ts, which is MIT Licensed: https://github.com/woltapp/blurhash?tab=MIT-1-ov-file#readme */ const digitCharacters = [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "#", "$", "%", "*", "+", ",", "-", ".", ":", ";", "=", "?", "@", "[", "]", "^", "_", "{", "|", "}", "~", ]; function decode83(str: string) { let value = 0; for (let i = 0; i < str.length; i++) { const c = str[i]; const digit = digitCharacters.indexOf(c); value = value * 83 + digit; } return value; } function encode83(n: number, length: number): string { var result = ""; for (let i = 1; i <= length; i++) { let digit = (Math.floor(n) / Math.pow(83, length - i)) % 83; result += digitCharacters[Math.floor(digit)]; } return result; } /* toColorHex() is modified from https://www.xaymar.com/articles/2020/12/08/fastest-uint8array-to-hex-string-conversion-in-javascript/, licensed BSD-3. */ // Pre-Init const LUT_HEX_4b = [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", ]; const LUT_HEX_8b = new Array(0x100); for (let n = 0; n < 0x100; n++) { LUT_HEX_8b[n] = `${LUT_HEX_4b[(n >>> 4) & 0xf]}${LUT_HEX_4b[n & 0xf]}`; } // End Pre-Init function toColorHex(buffer: Uint8ClampedArray): `#${string}` { let out = "#"; for (let idx = 0, edx = buffer.length; idx < edx; idx++) { out += LUT_HEX_8b[buffer[idx]]; } return out as `#${string}`; } export function averageColor(blurhash: string) { const v = decode83(blurhash.substring(2, 6)); // 24-bit RGB return [v >> 16, (v >> 8) & 255, v & 255] as const; } export function averageColorHex(blurhash: string) : `#${string}` { const [r, g, b] = averageColor(blurhash); const buf = new Uint8ClampedArray(3); buf[0] = r; buf[1] = g; buf[2] = b; return toColorHex(buf); }