Update ImageEffector.ts

This commit is contained in:
syuilo 2025-11-03 19:03:08 +09:00
parent a07fcafdee
commit e4b6853f0a
1 changed files with 26 additions and 23 deletions

View File

@ -72,17 +72,12 @@ interface TextureParamDef extends CommonParamDef {
} | null; } | null;
}; };
interface TextureRefParamDef extends CommonParamDef {
type: 'textureRef';
default: string;
};
interface ColorParamDef extends CommonParamDef { interface ColorParamDef extends CommonParamDef {
type: 'color'; type: 'color';
default: ImageEffectorRGB; default: ImageEffectorRGB;
}; };
type ImageEffectorFxParamDef = NumberParamDef | NumberEnumParamDef | BooleanParamDef | AlignParamDef | SeedParamDef | TextureParamDef | TextureRefParamDef | ColorParamDef; type ImageEffectorFxParamDef = NumberParamDef | NumberEnumParamDef | BooleanParamDef | AlignParamDef | SeedParamDef | TextureParamDef | ColorParamDef;
export type ImageEffectorFxParamDefs = Record<string, ImageEffectorFxParamDef>; export type ImageEffectorFxParamDefs = Record<string, ImageEffectorFxParamDef>;
@ -160,7 +155,7 @@ export class ImageEffector {
} }
public async render(layers: ImageEffectorLayer[]) { public async render(layers: ImageEffectorLayer[]) {
const fnParams: Record<string, any> = {}; const compositorLayers: ImageCompositorLayer[] = [];
const unused = new Set(this.compositor.getKeysOfRegisteredTextures()); const unused = new Set(this.compositor.getKeysOfRegisteredTextures());
@ -168,28 +163,40 @@ export class ImageEffector {
const fx = this.fxs.find(fx => fx.id === layer.fxId); const fx = this.fxs.find(fx => fx.id === layer.fxId);
if (fx == null) continue; if (fx == null) continue;
const fnParams: Record<string, any> = {};
for (const k of Object.keys(layer.params)) { for (const k of Object.keys(layer.params)) {
const paramDef = (fx.params as ImageEffectorFxParamDefs)[k]; const paramDef = (fx.params as ImageEffectorFxParamDefs)[k];
if (paramDef == null) continue; if (paramDef == null) continue;
if (paramDef.type !== 'texture') continue; if (paramDef.type === 'texture') {
const v = getValue<typeof paramDef.type>(layer.params, k); const v = getValue<typeof paramDef.type>(layer.params, k);
if (v == null) continue; if (v == null) continue;
const textureKey = this.getTextureKeyForParam(v); const textureKey = this.getTextureKeyForParam(v);
unused.delete(textureKey); unused.delete(textureKey);
if (this.compositor.hasTexture(textureKey)) continue; fnParams[k] = textureKey;
if (this.compositor.hasTexture(textureKey)) continue;
if (_DEV_) console.log(`Baking texture of <${textureKey}>...`); if (_DEV_) console.log(`Baking texture of <${textureKey}>...`);
const image = const image =
v.type === 'text' ? await createTextureFromText(v.text) : v.type === 'text' ? await createTextureFromText(v.text) :
v.type === 'url' ? await createTextureFromUrl(v.url) : v.type === 'url' ? await createTextureFromUrl(v.url) :
v.type === 'qr' ? await createTextureFromQr({ data: v.data }) : v.type === 'qr' ? await createTextureFromQr({ data: v.data }) :
null; null;
if (image == null) continue; if (image == null) continue;
this.compositor.registerTexture(textureKey, image); this.compositor.registerTexture(textureKey, image);
} else {
fnParams[k] = layer.params[k];
}
} }
compositorLayers.push({
id: layer.id,
functionId: layer.fxId,
params: fnParams,
});
} }
for (const k of unused) { for (const k of unused) {
@ -197,11 +204,7 @@ export class ImageEffector {
this.compositor.unregisterTexture(k); this.compositor.unregisterTexture(k);
} }
this.compositor.render(layers.map(layer => ({ this.compositor.render(compositorLayers);
id: layer.id,
functionId: layer.fxId,
params: fnParams,
})));
} }
public changeResolution(width: number, height: number) { public changeResolution(width: number, height: number) {
@ -264,7 +267,7 @@ async function createTextureFromText(text: string | null, resolution = 2048) {
const textMetrics = ctx.measureText(text); const textMetrics = ctx.measureText(text);
const cropWidth = (Math.ceil(textMetrics.actualBoundingBoxRight + textMetrics.actualBoundingBoxLeft) + margin + margin); const cropWidth = (Math.ceil(textMetrics.actualBoundingBoxRight + textMetrics.actualBoundingBoxLeft) + margin + margin);
const cropHeight = (Math.ceil(textMetrics.actualBoundingBoxAscent + textMetrics.actualBoundingBoxDescent) + margin + margin); const cropHeight = (Math.ceil(textMetrics.actualBoundingBoxAscent + textMetrics.actualBoundingBoxDescent) + margin + margin);
const data = ctx.getImageData(0, (ctx.canvas.height / 2) - (cropHeight / 2), ctx.canvas.width, ctx.canvas.height); const data = ctx.getImageData(0, (ctx.canvas.height / 2) - (cropHeight / 2), cropWidth, cropHeight);
ctx.canvas.remove(); ctx.canvas.remove();