parent
c372ea4a92
commit
2aa2cf21da
5 changed files with 226 additions and 40 deletions
src/platform
164
src/platform/blurhash.ts
Normal file
164
src/platform/blurhash.ts
Normal file
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
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);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue