refactor(ui): update graphs to use the right w/h/aspect

This commit is contained in:
psychedelicious
2025-07-05 23:59:07 +10:00
parent 4925694dc1
commit b771c3b164
9 changed files with 54 additions and 32 deletions

View File

@@ -423,11 +423,15 @@ export const selectIsCogView4 = createParamsSelector((params) => params.model?.b
export const selectIsImagen3 = createParamsSelector((params) => params.model?.base === 'imagen3');
export const selectIsImagen4 = createParamsSelector((params) => params.model?.base === 'imagen4');
export const selectIsFluxKontextApi = createParamsSelector((params) => params.model?.base === 'flux-kontext');
export const selectIsFluxKontext = createParamsSelector(
(params) =>
params.model?.base === 'flux-kontext' ||
(params.model?.base === 'flux' && params.model?.name?.toLowerCase().includes('kontext'))
);
export const selectIsFluxKontext = createParamsSelector((params) => {
if (params.model?.base === 'flux-kontext') {
return true;
}
if (params.model?.base === 'flux' && params.model?.name.toLowerCase().includes('kontext')) {
return true;
}
return false;
});
export const selectIsChatGPT4o = createParamsSelector((params) => params.model?.base === 'chatgpt-4o');
export const selectModel = createParamsSelector((params) => params.model);

View File

@@ -2,12 +2,15 @@ import { logger } from 'app/logging/logger';
import { getPrefixedId } from 'features/controlLayers/konva/util';
import { selectMainModelConfig } from 'features/controlLayers/store/paramsSlice';
import { selectRefImagesSlice } from 'features/controlLayers/store/refImagesSlice';
import { selectCanvasSlice } from 'features/controlLayers/store/selectors';
import { isChatGPT4oAspectRatioID, isChatGPT4oReferenceImageConfig } from 'features/controlLayers/store/types';
import { getGlobalReferenceImageWarnings } from 'features/controlLayers/store/validators';
import { type ImageField, zModelIdentifierField } from 'features/nodes/types/common';
import { Graph } from 'features/nodes/util/graph/generation/Graph';
import { selectCanvasOutputFields, selectPresetModifiedPrompts } from 'features/nodes/util/graph/graphBuilderUtils';
import {
selectCanvasOutputFields,
selectOriginalAndScaledSizes,
selectPresetModifiedPrompts,
} from 'features/nodes/util/graph/graphBuilderUtils';
import type { GraphBuilderArg, GraphBuilderReturn } from 'features/nodes/util/graph/types';
import { UnsupportedGenerationModeError } from 'features/nodes/util/graph/types';
import { t } from 'i18next';
@@ -27,17 +30,14 @@ export const buildChatGPT4oGraph = async (arg: GraphBuilderArg): Promise<GraphBu
const model = selectMainModelConfig(state);
const canvas = selectCanvasSlice(state);
const refImages = selectRefImagesSlice(state);
const { bbox } = canvas;
const { originalSize, scaledSize, aspectRatio } = selectOriginalAndScaledSizes(state);
const { positivePrompt } = selectPresetModifiedPrompts(state);
assert(model, 'No model found in state');
assert(model.base === 'chatgpt-4o', 'Model is not a ChatGPT 4o model');
assert(isChatGPT4oAspectRatioID(bbox.aspectRatio.id), 'ChatGPT 4o does not support this aspect ratio');
const validRefImages = refImages.entities
.filter((entity) => entity.isEnabled)
.filter((entity) => isChatGPT4oReferenceImageConfig(entity.config))
@@ -57,21 +57,23 @@ export const buildChatGPT4oGraph = async (arg: GraphBuilderArg): Promise<GraphBu
}
if (generationMode === 'txt2img') {
assert(isChatGPT4oAspectRatioID(aspectRatio.id), 'ChatGPT 4o does not support this aspect ratio');
const g = new Graph(getPrefixedId('chatgpt_4o_txt2img_graph'));
const gptImage = g.addNode({
// @ts-expect-error: These nodes are not available in the OSS application
type: 'chatgpt_4o_generate_image',
model: zModelIdentifierField.parse(model),
positive_prompt: positivePrompt,
aspect_ratio: bbox.aspectRatio.id,
aspect_ratio: aspectRatio.id,
reference_images,
...selectCanvasOutputFields(state),
});
g.upsertMetadata({
positive_prompt: positivePrompt,
model: Graph.getModelMetadataField(model),
width: bbox.rect.width,
height: bbox.rect.height,
width: originalSize.width,
height: originalSize.height,
});
return {
g,

View File

@@ -11,8 +11,8 @@ import { addTextToImage } from 'features/nodes/util/graph/generation/addTextToIm
import { addWatermarker } from 'features/nodes/util/graph/generation/addWatermarker';
import { Graph } from 'features/nodes/util/graph/generation/Graph';
import {
getSizes,
selectCanvasOutputFields,
selectOriginalAndScaledSizes,
selectPresetModifiedPrompts,
} from 'features/nodes/util/graph/graphBuilderUtils';
import type { GraphBuilderArg, GraphBuilderReturn, ImageOutputNodes } from 'features/nodes/util/graph/types';
@@ -36,7 +36,7 @@ export const buildCogView4Graph = async (arg: GraphBuilderArg): Promise<GraphBui
assert(model, 'No model found in state');
const { originalSize, scaledSize } = getSizes(bbox);
const { originalSize, scaledSize } = selectOriginalAndScaledSizes(state);
const { positivePrompt, negativePrompt } = selectPresetModifiedPrompts(state);
const g = new Graph(getPrefixedId('cogview4_graph'));

View File

@@ -17,8 +17,8 @@ import { addTextToImage } from 'features/nodes/util/graph/generation/addTextToIm
import { addWatermarker } from 'features/nodes/util/graph/generation/addWatermarker';
import { Graph } from 'features/nodes/util/graph/generation/Graph';
import {
getSizes,
selectCanvasOutputFields,
selectOriginalAndScaledSizes,
selectPresetModifiedPrompts,
} from 'features/nodes/util/graph/graphBuilderUtils';
import type { GraphBuilderArg, GraphBuilderReturn, ImageOutputNodes } from 'features/nodes/util/graph/types';
@@ -43,7 +43,7 @@ export const buildFLUXGraph = async (arg: GraphBuilderArg): Promise<GraphBuilder
const { bbox } = canvas;
const { originalSize, scaledSize } = getSizes(bbox);
const { originalSize, scaledSize } = selectOriginalAndScaledSizes(state);
const model = selectMainModelConfig(state);

View File

@@ -16,8 +16,8 @@ import { addTextToImage } from 'features/nodes/util/graph/generation/addTextToIm
import { addWatermarker } from 'features/nodes/util/graph/generation/addWatermarker';
import { Graph } from 'features/nodes/util/graph/generation/Graph';
import {
getSizes,
selectCanvasOutputFields,
selectOriginalAndScaledSizes,
selectPresetModifiedPrompts,
} from 'features/nodes/util/graph/graphBuilderUtils';
import type { GraphBuilderArg, GraphBuilderReturn, ImageOutputNodes } from 'features/nodes/util/graph/types';
@@ -56,7 +56,7 @@ export const buildSD1Graph = async (arg: GraphBuilderArg): Promise<GraphBuilderR
const fp32 = vaePrecision === 'fp32';
const { positivePrompt, negativePrompt } = selectPresetModifiedPrompts(state);
const { originalSize, scaledSize } = getSizes(bbox);
const { originalSize, scaledSize } = selectOriginalAndScaledSizes(state);
const g = new Graph(getPrefixedId('sd1_graph'));
const modelLoader = g.addNode({

View File

@@ -10,8 +10,8 @@ import { addTextToImage } from 'features/nodes/util/graph/generation/addTextToIm
import { addWatermarker } from 'features/nodes/util/graph/generation/addWatermarker';
import { Graph } from 'features/nodes/util/graph/generation/Graph';
import {
getSizes,
selectCanvasOutputFields,
selectOriginalAndScaledSizes,
selectPresetModifiedPrompts,
} from 'features/nodes/util/graph/graphBuilderUtils';
import type { GraphBuilderArg, GraphBuilderReturn, ImageOutputNodes } from 'features/nodes/util/graph/types';
@@ -46,7 +46,7 @@ export const buildSD3Graph = async (arg: GraphBuilderArg): Promise<GraphBuilderR
img2imgStrength,
} = params;
const { originalSize, scaledSize } = getSizes(bbox);
const { originalSize, scaledSize } = selectOriginalAndScaledSizes(state);
const { positivePrompt, negativePrompt } = selectPresetModifiedPrompts(state);
const g = new Graph(getPrefixedId('sd3_graph'));

View File

@@ -16,8 +16,8 @@ import { addTextToImage } from 'features/nodes/util/graph/generation/addTextToIm
import { addWatermarker } from 'features/nodes/util/graph/generation/addWatermarker';
import { Graph } from 'features/nodes/util/graph/generation/Graph';
import {
getSizes,
selectCanvasOutputFields,
selectOriginalAndScaledSizes,
selectPresetModifiedPrompts,
} from 'features/nodes/util/graph/graphBuilderUtils';
import type { GraphBuilderArg, GraphBuilderReturn, ImageOutputNodes } from 'features/nodes/util/graph/types';
@@ -59,7 +59,7 @@ export const buildSDXLGraph = async (arg: GraphBuilderArg): Promise<GraphBuilder
assert(model, 'No model found in state');
const fp32 = vaePrecision === 'fp32';
const { originalSize, scaledSize } = getSizes(bbox);
const { originalSize, scaledSize } = selectOriginalAndScaledSizes(state);
const { positivePrompt, negativePrompt, positiveStylePrompt, negativeStylePrompt } =
selectPresetModifiedPrompts(state);

View File

@@ -1,9 +1,9 @@
import { createSelector } from '@reduxjs/toolkit';
import type { RootState } from 'app/store/store';
import { pick } from 'es-toolkit/compat';
import { getPrefixedId } from 'features/controlLayers/konva/util';
import { selectParamsSlice } from 'features/controlLayers/store/paramsSlice';
import type { CanvasState, ParamsState } from 'features/controlLayers/store/types';
import { selectCanvasSlice } from 'features/controlLayers/store/selectors';
import type { ParamsState } from 'features/controlLayers/store/types';
import type { BoardField } from 'features/nodes/types/common';
import type { Graph } from 'features/nodes/util/graph/generation/Graph';
import { buildPresetModifiedPrompt } from 'features/stylePresets/hooks/usePresetModifiedPrompts';
@@ -94,11 +94,27 @@ export const selectPresetModifiedPrompts = createSelector(
}
);
export const getSizes = (bboxState: CanvasState['bbox']) => {
const originalSize = pick(bboxState.rect, 'width', 'height');
const scaledSize = ['auto', 'manual'].includes(bboxState.scaleMethod) ? bboxState.scaledSize : originalSize;
return { originalSize, scaledSize };
};
export const selectOriginalAndScaledSizes = createSelector(
[selectActiveTab, selectParamsSlice, selectCanvasSlice],
(tab, params, canvas) => {
if (tab === 'generate') {
const { width, height } = params.dimensions.rect;
const { aspectRatio } = params.dimensions;
return {
originalSize: { width, height },
scaledSize: { width, height },
aspectRatio,
};
} else {
// tab === 'canvas'
const { width, height } = canvas.bbox.rect;
const { aspectRatio } = canvas.bbox;
const originalSize = { width, height };
const scaledSize = ['auto', 'manual'].includes(canvas.bbox.scaleMethod) ? canvas.bbox.scaledSize : originalSize;
return { originalSize, scaledSize, aspectRatio };
}
}
);
export const getInfill = (
g: Graph,

View File

@@ -249,7 +249,7 @@ export const isFluxKontextApiModelConfig = (config: AnyModelConfig): config is A
};
export const isFluxKontextModelConfig = (config: AnyModelConfig): config is FLUXKontextModelConfig => {
return config.type === 'main' && config.base === 'flux' && config.name?.toLowerCase().includes('kontext');
return config.type === 'main' && config.base === 'flux' && config.name.toLowerCase().includes('kontext');
};
export const isNonRefinerMainModelConfig = (config: AnyModelConfig): config is MainModelConfig => {