diff --git a/docs/converting-models.md b/docs/converting-models.md index 26cba85c..7b3d8e68 100644 --- a/docs/converting-models.md +++ b/docs/converting-models.md @@ -22,7 +22,7 @@ You can start from a diffusers directory, HuggingFace Hub repository, or an SD c 1. LoRA weights from `kohya-ss/sd-scripts` to... 2. SD or Dreambooth checkpoint to... -3. diffusers or LoRA weights from `cloneofsimo/lora` to... +3. diffusers directory or LoRA weights from `cloneofsimo/lora` to... 4. ONNX models One disadvantage of using ONNX is that LoRA weights must be merged with the base model before being converted, diff --git a/gui/src/client.ts b/gui/src/client.ts index 5b6cb14d..5155e0f2 100644 --- a/gui/src/client.ts +++ b/gui/src/client.ts @@ -129,6 +129,8 @@ export interface UpscaleParams { * Parameters for upscale requests. */ export interface UpscaleReqParams { + prompt: string; + negativePrompt?: string; source: Blob; } @@ -477,6 +479,12 @@ export function makeClient(root: string, f = fetch): ApiClient { appendUpscaleToURL(url, upscale); } + url.searchParams.append('prompt', params.prompt); + + if (doesExist(params.negativePrompt)) { + url.searchParams.append('negativePrompt', params.negativePrompt); + } + const body = new FormData(); body.append('source', params.source, 'source'); diff --git a/gui/src/components/control/ImageControl.tsx b/gui/src/components/control/ImageControl.tsx index a01a16f8..e1784031 100644 --- a/gui/src/components/control/ImageControl.tsx +++ b/gui/src/components/control/ImageControl.tsx @@ -1,6 +1,6 @@ import { doesExist, mustDefault, mustExist } from '@apextoaster/js-utils'; import { Casino } from '@mui/icons-material'; -import { Button, Stack, TextField } from '@mui/material'; +import { Button, Stack } from '@mui/material'; import * as React from 'react'; import { useContext } from 'react'; import { useQuery } from 'react-query'; @@ -11,10 +11,9 @@ import { STALE_TIME } from '../../config.js'; import { ClientContext, ConfigContext, OnnxState, StateContext } from '../../state.js'; import { SCHEDULER_LABELS } from '../../strings.js'; import { NumericField } from '../input/NumericField.js'; +import { PromptInput } from '../input/PromptInput.js'; import { QueryList } from '../input/QueryList.js'; -export const PROMPT_LIMIT = 70; - export interface ImageControlProps { selector: (state: OnnxState) => BaseImgParams; @@ -34,17 +33,6 @@ export function ImageControl(props: ImageControlProps) { staleTime: STALE_TIME, }); - const promptLength = controlState.prompt.split(' ').length; - const error = promptLength > PROMPT_LIMIT; - - function promptHelper() { - if (error) { - return `Too many tokens: ${promptLength}/${PROMPT_LIMIT}`; - } else { - return `Tokens: ${promptLength}/${PROMPT_LIMIT}`; - } - } - return - { + { if (doesExist(props.onChange)) { props.onChange({ ...controlState, - prompt: event.target.value, - }); - } - }} - /> - { - if (doesExist(props.onChange)) { - props.onChange({ - ...controlState, - negativePrompt: event.target.value, + ...value, }); } }} diff --git a/gui/src/components/input/PromptInput.tsx b/gui/src/components/input/PromptInput.tsx new file mode 100644 index 00000000..5bbf2dd6 --- /dev/null +++ b/gui/src/components/input/PromptInput.tsx @@ -0,0 +1,60 @@ +import { doesExist, Maybe } from '@apextoaster/js-utils'; +import { TextField } from '@mui/material'; +import { Stack } from '@mui/system'; +import * as React from 'react'; + +export interface PromptValue { + prompt: string; + negativePrompt?: string; +} + +export interface PromptInputProps extends PromptValue { + onChange?: Maybe<(value: PromptValue) => void>; +} + +export const PROMPT_LIMIT = 77; + +export function PromptInput(props: PromptInputProps) { + const { prompt = '', negativePrompt = '' } = props; + const promptLength = prompt.split(' ').length; + const error = promptLength > PROMPT_LIMIT; + + function promptHelper() { + if (error) { + return `Too many tokens: ${promptLength}/${PROMPT_LIMIT}`; + } else { + return `Tokens: ${promptLength}/${PROMPT_LIMIT}`; + } + } + + return + { + if (doesExist(props.onChange)) { + props.onChange({ + prompt: event.target.value, + negativePrompt, + }); + } + }} + /> + { + if (doesExist(props.onChange)) { + props.onChange({ + prompt, + negativePrompt: event.target.value, + }); + } + }} + /> + ; +} diff --git a/gui/src/components/tab/Upscale.tsx b/gui/src/components/tab/Upscale.tsx index 9e39f63b..b0e00f51 100644 --- a/gui/src/components/tab/Upscale.tsx +++ b/gui/src/components/tab/Upscale.tsx @@ -9,6 +9,7 @@ import { IMAGE_FILTER } from '../../config.js'; import { ClientContext, StateContext } from '../../state.js'; import { UpscaleControl } from '../control/UpscaleControl.js'; import { ImageInput } from '../input/ImageInput.js'; +import { PromptInput } from '../input/PromptInput.js'; export function Upscale() { async function uploadSource() { @@ -47,6 +48,13 @@ export function Upscale() { }); }} /> + { + setSource(value); + }} + />