mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Merge branch 'main' into chore/update-pypi-from-release-branches
This commit is contained in:
commit
22dd64dfa4
@ -156,6 +156,18 @@ class MetadataAccumulatorInvocation(BaseInvocation):
|
|||||||
description="The VAE used for decoding, if the main model's default was not used",
|
description="The VAE used for decoding, if the main model's default was not used",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# High resolution fix metadata.
|
||||||
|
hrf_width: Optional[int] = InputField(
|
||||||
|
description="The high resolution fix height and width multipler.",
|
||||||
|
)
|
||||||
|
hrf_height: Optional[int] = InputField(
|
||||||
|
description="The high resolution fix height and width multipler.",
|
||||||
|
)
|
||||||
|
hrf_strength: Optional[float] = InputField(
|
||||||
|
default=None,
|
||||||
|
description="The high resolution fix img2img strength used in the upscale pass.",
|
||||||
|
)
|
||||||
|
|
||||||
# SDXL
|
# SDXL
|
||||||
positive_style_prompt: Optional[str] = InputField(
|
positive_style_prompt: Optional[str] = InputField(
|
||||||
default=None,
|
default=None,
|
||||||
|
@ -559,8 +559,10 @@
|
|||||||
"negativePrompt": "Negative Prompt",
|
"negativePrompt": "Negative Prompt",
|
||||||
"noImageDetails": "No image details found",
|
"noImageDetails": "No image details found",
|
||||||
"noMetaData": "No metadata found",
|
"noMetaData": "No metadata found",
|
||||||
|
"noRecallParameters": "No parameters to recall found",
|
||||||
"perlin": "Perlin Noise",
|
"perlin": "Perlin Noise",
|
||||||
"positivePrompt": "Positive Prompt",
|
"positivePrompt": "Positive Prompt",
|
||||||
|
"recallParameters": "Recall Parameters",
|
||||||
"scheduler": "Scheduler",
|
"scheduler": "Scheduler",
|
||||||
"seamless": "Seamless",
|
"seamless": "Seamless",
|
||||||
"seed": "Seed",
|
"seed": "Seed",
|
||||||
|
@ -115,7 +115,10 @@
|
|||||||
"currentlyInUse": "Questa immagine è attualmente utilizzata nelle seguenti funzionalità:",
|
"currentlyInUse": "Questa immagine è attualmente utilizzata nelle seguenti funzionalità:",
|
||||||
"copy": "Copia",
|
"copy": "Copia",
|
||||||
"download": "Scarica",
|
"download": "Scarica",
|
||||||
"setCurrentImage": "Imposta come immagine corrente"
|
"setCurrentImage": "Imposta come immagine corrente",
|
||||||
|
"preparingDownload": "Preparazione del download",
|
||||||
|
"preparingDownloadFailed": "Problema durante la preparazione del download",
|
||||||
|
"downloadSelection": "Scarica gli elementi selezionati"
|
||||||
},
|
},
|
||||||
"hotkeys": {
|
"hotkeys": {
|
||||||
"keyboardShortcuts": "Tasti rapidi",
|
"keyboardShortcuts": "Tasti rapidi",
|
||||||
@ -572,7 +575,8 @@
|
|||||||
"systemDisconnected": "Sistema disconnesso",
|
"systemDisconnected": "Sistema disconnesso",
|
||||||
"noControlImageForControlAdapter": "L'adattatore di controllo {{number}} non ha un'immagine di controllo",
|
"noControlImageForControlAdapter": "L'adattatore di controllo {{number}} non ha un'immagine di controllo",
|
||||||
"noModelForControlAdapter": "Nessun modello selezionato per l'adattatore di controllo {{number}}.",
|
"noModelForControlAdapter": "Nessun modello selezionato per l'adattatore di controllo {{number}}.",
|
||||||
"incompatibleBaseModelForControlAdapter": "Il modello dell'adattatore di controllo {{number}} non è compatibile con il modello principale."
|
"incompatibleBaseModelForControlAdapter": "Il modello dell'adattatore di controllo {{number}} non è compatibile con il modello principale.",
|
||||||
|
"missingNodeTemplate": "Modello di nodo mancante"
|
||||||
},
|
},
|
||||||
"enableNoiseSettings": "Abilita le impostazioni del rumore",
|
"enableNoiseSettings": "Abilita le impostazioni del rumore",
|
||||||
"cpuNoise": "Rumore CPU",
|
"cpuNoise": "Rumore CPU",
|
||||||
@ -620,7 +624,15 @@
|
|||||||
"beta": "Beta",
|
"beta": "Beta",
|
||||||
"enableNodesEditor": "Abilita l'editor dei nodi",
|
"enableNodesEditor": "Abilita l'editor dei nodi",
|
||||||
"experimental": "Sperimentale",
|
"experimental": "Sperimentale",
|
||||||
"autoChangeDimensions": "Aggiorna L/A alle impostazioni predefinite del modello in caso di modifica"
|
"autoChangeDimensions": "Aggiorna L/A alle impostazioni predefinite del modello in caso di modifica",
|
||||||
|
"clearIntermediates": "Cancella le immagini intermedie",
|
||||||
|
"clearIntermediatesDesc3": "Le immagini della galleria non verranno eliminate.",
|
||||||
|
"clearIntermediatesDesc2": "Le immagini intermedie sono sottoprodotti della generazione, diversi dalle immagini risultanti nella galleria. La cancellazione degli intermedi libererà spazio su disco.",
|
||||||
|
"intermediatesCleared_one": "Cancellata 1 immagine intermedia",
|
||||||
|
"intermediatesCleared_many": "Cancellate {{number}} immagini intermedie",
|
||||||
|
"intermediatesCleared_other": "",
|
||||||
|
"clearIntermediatesDesc1": "La cancellazione delle immagini intermedie ripristinerà lo stato di Tela Unificata e ControlNet.",
|
||||||
|
"intermediatesClearedFailed": "Problema con la cancellazione delle immagini intermedie"
|
||||||
},
|
},
|
||||||
"toast": {
|
"toast": {
|
||||||
"tempFoldersEmptied": "Cartella temporanea svuotata",
|
"tempFoldersEmptied": "Cartella temporanea svuotata",
|
||||||
@ -866,7 +878,26 @@
|
|||||||
"workflowValidation": "Errore di convalida del flusso di lavoro",
|
"workflowValidation": "Errore di convalida del flusso di lavoro",
|
||||||
"workflowAuthor": "Autore",
|
"workflowAuthor": "Autore",
|
||||||
"workflowName": "Nome",
|
"workflowName": "Nome",
|
||||||
"workflowNotes": "Note"
|
"workflowNotes": "Note",
|
||||||
|
"unhandledInputProperty": "Proprietà di input non gestita",
|
||||||
|
"versionUnknown": " Versione sconosciuta",
|
||||||
|
"unableToValidateWorkflow": "Impossibile convalidare il flusso di lavoro",
|
||||||
|
"updateApp": "Aggiorna App",
|
||||||
|
"problemReadingWorkflow": "Problema durante la lettura del flusso di lavoro dall'immagine",
|
||||||
|
"unableToLoadWorkflow": "Impossibile caricare il flusso di lavoro",
|
||||||
|
"updateNode": "Aggiorna nodo",
|
||||||
|
"version": "Versione",
|
||||||
|
"notes": "Note",
|
||||||
|
"problemSettingTitle": "Problema nell'impostazione del titolo",
|
||||||
|
"unkownInvocation": "Tipo di invocazione sconosciuta",
|
||||||
|
"unknownTemplate": "Modello sconosciuto",
|
||||||
|
"nodeType": "Tipo di nodo",
|
||||||
|
"vaeField": "VAE",
|
||||||
|
"unhandledOutputProperty": "Proprietà di output non gestita",
|
||||||
|
"notesDescription": "Aggiunge note sul tuo flusso di lavoro",
|
||||||
|
"unknownField": "Campo sconosciuto",
|
||||||
|
"unknownNode": "Nodo sconosciuto",
|
||||||
|
"vaeFieldDescription": "Sotto modello VAE."
|
||||||
},
|
},
|
||||||
"boards": {
|
"boards": {
|
||||||
"autoAddBoard": "Aggiungi automaticamente bacheca",
|
"autoAddBoard": "Aggiungi automaticamente bacheca",
|
||||||
@ -883,7 +914,8 @@
|
|||||||
"searchBoard": "Cerca bacheche ...",
|
"searchBoard": "Cerca bacheche ...",
|
||||||
"noMatching": "Nessuna bacheca corrispondente",
|
"noMatching": "Nessuna bacheca corrispondente",
|
||||||
"selectBoard": "Seleziona una Bacheca",
|
"selectBoard": "Seleziona una Bacheca",
|
||||||
"uncategorized": "Non categorizzato"
|
"uncategorized": "Non categorizzato",
|
||||||
|
"downloadBoard": "Scarica la bacheca"
|
||||||
},
|
},
|
||||||
"controlnet": {
|
"controlnet": {
|
||||||
"contentShuffleDescription": "Rimescola il contenuto di un'immagine",
|
"contentShuffleDescription": "Rimescola il contenuto di un'immagine",
|
||||||
@ -1068,9 +1100,7 @@
|
|||||||
},
|
},
|
||||||
"compositingMaskAdjustments": {
|
"compositingMaskAdjustments": {
|
||||||
"heading": "Regolazioni della maschera",
|
"heading": "Regolazioni della maschera",
|
||||||
"paragraphs": [
|
"paragraphs": ["Regola la maschera."]
|
||||||
"Regola la maschera."
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"compositingCoherenceSteps": {
|
"compositingCoherenceSteps": {
|
||||||
"heading": "Passi",
|
"heading": "Passi",
|
||||||
@ -1081,15 +1111,11 @@
|
|||||||
},
|
},
|
||||||
"compositingBlur": {
|
"compositingBlur": {
|
||||||
"heading": "Sfocatura",
|
"heading": "Sfocatura",
|
||||||
"paragraphs": [
|
"paragraphs": ["Il raggio di sfocatura della maschera."]
|
||||||
"Il raggio di sfocatura della maschera."
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"compositingCoherenceMode": {
|
"compositingCoherenceMode": {
|
||||||
"heading": "Modalità",
|
"heading": "Modalità",
|
||||||
"paragraphs": [
|
"paragraphs": ["La modalità del Passaggio di Coerenza."]
|
||||||
"La modalità del Passaggio di Coerenza."
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"clipSkip": {
|
"clipSkip": {
|
||||||
"paragraphs": [
|
"paragraphs": [
|
||||||
@ -1229,9 +1255,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"infillMethod": {
|
"infillMethod": {
|
||||||
"paragraphs": [
|
"paragraphs": ["Metodo per riempire l'area selezionata."],
|
||||||
"Metodo per riempire l'area selezionata."
|
|
||||||
],
|
|
||||||
"heading": "Metodo di riempimento"
|
"heading": "Metodo di riempimento"
|
||||||
},
|
},
|
||||||
"controlNetWeight": {
|
"controlNetWeight": {
|
||||||
@ -1247,9 +1271,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"controlNetControlMode": {
|
"controlNetControlMode": {
|
||||||
"paragraphs": [
|
"paragraphs": ["Attribuisce più peso al prompt o a ControlNet."],
|
||||||
"Attribuisce più peso al prompt o a ControlNet."
|
|
||||||
],
|
|
||||||
"heading": "Modalità di controllo"
|
"heading": "Modalità di controllo"
|
||||||
},
|
},
|
||||||
"paramSteps": {
|
"paramSteps": {
|
||||||
|
@ -630,8 +630,7 @@
|
|||||||
"clearIntermediatesDesc2": "中间产物图像是生成过程中产生的副产品,与图库中的结果图像不同。清除中间产物可释放磁盘空间。",
|
"clearIntermediatesDesc2": "中间产物图像是生成过程中产生的副产品,与图库中的结果图像不同。清除中间产物可释放磁盘空间。",
|
||||||
"intermediatesCleared_other": "已清除 {{number}} 个中间产物",
|
"intermediatesCleared_other": "已清除 {{number}} 个中间产物",
|
||||||
"clearIntermediatesDesc1": "清除中间产物会重置您的画布和 ControlNet 状态。",
|
"clearIntermediatesDesc1": "清除中间产物会重置您的画布和 ControlNet 状态。",
|
||||||
"intermediatesClearedFailed": "清除中间产物时出现问题",
|
"intermediatesClearedFailed": "清除中间产物时出现问题"
|
||||||
"noIntermediates": "没有可清除的中间产物"
|
|
||||||
},
|
},
|
||||||
"toast": {
|
"toast": {
|
||||||
"tempFoldersEmptied": "临时文件夹已清空",
|
"tempFoldersEmptied": "临时文件夹已清空",
|
||||||
@ -1243,9 +1242,7 @@
|
|||||||
"popovers": {
|
"popovers": {
|
||||||
"compositingMaskAdjustments": {
|
"compositingMaskAdjustments": {
|
||||||
"heading": "遮罩调整",
|
"heading": "遮罩调整",
|
||||||
"paragraphs": [
|
"paragraphs": ["调整遮罩。"]
|
||||||
"调整遮罩。"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"paramRatio": {
|
"paramRatio": {
|
||||||
"heading": "纵横比",
|
"heading": "纵横比",
|
||||||
@ -1263,9 +1260,7 @@
|
|||||||
},
|
},
|
||||||
"compositingBlur": {
|
"compositingBlur": {
|
||||||
"heading": "模糊",
|
"heading": "模糊",
|
||||||
"paragraphs": [
|
"paragraphs": ["遮罩模糊半径。"]
|
||||||
"遮罩模糊半径。"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"noiseUseCPU": {
|
"noiseUseCPU": {
|
||||||
"heading": "使用 CPU 噪声",
|
"heading": "使用 CPU 噪声",
|
||||||
@ -1283,15 +1278,11 @@
|
|||||||
},
|
},
|
||||||
"compositingCoherenceMode": {
|
"compositingCoherenceMode": {
|
||||||
"heading": "模式",
|
"heading": "模式",
|
||||||
"paragraphs": [
|
"paragraphs": ["一致性层模式。"]
|
||||||
"一致性层模式。"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"controlNetResizeMode": {
|
"controlNetResizeMode": {
|
||||||
"heading": "缩放模式",
|
"heading": "缩放模式",
|
||||||
"paragraphs": [
|
"paragraphs": ["ControlNet 输入图像适应输出图像大小的方法。"]
|
||||||
"ControlNet 输入图像适应输出图像大小的方法。"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"clipSkip": {
|
"clipSkip": {
|
||||||
"paragraphs": [
|
"paragraphs": [
|
||||||
@ -1317,9 +1308,7 @@
|
|||||||
},
|
},
|
||||||
"compositingCoherencePass": {
|
"compositingCoherencePass": {
|
||||||
"heading": "一致性层",
|
"heading": "一致性层",
|
||||||
"paragraphs": [
|
"paragraphs": ["第二轮去噪有助于合成内补/外扩图像。"]
|
||||||
"第二轮去噪有助于合成内补/外扩图像。"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"compositingStrength": {
|
"compositingStrength": {
|
||||||
"heading": "强度",
|
"heading": "强度",
|
||||||
@ -1337,9 +1326,7 @@
|
|||||||
},
|
},
|
||||||
"compositingBlurMethod": {
|
"compositingBlurMethod": {
|
||||||
"heading": "模糊方式",
|
"heading": "模糊方式",
|
||||||
"paragraphs": [
|
"paragraphs": ["应用于遮罩区域的模糊方法。"]
|
||||||
"应用于遮罩区域的模糊方法。"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"paramScheduler": {
|
"paramScheduler": {
|
||||||
"heading": "调度器",
|
"heading": "调度器",
|
||||||
@ -1349,15 +1336,11 @@
|
|||||||
},
|
},
|
||||||
"controlNetWeight": {
|
"controlNetWeight": {
|
||||||
"heading": "权重",
|
"heading": "权重",
|
||||||
"paragraphs": [
|
"paragraphs": ["ControlNet 对生成图像的影响强度。"]
|
||||||
"ControlNet 对生成图像的影响强度。"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"paramCFGScale": {
|
"paramCFGScale": {
|
||||||
"heading": "CFG 等级",
|
"heading": "CFG 等级",
|
||||||
"paragraphs": [
|
"paragraphs": ["控制提示词对生成过程的影响程度。"]
|
||||||
"控制提示词对生成过程的影响程度。"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"paramSteps": {
|
"paramSteps": {
|
||||||
"heading": "步数",
|
"heading": "步数",
|
||||||
@ -1375,15 +1358,11 @@
|
|||||||
},
|
},
|
||||||
"lora": {
|
"lora": {
|
||||||
"heading": "LoRA 权重",
|
"heading": "LoRA 权重",
|
||||||
"paragraphs": [
|
"paragraphs": ["更高的 LoRA 权重会对最终图像产生更大的影响。"]
|
||||||
"更高的 LoRA 权重会对最终图像产生更大的影响。"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"infillMethod": {
|
"infillMethod": {
|
||||||
"heading": "填充方法",
|
"heading": "填充方法",
|
||||||
"paragraphs": [
|
"paragraphs": ["填充选定区域的方式。"]
|
||||||
"填充选定区域的方式。"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"controlNetBeginEnd": {
|
"controlNetBeginEnd": {
|
||||||
"heading": "开始 / 结束步数百分比",
|
"heading": "开始 / 结束步数百分比",
|
||||||
@ -1394,9 +1373,7 @@
|
|||||||
},
|
},
|
||||||
"scaleBeforeProcessing": {
|
"scaleBeforeProcessing": {
|
||||||
"heading": "处理前缩放",
|
"heading": "处理前缩放",
|
||||||
"paragraphs": [
|
"paragraphs": ["生成图像前将所选区域缩放为最适合模型的大小。"]
|
||||||
"生成图像前将所选区域缩放为最适合模型的大小。"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"paramDenoisingStrength": {
|
"paramDenoisingStrength": {
|
||||||
"heading": "去噪强度",
|
"heading": "去噪强度",
|
||||||
@ -1414,9 +1391,7 @@
|
|||||||
},
|
},
|
||||||
"controlNetControlMode": {
|
"controlNetControlMode": {
|
||||||
"heading": "控制模式",
|
"heading": "控制模式",
|
||||||
"paragraphs": [
|
"paragraphs": ["给提示词或 ControlNet 增加更大的权重。"]
|
||||||
"给提示词或 ControlNet 增加更大的权重。"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"dynamicPrompts": {
|
"dynamicPrompts": {
|
||||||
"paragraphs": [
|
"paragraphs": [
|
||||||
@ -1427,9 +1402,7 @@
|
|||||||
"heading": "动态提示词"
|
"heading": "动态提示词"
|
||||||
},
|
},
|
||||||
"paramVAE": {
|
"paramVAE": {
|
||||||
"paragraphs": [
|
"paragraphs": ["用于将 AI 输出转换成最终图像的模型。"],
|
||||||
"用于将 AI 输出转换成最终图像的模型。"
|
|
||||||
],
|
|
||||||
"heading": "VAE"
|
"heading": "VAE"
|
||||||
},
|
},
|
||||||
"dynamicPromptsSeedBehaviour": {
|
"dynamicPromptsSeedBehaviour": {
|
||||||
@ -1443,9 +1416,7 @@
|
|||||||
},
|
},
|
||||||
"dynamicPromptsMaxPrompts": {
|
"dynamicPromptsMaxPrompts": {
|
||||||
"heading": "最大提示词数量",
|
"heading": "最大提示词数量",
|
||||||
"paragraphs": [
|
"paragraphs": ["限制动态提示词可生成的提示词数量。"]
|
||||||
"限制动态提示词可生成的提示词数量。"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"controlNet": {
|
"controlNet": {
|
||||||
"paragraphs": [
|
"paragraphs": [
|
||||||
|
@ -39,7 +39,8 @@ export type SDFeature =
|
|||||||
| 'hires'
|
| 'hires'
|
||||||
| 'lora'
|
| 'lora'
|
||||||
| 'embedding'
|
| 'embedding'
|
||||||
| 'vae';
|
| 'vae'
|
||||||
|
| 'hrf';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration options for the InvokeAI UI.
|
* Configuration options for the InvokeAI UI.
|
||||||
@ -110,6 +111,14 @@ export type AppConfig = {
|
|||||||
fineStep: number;
|
fineStep: number;
|
||||||
coarseStep: number;
|
coarseStep: number;
|
||||||
};
|
};
|
||||||
|
hrfStrength: {
|
||||||
|
initial: number;
|
||||||
|
min: number;
|
||||||
|
sliderMax: number;
|
||||||
|
inputMax: number;
|
||||||
|
fineStep: number;
|
||||||
|
coarseStep: number;
|
||||||
|
};
|
||||||
dynamicPrompts: {
|
dynamicPrompts: {
|
||||||
maxPrompts: {
|
maxPrompts: {
|
||||||
initial: number;
|
initial: number;
|
||||||
|
@ -2,6 +2,7 @@ import { PopoverProps } from '@chakra-ui/react';
|
|||||||
|
|
||||||
export type Feature =
|
export type Feature =
|
||||||
| 'clipSkip'
|
| 'clipSkip'
|
||||||
|
| 'hrf'
|
||||||
| 'paramNegativeConditioning'
|
| 'paramNegativeConditioning'
|
||||||
| 'paramPositiveConditioning'
|
| 'paramPositiveConditioning'
|
||||||
| 'paramScheduler'
|
| 'paramScheduler'
|
||||||
|
@ -18,6 +18,7 @@ import ImageMetadataActions from './ImageMetadataActions';
|
|||||||
import { useAppSelector } from '../../../../app/store/storeHooks';
|
import { useAppSelector } from '../../../../app/store/storeHooks';
|
||||||
import { configSelector } from '../../../system/store/configSelectors';
|
import { configSelector } from '../../../system/store/configSelectors';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import ScrollableContent from 'features/nodes/components/sidePanel/ScrollableContent';
|
||||||
|
|
||||||
type ImageMetadataViewerProps = {
|
type ImageMetadataViewerProps = {
|
||||||
image: ImageDTO;
|
image: ImageDTO;
|
||||||
@ -65,19 +66,32 @@ const ImageMetadataViewer = ({ image }: ImageMetadataViewerProps) => {
|
|||||||
</Link>
|
</Link>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<ImageMetadataActions metadata={metadata} />
|
|
||||||
|
|
||||||
<Tabs
|
<Tabs
|
||||||
variant="line"
|
variant="line"
|
||||||
sx={{ display: 'flex', flexDir: 'column', w: 'full', h: 'full' }}
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDir: 'column',
|
||||||
|
w: 'full',
|
||||||
|
h: 'full',
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<TabList>
|
<TabList>
|
||||||
|
<Tab>{t('metadata.recallParameters')}</Tab>
|
||||||
<Tab>{t('metadata.metadata')}</Tab>
|
<Tab>{t('metadata.metadata')}</Tab>
|
||||||
<Tab>{t('metadata.imageDetails')}</Tab>
|
<Tab>{t('metadata.imageDetails')}</Tab>
|
||||||
<Tab>{t('metadata.workflow')}</Tab>
|
<Tab>{t('metadata.workflow')}</Tab>
|
||||||
</TabList>
|
</TabList>
|
||||||
|
|
||||||
<TabPanels>
|
<TabPanels>
|
||||||
|
<TabPanel>
|
||||||
|
{metadata ? (
|
||||||
|
<ScrollableContent>
|
||||||
|
<ImageMetadataActions metadata={metadata} />
|
||||||
|
</ScrollableContent>
|
||||||
|
) : (
|
||||||
|
<IAINoContentFallback label={t('metadata.noRecallParameters')} />
|
||||||
|
)}
|
||||||
|
</TabPanel>
|
||||||
<TabPanel>
|
<TabPanel>
|
||||||
{metadata ? (
|
{metadata ? (
|
||||||
<DataViewer data={metadata} label={t('metadata.metadata')} />
|
<DataViewer data={metadata} label={t('metadata.metadata')} />
|
||||||
|
@ -0,0 +1,247 @@
|
|||||||
|
import { RootState } from 'app/store/store';
|
||||||
|
import { NonNullableGraph } from 'features/nodes/types/types';
|
||||||
|
import {
|
||||||
|
DenoiseLatentsInvocation,
|
||||||
|
ResizeLatentsInvocation,
|
||||||
|
NoiseInvocation,
|
||||||
|
LatentsToImageInvocation,
|
||||||
|
Edge,
|
||||||
|
} from 'services/api/types';
|
||||||
|
import {
|
||||||
|
LATENTS_TO_IMAGE,
|
||||||
|
DENOISE_LATENTS,
|
||||||
|
NOISE,
|
||||||
|
MAIN_MODEL_LOADER,
|
||||||
|
METADATA_ACCUMULATOR,
|
||||||
|
LATENTS_TO_IMAGE_HRF,
|
||||||
|
DENOISE_LATENTS_HRF,
|
||||||
|
RESCALE_LATENTS,
|
||||||
|
NOISE_HRF,
|
||||||
|
VAE_LOADER,
|
||||||
|
} from './constants';
|
||||||
|
import { logger } from 'app/logging/logger';
|
||||||
|
|
||||||
|
// Copy certain connections from previous DENOISE_LATENTS to new DENOISE_LATENTS_HRF.
|
||||||
|
function copyConnectionsToDenoiseLatentsHrf(graph: NonNullableGraph): void {
|
||||||
|
const destinationFields = [
|
||||||
|
'vae',
|
||||||
|
'control',
|
||||||
|
'ip_adapter',
|
||||||
|
'metadata',
|
||||||
|
'unet',
|
||||||
|
'positive_conditioning',
|
||||||
|
'negative_conditioning',
|
||||||
|
];
|
||||||
|
const newEdges: Edge[] = [];
|
||||||
|
|
||||||
|
// Loop through the existing edges connected to DENOISE_LATENTS
|
||||||
|
graph.edges.forEach((edge: Edge) => {
|
||||||
|
if (
|
||||||
|
edge.destination.node_id === DENOISE_LATENTS &&
|
||||||
|
destinationFields.includes(edge.destination.field)
|
||||||
|
) {
|
||||||
|
// Add a similar connection to DENOISE_LATENTS_HRF
|
||||||
|
newEdges.push({
|
||||||
|
source: {
|
||||||
|
node_id: edge.source.node_id,
|
||||||
|
field: edge.source.field,
|
||||||
|
},
|
||||||
|
destination: {
|
||||||
|
node_id: DENOISE_LATENTS_HRF,
|
||||||
|
field: edge.destination.field,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
graph.edges = graph.edges.concat(newEdges);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds the high-res fix feature to the given graph.
|
||||||
|
export const addHrfToGraph = (
|
||||||
|
state: RootState,
|
||||||
|
graph: NonNullableGraph
|
||||||
|
): void => {
|
||||||
|
// Double check hrf is enabled.
|
||||||
|
if (
|
||||||
|
!state.generation.hrfEnabled ||
|
||||||
|
state.config.disabledSDFeatures.includes('hrf') ||
|
||||||
|
state.generation.model?.model_type === 'onnx' // TODO: ONNX support
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const log = logger('txt2img');
|
||||||
|
|
||||||
|
const { vae } = state.generation;
|
||||||
|
const isAutoVae = !vae;
|
||||||
|
const hrfWidth = state.generation.hrfWidth;
|
||||||
|
const hrfHeight = state.generation.hrfHeight;
|
||||||
|
|
||||||
|
// Pre-existing (original) graph nodes.
|
||||||
|
const originalDenoiseLatentsNode = graph.nodes[DENOISE_LATENTS] as
|
||||||
|
| DenoiseLatentsInvocation
|
||||||
|
| undefined;
|
||||||
|
const originalNoiseNode = graph.nodes[NOISE] as NoiseInvocation | undefined;
|
||||||
|
// Original latents to image should pick this up.
|
||||||
|
const originalLatentsToImageNode = graph.nodes[LATENTS_TO_IMAGE] as
|
||||||
|
| LatentsToImageInvocation
|
||||||
|
| undefined;
|
||||||
|
// Check if originalDenoiseLatentsNode is undefined and log an error
|
||||||
|
if (!originalDenoiseLatentsNode) {
|
||||||
|
log.error('originalDenoiseLatentsNode is undefined');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Check if originalNoiseNode is undefined and log an error
|
||||||
|
if (!originalNoiseNode) {
|
||||||
|
log.error('originalNoiseNode is undefined');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if originalLatentsToImageNode is undefined and log an error
|
||||||
|
if (!originalLatentsToImageNode) {
|
||||||
|
log.error('originalLatentsToImageNode is undefined');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Change height and width of original noise node to initial resolution.
|
||||||
|
if (originalNoiseNode) {
|
||||||
|
originalNoiseNode.width = hrfWidth;
|
||||||
|
originalNoiseNode.height = hrfHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define new nodes.
|
||||||
|
// Denoise latents node to be run on upscaled latents.
|
||||||
|
const denoiseLatentsHrfNode: DenoiseLatentsInvocation = {
|
||||||
|
type: 'denoise_latents',
|
||||||
|
id: DENOISE_LATENTS_HRF,
|
||||||
|
is_intermediate: originalDenoiseLatentsNode?.is_intermediate,
|
||||||
|
cfg_scale: originalDenoiseLatentsNode?.cfg_scale,
|
||||||
|
scheduler: originalDenoiseLatentsNode?.scheduler,
|
||||||
|
steps: originalDenoiseLatentsNode?.steps,
|
||||||
|
denoising_start: 1 - state.generation.hrfStrength,
|
||||||
|
denoising_end: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
// New base resolution noise node.
|
||||||
|
const hrfNoiseNode: NoiseInvocation = {
|
||||||
|
type: 'noise',
|
||||||
|
id: NOISE_HRF,
|
||||||
|
seed: originalNoiseNode?.seed,
|
||||||
|
use_cpu: originalNoiseNode?.use_cpu,
|
||||||
|
is_intermediate: originalNoiseNode?.is_intermediate,
|
||||||
|
};
|
||||||
|
|
||||||
|
const rescaleLatentsNode: ResizeLatentsInvocation = {
|
||||||
|
id: RESCALE_LATENTS,
|
||||||
|
type: 'lresize',
|
||||||
|
width: state.generation.width,
|
||||||
|
height: state.generation.height,
|
||||||
|
};
|
||||||
|
|
||||||
|
// New node to convert latents to image.
|
||||||
|
const latentsToImageHrfNode: LatentsToImageInvocation | undefined =
|
||||||
|
originalLatentsToImageNode
|
||||||
|
? {
|
||||||
|
type: 'l2i',
|
||||||
|
id: LATENTS_TO_IMAGE_HRF,
|
||||||
|
fp32: originalLatentsToImageNode?.fp32,
|
||||||
|
is_intermediate: originalLatentsToImageNode?.is_intermediate,
|
||||||
|
}
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
// Add new nodes to graph.
|
||||||
|
graph.nodes[LATENTS_TO_IMAGE_HRF] =
|
||||||
|
latentsToImageHrfNode as LatentsToImageInvocation;
|
||||||
|
graph.nodes[DENOISE_LATENTS_HRF] =
|
||||||
|
denoiseLatentsHrfNode as DenoiseLatentsInvocation;
|
||||||
|
graph.nodes[NOISE_HRF] = hrfNoiseNode as NoiseInvocation;
|
||||||
|
graph.nodes[RESCALE_LATENTS] = rescaleLatentsNode as ResizeLatentsInvocation;
|
||||||
|
|
||||||
|
// Connect nodes.
|
||||||
|
graph.edges.push(
|
||||||
|
{
|
||||||
|
// Set up rescale latents.
|
||||||
|
source: {
|
||||||
|
node_id: DENOISE_LATENTS,
|
||||||
|
field: 'latents',
|
||||||
|
},
|
||||||
|
destination: {
|
||||||
|
node_id: RESCALE_LATENTS,
|
||||||
|
field: 'latents',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Set up new noise node
|
||||||
|
{
|
||||||
|
source: {
|
||||||
|
node_id: RESCALE_LATENTS,
|
||||||
|
field: 'height',
|
||||||
|
},
|
||||||
|
destination: {
|
||||||
|
node_id: NOISE_HRF,
|
||||||
|
field: 'height',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: {
|
||||||
|
node_id: RESCALE_LATENTS,
|
||||||
|
field: 'width',
|
||||||
|
},
|
||||||
|
destination: {
|
||||||
|
node_id: NOISE_HRF,
|
||||||
|
field: 'width',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Set up new denoise node.
|
||||||
|
{
|
||||||
|
source: {
|
||||||
|
node_id: RESCALE_LATENTS,
|
||||||
|
field: 'latents',
|
||||||
|
},
|
||||||
|
destination: {
|
||||||
|
node_id: DENOISE_LATENTS_HRF,
|
||||||
|
field: 'latents',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: {
|
||||||
|
node_id: NOISE_HRF,
|
||||||
|
field: 'noise',
|
||||||
|
},
|
||||||
|
destination: {
|
||||||
|
node_id: DENOISE_LATENTS_HRF,
|
||||||
|
field: 'noise',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Set up new latents to image node.
|
||||||
|
{
|
||||||
|
source: {
|
||||||
|
node_id: DENOISE_LATENTS_HRF,
|
||||||
|
field: 'latents',
|
||||||
|
},
|
||||||
|
destination: {
|
||||||
|
node_id: LATENTS_TO_IMAGE_HRF,
|
||||||
|
field: 'latents',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: {
|
||||||
|
node_id: METADATA_ACCUMULATOR,
|
||||||
|
field: 'metadata',
|
||||||
|
},
|
||||||
|
destination: {
|
||||||
|
node_id: LATENTS_TO_IMAGE_HRF,
|
||||||
|
field: 'metadata',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: {
|
||||||
|
node_id: isAutoVae ? MAIN_MODEL_LOADER : VAE_LOADER,
|
||||||
|
field: 'vae',
|
||||||
|
},
|
||||||
|
destination: {
|
||||||
|
node_id: LATENTS_TO_IMAGE_HRF,
|
||||||
|
field: 'vae',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
copyConnectionsToDenoiseLatentsHrf(graph);
|
||||||
|
};
|
@ -2,6 +2,7 @@ import { NonNullableGraph } from 'features/nodes/types/types';
|
|||||||
import {
|
import {
|
||||||
CANVAS_OUTPUT,
|
CANVAS_OUTPUT,
|
||||||
LATENTS_TO_IMAGE,
|
LATENTS_TO_IMAGE,
|
||||||
|
LATENTS_TO_IMAGE_HRF,
|
||||||
METADATA_ACCUMULATOR,
|
METADATA_ACCUMULATOR,
|
||||||
NSFW_CHECKER,
|
NSFW_CHECKER,
|
||||||
SAVE_IMAGE,
|
SAVE_IMAGE,
|
||||||
@ -82,6 +83,14 @@ export const addSaveImageNode = (
|
|||||||
},
|
},
|
||||||
destination,
|
destination,
|
||||||
});
|
});
|
||||||
|
} else if (LATENTS_TO_IMAGE_HRF in graph.nodes) {
|
||||||
|
graph.edges.push({
|
||||||
|
source: {
|
||||||
|
node_id: LATENTS_TO_IMAGE_HRF,
|
||||||
|
field: 'image',
|
||||||
|
},
|
||||||
|
destination,
|
||||||
|
});
|
||||||
} else if (LATENTS_TO_IMAGE in graph.nodes) {
|
} else if (LATENTS_TO_IMAGE in graph.nodes) {
|
||||||
graph.edges.push({
|
graph.edges.push({
|
||||||
source: {
|
source: {
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
ONNXTextToLatentsInvocation,
|
ONNXTextToLatentsInvocation,
|
||||||
} from 'services/api/types';
|
} from 'services/api/types';
|
||||||
import { addControlNetToLinearGraph } from './addControlNetToLinearGraph';
|
import { addControlNetToLinearGraph } from './addControlNetToLinearGraph';
|
||||||
|
import { addHrfToGraph } from './addHrfToGraph';
|
||||||
import { addIPAdapterToLinearGraph } from './addIPAdapterToLinearGraph';
|
import { addIPAdapterToLinearGraph } from './addIPAdapterToLinearGraph';
|
||||||
import { addLoRAsToGraph } from './addLoRAsToGraph';
|
import { addLoRAsToGraph } from './addLoRAsToGraph';
|
||||||
import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph';
|
import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph';
|
||||||
@ -47,6 +48,10 @@ export const buildLinearTextToImageGraph = (
|
|||||||
seamlessXAxis,
|
seamlessXAxis,
|
||||||
seamlessYAxis,
|
seamlessYAxis,
|
||||||
seed,
|
seed,
|
||||||
|
hrfWidth,
|
||||||
|
hrfHeight,
|
||||||
|
hrfStrength,
|
||||||
|
hrfEnabled: hrfEnabled,
|
||||||
} = state.generation;
|
} = state.generation;
|
||||||
|
|
||||||
const use_cpu = shouldUseCpuNoise;
|
const use_cpu = shouldUseCpuNoise;
|
||||||
@ -254,6 +259,9 @@ export const buildLinearTextToImageGraph = (
|
|||||||
ipAdapters: [], // populated in addIPAdapterToLinearGraph
|
ipAdapters: [], // populated in addIPAdapterToLinearGraph
|
||||||
t2iAdapters: [], // populated in addT2IAdapterToLinearGraph
|
t2iAdapters: [], // populated in addT2IAdapterToLinearGraph
|
||||||
clip_skip: clipSkip,
|
clip_skip: clipSkip,
|
||||||
|
hrf_width: hrfEnabled ? hrfWidth : undefined,
|
||||||
|
hrf_height: hrfEnabled ? hrfHeight : undefined,
|
||||||
|
hrf_strength: hrfEnabled ? hrfStrength : undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
graph.edges.push({
|
graph.edges.push({
|
||||||
@ -287,6 +295,12 @@ export const buildLinearTextToImageGraph = (
|
|||||||
|
|
||||||
addT2IAdaptersToLinearGraph(state, graph, DENOISE_LATENTS);
|
addT2IAdaptersToLinearGraph(state, graph, DENOISE_LATENTS);
|
||||||
|
|
||||||
|
// High resolution fix.
|
||||||
|
// NOTE: Not supported for onnx models.
|
||||||
|
if (state.generation.hrfEnabled && !isUsingOnnxModel) {
|
||||||
|
addHrfToGraph(state, graph);
|
||||||
|
}
|
||||||
|
|
||||||
// NSFW & watermark - must be last thing added to graph
|
// NSFW & watermark - must be last thing added to graph
|
||||||
if (state.system.shouldUseNSFWChecker) {
|
if (state.system.shouldUseNSFWChecker) {
|
||||||
// must add before watermarker!
|
// must add before watermarker!
|
||||||
|
@ -2,11 +2,14 @@
|
|||||||
export const POSITIVE_CONDITIONING = 'positive_conditioning';
|
export const POSITIVE_CONDITIONING = 'positive_conditioning';
|
||||||
export const NEGATIVE_CONDITIONING = 'negative_conditioning';
|
export const NEGATIVE_CONDITIONING = 'negative_conditioning';
|
||||||
export const DENOISE_LATENTS = 'denoise_latents';
|
export const DENOISE_LATENTS = 'denoise_latents';
|
||||||
|
export const DENOISE_LATENTS_HRF = 'denoise_latents_hrf';
|
||||||
export const LATENTS_TO_IMAGE = 'latents_to_image';
|
export const LATENTS_TO_IMAGE = 'latents_to_image';
|
||||||
|
export const LATENTS_TO_IMAGE_HRF = 'latents_to_image_hrf';
|
||||||
export const SAVE_IMAGE = 'save_image';
|
export const SAVE_IMAGE = 'save_image';
|
||||||
export const NSFW_CHECKER = 'nsfw_checker';
|
export const NSFW_CHECKER = 'nsfw_checker';
|
||||||
export const WATERMARKER = 'invisible_watermark';
|
export const WATERMARKER = 'invisible_watermark';
|
||||||
export const NOISE = 'noise';
|
export const NOISE = 'noise';
|
||||||
|
export const NOISE_HRF = 'noise_hrf';
|
||||||
export const RANDOM_INT = 'rand_int';
|
export const RANDOM_INT = 'rand_int';
|
||||||
export const RANGE_OF_SIZE = 'range_of_size';
|
export const RANGE_OF_SIZE = 'range_of_size';
|
||||||
export const ITERATE = 'iterate';
|
export const ITERATE = 'iterate';
|
||||||
@ -18,6 +21,7 @@ export const CLIP_SKIP = 'clip_skip';
|
|||||||
export const IMAGE_TO_LATENTS = 'image_to_latents';
|
export const IMAGE_TO_LATENTS = 'image_to_latents';
|
||||||
export const LATENTS_TO_LATENTS = 'latents_to_latents';
|
export const LATENTS_TO_LATENTS = 'latents_to_latents';
|
||||||
export const RESIZE = 'resize_image';
|
export const RESIZE = 'resize_image';
|
||||||
|
export const RESCALE_LATENTS = 'rescale_latents';
|
||||||
export const IMG2IMG_RESIZE = 'img2img_resize';
|
export const IMG2IMG_RESIZE = 'img2img_resize';
|
||||||
export const CANVAS_OUTPUT = 'canvas_output';
|
export const CANVAS_OUTPUT = 'canvas_output';
|
||||||
export const INPAINT_IMAGE = 'inpaint_image';
|
export const INPAINT_IMAGE = 'inpaint_image';
|
||||||
|
@ -0,0 +1,65 @@
|
|||||||
|
import { Flex } from '@chakra-ui/react';
|
||||||
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
|
import { RootState, stateSelector } from 'app/store/store';
|
||||||
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||||
|
import IAICollapse from 'common/components/IAICollapse';
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
import ParamHrfStrength from './ParamHrfStrength';
|
||||||
|
import ParamHrfToggle from './ParamHrfToggle';
|
||||||
|
import ParamHrfWidth from './ParamHrfWidth';
|
||||||
|
import ParamHrfHeight from './ParamHrfHeight';
|
||||||
|
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
||||||
|
|
||||||
|
const selector = createSelector(
|
||||||
|
stateSelector,
|
||||||
|
(state: RootState) => {
|
||||||
|
const { hrfEnabled } = state.generation;
|
||||||
|
|
||||||
|
return { hrfEnabled };
|
||||||
|
},
|
||||||
|
defaultSelectorOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
export default function ParamHrfCollapse() {
|
||||||
|
const isHRFFeatureEnabled = useFeatureStatus('hrf').isFeatureEnabled;
|
||||||
|
const { hrfEnabled } = useAppSelector(selector);
|
||||||
|
const activeLabel = useMemo(() => {
|
||||||
|
if (hrfEnabled) {
|
||||||
|
return 'On';
|
||||||
|
} else {
|
||||||
|
return 'Off';
|
||||||
|
}
|
||||||
|
}, [hrfEnabled]);
|
||||||
|
|
||||||
|
if (!isHRFFeatureEnabled) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IAICollapse label="High Resolution Fix" activeLabel={activeLabel}>
|
||||||
|
<Flex sx={{ flexDir: 'column', gap: 2 }}>
|
||||||
|
<ParamHrfToggle />
|
||||||
|
{hrfEnabled && (
|
||||||
|
<Flex
|
||||||
|
sx={{
|
||||||
|
gap: 2,
|
||||||
|
p: 4,
|
||||||
|
borderRadius: 4,
|
||||||
|
flexDirection: 'column',
|
||||||
|
w: 'full',
|
||||||
|
bg: 'base.100',
|
||||||
|
_dark: {
|
||||||
|
bg: 'base.750',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ParamHrfWidth />
|
||||||
|
<ParamHrfHeight />
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
{hrfEnabled && <ParamHrfStrength />}
|
||||||
|
</Flex>
|
||||||
|
</IAICollapse>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
|
import { stateSelector } from 'app/store/store';
|
||||||
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||||
|
import IAISlider, { IAIFullSliderProps } from 'common/components/IAISlider';
|
||||||
|
import { roundToMultiple } from 'common/util/roundDownToMultiple';
|
||||||
|
import {
|
||||||
|
setHrfHeight,
|
||||||
|
setHrfWidth,
|
||||||
|
} from 'features/parameters/store/generationSlice';
|
||||||
|
import { memo, useCallback } from 'react';
|
||||||
|
|
||||||
|
function findPrevMultipleOfEight(n: number): number {
|
||||||
|
return Math.floor((n - 1) / 8) * 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
const selector = createSelector(
|
||||||
|
[stateSelector],
|
||||||
|
({ generation, hotkeys, config }) => {
|
||||||
|
const { min, fineStep, coarseStep } = config.sd.height;
|
||||||
|
const { model, height, hrfHeight, aspectRatio, hrfEnabled } = generation;
|
||||||
|
|
||||||
|
const step = hotkeys.shift ? fineStep : coarseStep;
|
||||||
|
|
||||||
|
return {
|
||||||
|
model,
|
||||||
|
height,
|
||||||
|
hrfHeight,
|
||||||
|
min,
|
||||||
|
step,
|
||||||
|
aspectRatio,
|
||||||
|
hrfEnabled,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
defaultSelectorOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
type ParamHeightProps = Omit<
|
||||||
|
IAIFullSliderProps,
|
||||||
|
'label' | 'value' | 'onChange'
|
||||||
|
>;
|
||||||
|
|
||||||
|
const ParamHrfHeight = (props: ParamHeightProps) => {
|
||||||
|
const { height, hrfHeight, min, step, aspectRatio, hrfEnabled } =
|
||||||
|
useAppSelector(selector);
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const maxHrfHeight = Math.max(findPrevMultipleOfEight(height), min);
|
||||||
|
|
||||||
|
const handleChange = useCallback(
|
||||||
|
(v: number) => {
|
||||||
|
dispatch(setHrfHeight(v));
|
||||||
|
if (aspectRatio) {
|
||||||
|
const newWidth = roundToMultiple(v * aspectRatio, 8);
|
||||||
|
dispatch(setHrfWidth(newWidth));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[dispatch, aspectRatio]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleReset = useCallback(() => {
|
||||||
|
dispatch(setHrfHeight(maxHrfHeight));
|
||||||
|
if (aspectRatio) {
|
||||||
|
const newWidth = roundToMultiple(maxHrfHeight * aspectRatio, 8);
|
||||||
|
dispatch(setHrfWidth(newWidth));
|
||||||
|
}
|
||||||
|
}, [dispatch, maxHrfHeight, aspectRatio]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IAISlider
|
||||||
|
label="Initial Height"
|
||||||
|
value={hrfHeight}
|
||||||
|
min={min}
|
||||||
|
step={step}
|
||||||
|
max={maxHrfHeight}
|
||||||
|
onChange={handleChange}
|
||||||
|
handleReset={handleReset}
|
||||||
|
withInput
|
||||||
|
withReset
|
||||||
|
withSliderMarks
|
||||||
|
sliderNumberInputProps={{ max: maxHrfHeight }}
|
||||||
|
isDisabled={!hrfEnabled}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(ParamHrfHeight);
|
@ -0,0 +1,64 @@
|
|||||||
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
|
import { useAppSelector, useAppDispatch } from 'app/store/storeHooks';
|
||||||
|
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||||
|
import { memo, useCallback } from 'react';
|
||||||
|
import { stateSelector } from 'app/store/store';
|
||||||
|
import { setHrfStrength } from 'features/parameters/store/generationSlice';
|
||||||
|
import IAISlider from 'common/components/IAISlider';
|
||||||
|
|
||||||
|
const selector = createSelector(
|
||||||
|
[stateSelector],
|
||||||
|
({ generation, hotkeys, config }) => {
|
||||||
|
const { initial, min, sliderMax, inputMax, fineStep, coarseStep } =
|
||||||
|
config.sd.hrfStrength;
|
||||||
|
const { hrfStrength, hrfEnabled } = generation;
|
||||||
|
const step = hotkeys.shift ? fineStep : coarseStep;
|
||||||
|
|
||||||
|
return {
|
||||||
|
hrfStrength,
|
||||||
|
initial,
|
||||||
|
min,
|
||||||
|
sliderMax,
|
||||||
|
inputMax,
|
||||||
|
step,
|
||||||
|
hrfEnabled,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
defaultSelectorOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
const ParamHrfStrength = () => {
|
||||||
|
const { hrfStrength, initial, min, sliderMax, step, hrfEnabled } =
|
||||||
|
useAppSelector(selector);
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
const handleHrfStrengthReset = useCallback(() => {
|
||||||
|
dispatch(setHrfStrength(initial));
|
||||||
|
}, [dispatch, initial]);
|
||||||
|
|
||||||
|
const handleHrfStrengthChange = useCallback(
|
||||||
|
(v: number) => {
|
||||||
|
dispatch(setHrfStrength(v));
|
||||||
|
},
|
||||||
|
[dispatch]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IAISlider
|
||||||
|
label="Denoising Strength"
|
||||||
|
aria-label="High Resolution Denoising Strength"
|
||||||
|
min={min}
|
||||||
|
max={sliderMax}
|
||||||
|
step={step}
|
||||||
|
value={hrfStrength}
|
||||||
|
onChange={handleHrfStrengthChange}
|
||||||
|
withSliderMarks
|
||||||
|
withInput
|
||||||
|
withReset
|
||||||
|
handleReset={handleHrfStrengthReset}
|
||||||
|
isDisabled={!hrfEnabled}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(ParamHrfStrength);
|
@ -0,0 +1,27 @@
|
|||||||
|
import { RootState } from 'app/store/store';
|
||||||
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import IAISwitch from 'common/components/IAISwitch';
|
||||||
|
import { setHrfEnabled } from 'features/parameters/store/generationSlice';
|
||||||
|
import { ChangeEvent, useCallback } from 'react';
|
||||||
|
|
||||||
|
export default function ParamHrfToggle() {
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
const hrfEnabled = useAppSelector(
|
||||||
|
(state: RootState) => state.generation.hrfEnabled
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleHrfEnabled = useCallback(
|
||||||
|
(e: ChangeEvent<HTMLInputElement>) =>
|
||||||
|
dispatch(setHrfEnabled(e.target.checked)),
|
||||||
|
[dispatch]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IAISwitch
|
||||||
|
label="Enable High Resolution Fix"
|
||||||
|
isChecked={hrfEnabled}
|
||||||
|
onChange={handleHrfEnabled}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
|
import { stateSelector } from 'app/store/store';
|
||||||
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||||
|
import IAISlider, { IAIFullSliderProps } from 'common/components/IAISlider';
|
||||||
|
import { roundToMultiple } from 'common/util/roundDownToMultiple';
|
||||||
|
import {
|
||||||
|
setHrfHeight,
|
||||||
|
setHrfWidth,
|
||||||
|
} from 'features/parameters/store/generationSlice';
|
||||||
|
import { memo, useCallback } from 'react';
|
||||||
|
|
||||||
|
function findPrevMultipleOfEight(n: number): number {
|
||||||
|
return Math.floor((n - 1) / 8) * 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
const selector = createSelector(
|
||||||
|
[stateSelector],
|
||||||
|
({ generation, hotkeys, config }) => {
|
||||||
|
const { min, fineStep, coarseStep } = config.sd.width;
|
||||||
|
const { model, width, hrfWidth, aspectRatio, hrfEnabled } = generation;
|
||||||
|
|
||||||
|
const step = hotkeys.shift ? fineStep : coarseStep;
|
||||||
|
|
||||||
|
return {
|
||||||
|
model,
|
||||||
|
width,
|
||||||
|
hrfWidth,
|
||||||
|
min,
|
||||||
|
step,
|
||||||
|
aspectRatio,
|
||||||
|
hrfEnabled,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
defaultSelectorOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
type ParamWidthProps = Omit<IAIFullSliderProps, 'label' | 'value' | 'onChange'>;
|
||||||
|
|
||||||
|
const ParamHrfWidth = (props: ParamWidthProps) => {
|
||||||
|
const { width, hrfWidth, min, step, aspectRatio, hrfEnabled } =
|
||||||
|
useAppSelector(selector);
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const maxHrfWidth = Math.max(findPrevMultipleOfEight(width), min);
|
||||||
|
|
||||||
|
const handleChange = useCallback(
|
||||||
|
(v: number) => {
|
||||||
|
dispatch(setHrfWidth(v));
|
||||||
|
if (aspectRatio) {
|
||||||
|
const newHeight = roundToMultiple(v / aspectRatio, 8);
|
||||||
|
dispatch(setHrfHeight(newHeight));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[dispatch, aspectRatio]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleReset = useCallback(() => {
|
||||||
|
dispatch(setHrfWidth(maxHrfWidth));
|
||||||
|
if (aspectRatio) {
|
||||||
|
const newHeight = roundToMultiple(maxHrfWidth / aspectRatio, 8);
|
||||||
|
dispatch(setHrfHeight(newHeight));
|
||||||
|
}
|
||||||
|
}, [dispatch, maxHrfWidth, aspectRatio]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IAISlider
|
||||||
|
label="Initial Width"
|
||||||
|
value={hrfWidth}
|
||||||
|
min={min}
|
||||||
|
step={step}
|
||||||
|
max={maxHrfWidth}
|
||||||
|
onChange={handleChange}
|
||||||
|
handleReset={handleReset}
|
||||||
|
withInput
|
||||||
|
withReset
|
||||||
|
withSliderMarks
|
||||||
|
sliderNumberInputProps={{ max: maxHrfWidth }}
|
||||||
|
isDisabled={!hrfEnabled}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(ParamHrfWidth);
|
@ -27,6 +27,10 @@ import {
|
|||||||
} from '../types/parameterSchemas';
|
} from '../types/parameterSchemas';
|
||||||
|
|
||||||
export interface GenerationState {
|
export interface GenerationState {
|
||||||
|
hrfHeight: HeightParam;
|
||||||
|
hrfWidth: WidthParam;
|
||||||
|
hrfEnabled: boolean;
|
||||||
|
hrfStrength: StrengthParam;
|
||||||
cfgScale: CfgScaleParam;
|
cfgScale: CfgScaleParam;
|
||||||
height: HeightParam;
|
height: HeightParam;
|
||||||
img2imgStrength: StrengthParam;
|
img2imgStrength: StrengthParam;
|
||||||
@ -69,6 +73,10 @@ export interface GenerationState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const initialGenerationState: GenerationState = {
|
export const initialGenerationState: GenerationState = {
|
||||||
|
hrfHeight: 64,
|
||||||
|
hrfWidth: 64,
|
||||||
|
hrfStrength: 0.75,
|
||||||
|
hrfEnabled: false,
|
||||||
cfgScale: 7.5,
|
cfgScale: 7.5,
|
||||||
height: 512,
|
height: 512,
|
||||||
img2imgStrength: 0.75,
|
img2imgStrength: 0.75,
|
||||||
@ -271,6 +279,18 @@ export const generationSlice = createSlice({
|
|||||||
setClipSkip: (state, action: PayloadAction<number>) => {
|
setClipSkip: (state, action: PayloadAction<number>) => {
|
||||||
state.clipSkip = action.payload;
|
state.clipSkip = action.payload;
|
||||||
},
|
},
|
||||||
|
setHrfHeight: (state, action: PayloadAction<number>) => {
|
||||||
|
state.hrfHeight = action.payload;
|
||||||
|
},
|
||||||
|
setHrfWidth: (state, action: PayloadAction<number>) => {
|
||||||
|
state.hrfWidth = action.payload;
|
||||||
|
},
|
||||||
|
setHrfStrength: (state, action: PayloadAction<number>) => {
|
||||||
|
state.hrfStrength = action.payload;
|
||||||
|
},
|
||||||
|
setHrfEnabled: (state, action: PayloadAction<boolean>) => {
|
||||||
|
state.hrfEnabled = action.payload;
|
||||||
|
},
|
||||||
shouldUseCpuNoiseChanged: (state, action: PayloadAction<boolean>) => {
|
shouldUseCpuNoiseChanged: (state, action: PayloadAction<boolean>) => {
|
||||||
state.shouldUseCpuNoise = action.payload;
|
state.shouldUseCpuNoise = action.payload;
|
||||||
},
|
},
|
||||||
@ -355,6 +375,10 @@ export const {
|
|||||||
setSeamlessXAxis,
|
setSeamlessXAxis,
|
||||||
setSeamlessYAxis,
|
setSeamlessYAxis,
|
||||||
setClipSkip,
|
setClipSkip,
|
||||||
|
setHrfHeight,
|
||||||
|
setHrfWidth,
|
||||||
|
setHrfStrength,
|
||||||
|
setHrfEnabled,
|
||||||
shouldUseCpuNoiseChanged,
|
shouldUseCpuNoiseChanged,
|
||||||
setAspectRatio,
|
setAspectRatio,
|
||||||
setShouldLockAspectRatio,
|
setShouldLockAspectRatio,
|
||||||
|
@ -210,6 +210,15 @@ export type HeightParam = z.infer<typeof zHeight>;
|
|||||||
export const isValidHeight = (val: unknown): val is HeightParam =>
|
export const isValidHeight = (val: unknown): val is HeightParam =>
|
||||||
zHeight.safeParse(val).success;
|
zHeight.safeParse(val).success;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zod schema for resolution parameter
|
||||||
|
*/
|
||||||
|
export const zResolution = z.tuple([zWidth, zHeight]);
|
||||||
|
/**
|
||||||
|
* Type alias for resolution parameter, inferred from its zod schema
|
||||||
|
*/
|
||||||
|
export type ResolutionParam = z.infer<typeof zResolution>;
|
||||||
|
|
||||||
export const zBaseModel = z.enum([
|
export const zBaseModel = z.enum([
|
||||||
'any',
|
'any',
|
||||||
'sd-1',
|
'sd-1',
|
||||||
|
@ -69,6 +69,14 @@ export const initialConfigState: AppConfig = {
|
|||||||
fineStep: 0.01,
|
fineStep: 0.01,
|
||||||
coarseStep: 0.05,
|
coarseStep: 0.05,
|
||||||
},
|
},
|
||||||
|
hrfStrength: {
|
||||||
|
initial: 0.7,
|
||||||
|
min: 0,
|
||||||
|
sliderMax: 1,
|
||||||
|
inputMax: 1,
|
||||||
|
fineStep: 0.01,
|
||||||
|
coarseStep: 0.05,
|
||||||
|
},
|
||||||
dynamicPrompts: {
|
dynamicPrompts: {
|
||||||
maxPrompts: {
|
maxPrompts: {
|
||||||
initial: 100,
|
initial: 100,
|
||||||
|
@ -3,6 +3,7 @@ import ParamLoraCollapse from 'features/lora/components/ParamLoraCollapse';
|
|||||||
import ParamAdvancedCollapse from 'features/parameters/components/Parameters/Advanced/ParamAdvancedCollapse';
|
import ParamAdvancedCollapse from 'features/parameters/components/Parameters/Advanced/ParamAdvancedCollapse';
|
||||||
import ControlAdaptersCollapse from 'features/controlAdapters/components/ControlAdaptersCollapse';
|
import ControlAdaptersCollapse from 'features/controlAdapters/components/ControlAdaptersCollapse';
|
||||||
import ParamSymmetryCollapse from 'features/parameters/components/Parameters/Symmetry/ParamSymmetryCollapse';
|
import ParamSymmetryCollapse from 'features/parameters/components/Parameters/Symmetry/ParamSymmetryCollapse';
|
||||||
|
import ParamHrfCollapse from 'features/parameters/components/Parameters/HighResFix/ParamHrfCollapse';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import ParamPromptArea from '../../../../parameters/components/Parameters/Prompt/ParamPromptArea';
|
import ParamPromptArea from '../../../../parameters/components/Parameters/Prompt/ParamPromptArea';
|
||||||
import TextToImageTabCoreParameters from './TextToImageTabCoreParameters';
|
import TextToImageTabCoreParameters from './TextToImageTabCoreParameters';
|
||||||
@ -16,6 +17,7 @@ const TextToImageTabParameters = () => {
|
|||||||
<ParamLoraCollapse />
|
<ParamLoraCollapse />
|
||||||
<ParamDynamicPromptsCollapse />
|
<ParamDynamicPromptsCollapse />
|
||||||
<ParamSymmetryCollapse />
|
<ParamSymmetryCollapse />
|
||||||
|
<ParamHrfCollapse />
|
||||||
<ParamAdvancedCollapse />
|
<ParamAdvancedCollapse />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -6190,6 +6190,21 @@ export type components = {
|
|||||||
* @description The VAE used for decoding, if the main model's default was not used
|
* @description The VAE used for decoding, if the main model's default was not used
|
||||||
*/
|
*/
|
||||||
vae?: components["schemas"]["VAEModelField"];
|
vae?: components["schemas"]["VAEModelField"];
|
||||||
|
/**
|
||||||
|
* High Resolution Fix Width
|
||||||
|
* @description The high resolution fix height and width multiplier.
|
||||||
|
*/
|
||||||
|
hrf_width?: number;
|
||||||
|
/**
|
||||||
|
* High Resolution Fix Height
|
||||||
|
* @description The high resolution fix height and width multiplier.
|
||||||
|
*/
|
||||||
|
hrf_height?: number;
|
||||||
|
/**
|
||||||
|
* High Resolution Strength
|
||||||
|
* @description The high resolution fix img2img strength used in the upscale pass.
|
||||||
|
*/
|
||||||
|
hrf_strength?: number;
|
||||||
/**
|
/**
|
||||||
* Positive Style Prompt
|
* Positive Style Prompt
|
||||||
* @description The positive style prompt parameter
|
* @description The positive style prompt parameter
|
||||||
|
@ -137,6 +137,7 @@ export type CompelInvocation = s['CompelInvocation'];
|
|||||||
export type DynamicPromptInvocation = s['DynamicPromptInvocation'];
|
export type DynamicPromptInvocation = s['DynamicPromptInvocation'];
|
||||||
export type NoiseInvocation = s['NoiseInvocation'];
|
export type NoiseInvocation = s['NoiseInvocation'];
|
||||||
export type DenoiseLatentsInvocation = s['DenoiseLatentsInvocation'];
|
export type DenoiseLatentsInvocation = s['DenoiseLatentsInvocation'];
|
||||||
|
export type ResizeLatentsInvocation = s['ResizeLatentsInvocation'];
|
||||||
export type ONNXTextToLatentsInvocation = s['ONNXTextToLatentsInvocation'];
|
export type ONNXTextToLatentsInvocation = s['ONNXTextToLatentsInvocation'];
|
||||||
export type SDXLLoraLoaderInvocation = s['SDXLLoraLoaderInvocation'];
|
export type SDXLLoraLoaderInvocation = s['SDXLLoraLoaderInvocation'];
|
||||||
export type ImageToLatentsInvocation = s['ImageToLatentsInvocation'];
|
export type ImageToLatentsInvocation = s['ImageToLatentsInvocation'];
|
||||||
|
Loading…
Reference in New Issue
Block a user