Refactoring code
This commit is contained in:
@ -1,36 +1,49 @@
|
||||
"use server";
|
||||
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { VibrantSwatch } from "@/types/VibrantSwatch";
|
||||
import type { VibrantSwatch } from "@/types/VibrantSwatch";
|
||||
import { getImageBufferFromS3Key } from "@/utils/getImageBufferFromS3";
|
||||
import { generateColorName, rgbToHex } from "@/utils/uploadHelper";
|
||||
import { converter, parse } from "culori";
|
||||
import { Vibrant } from "node-vibrant/node";
|
||||
|
||||
const toOklab = converter("oklab");
|
||||
const A_MIN = -0.5, A_MAX = 0.5;
|
||||
const B_MIN = -0.5, B_MAX = 0.5;
|
||||
const A_MIN = -0.5,
|
||||
A_MAX = 0.5;
|
||||
const B_MIN = -0.5,
|
||||
B_MAX = 0.5;
|
||||
|
||||
function clamp01(x: number) { return Math.max(0, Math.min(1, x)); }
|
||||
function norm(x: number, lo: number, hi: number) { return clamp01((x - lo) / (hi - lo)); }
|
||||
function clamp01(x: number) {
|
||||
return Math.max(0, Math.min(1, x));
|
||||
}
|
||||
function norm(x: number, lo: number, hi: number) {
|
||||
return clamp01((x - lo) / (hi - lo));
|
||||
}
|
||||
|
||||
function hilbertIndex15(x01: number, y01: number): number {
|
||||
let x = Math.floor(clamp01(x01) * 32767);
|
||||
let y = Math.floor(clamp01(y01) * 32767);
|
||||
let index = 0;
|
||||
for (let s = 1 << 14; s > 0; s >>= 1) {
|
||||
const rx = (x & s) ? 1 : 0;
|
||||
const ry = (y & s) ? 1 : 0;
|
||||
const rx = x & s ? 1 : 0;
|
||||
const ry = y & s ? 1 : 0;
|
||||
index += s * s * ((3 * rx) ^ ry);
|
||||
if (ry === 0) {
|
||||
if (rx === 1) { x = 32767 - x; y = 32767 - y; }
|
||||
const t = x; x = y; y = t;
|
||||
if (rx === 1) {
|
||||
x = 32767 - x;
|
||||
y = 32767 - y;
|
||||
}
|
||||
const t = x;
|
||||
x = y;
|
||||
y = t;
|
||||
}
|
||||
}
|
||||
return index >>> 0;
|
||||
}
|
||||
|
||||
function centroidFromPaletteHexes(hexByType: Record<string, string | undefined>) {
|
||||
function centroidFromPaletteHexes(
|
||||
hexByType: Record<string, string | undefined>,
|
||||
) {
|
||||
const weights: Record<string, number> = {
|
||||
Vibrant: 0.7,
|
||||
Muted: 0.15,
|
||||
@ -48,14 +61,20 @@ function centroidFromPaletteHexes(hexByType: Record<string, string | undefined>)
|
||||
hexByType["LightVibrant"] ||
|
||||
hexByType["LightMuted"];
|
||||
|
||||
let L = 0, A = 0, B = 0, W = 0;
|
||||
let L = 0,
|
||||
A = 0,
|
||||
B = 0,
|
||||
W = 0;
|
||||
|
||||
for (const [type, w] of Object.entries(weights)) {
|
||||
const hex = hexByType[type] ?? fallbackHex;
|
||||
if (!hex || w <= 0) continue;
|
||||
const c = toOklab(parse(hex));
|
||||
if (!c) continue;
|
||||
L += c.l * w; A += c.a * w; B += c.b * w; W += w;
|
||||
L += c.l * w;
|
||||
A += c.a * w;
|
||||
B += c.b * w;
|
||||
W += w;
|
||||
}
|
||||
|
||||
if (W === 0) return { l: 0.5, a: 0, b: 0 };
|
||||
@ -78,7 +97,11 @@ export async function generateArtworkColorsForArtwork(artworkId: string) {
|
||||
where: { id: artworkId },
|
||||
select: {
|
||||
file: { select: { fileKey: true } },
|
||||
variants: { where: { type: "original" }, select: { s3Key: true }, take: 1 },
|
||||
variants: {
|
||||
where: { type: "original" },
|
||||
select: { s3Key: true },
|
||||
take: 1,
|
||||
},
|
||||
},
|
||||
});
|
||||
if (!artwork) throw new Error("Artwork not found");
|
||||
@ -117,11 +140,14 @@ export async function generateArtworkColorsForArtwork(artworkId: string) {
|
||||
}
|
||||
|
||||
const hexByType: Record<string, string | undefined> = Object.fromEntries(
|
||||
vibrantHexes.map(({ type, hex }) => [type, hex])
|
||||
vibrantHexes.map(({ type, hex }) => [type, hex]),
|
||||
);
|
||||
|
||||
const { l, a, b } = centroidFromPaletteHexes(hexByType);
|
||||
const sortKey = hilbertIndex15(norm(a, A_MIN, A_MAX), norm(b, B_MIN, B_MAX));
|
||||
const sortKey = hilbertIndex15(
|
||||
norm(a, A_MIN, A_MAX),
|
||||
norm(b, B_MIN, B_MAX),
|
||||
);
|
||||
|
||||
await prisma.artwork.update({
|
||||
where: { id: artworkId },
|
||||
@ -144,6 +170,9 @@ export async function generateArtworkColorsForArtwork(artworkId: string) {
|
||||
colorError: e instanceof Error ? e.message : "Color generation failed",
|
||||
},
|
||||
});
|
||||
return { ok: false as const, error: e instanceof Error ? e.message : "Color generation failed" };
|
||||
return {
|
||||
ok: false as const,
|
||||
error: e instanceof Error ? e.message : "Color generation failed",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
"use server";
|
||||
|
||||
import { Prisma } from "@/generated/prisma/client";
|
||||
import type { Prisma } from "@/generated/prisma/client";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { generateArtworkColorsForArtwork } from "../artworks/generateArtworkColors";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user