1
0
Fork 0

add scheduler dropdown, wrap numeric input

This commit is contained in:
Sean Sube 2023-01-05 01:14:27 -06:00
parent 6b4545b3bf
commit 75dde1dd75
4 changed files with 100 additions and 32 deletions

View File

@ -4,8 +4,15 @@ export interface Txt2ImgParams {
prompt: string; prompt: string;
cfg: number; cfg: number;
steps: number; steps: number;
width: number; width?: number;
height: number; height?: number;
seed?: string;
scheduler?: string;
}
export interface ApiResponse {
params: Txt2ImgParams;
path: string;
} }
export interface ApiClient { export interface ApiClient {
@ -34,8 +41,23 @@ export function makeClient(root: string, f = fetch): ApiClient {
const url = new URL('/txt2img', root); const url = new URL('/txt2img', root);
url.searchParams.append('cfg', params.cfg.toFixed(0)); url.searchParams.append('cfg', params.cfg.toFixed(0));
url.searchParams.append('steps', params.steps.toFixed(0)); url.searchParams.append('steps', params.steps.toFixed(0));
if (doesExist(params.width)) {
url.searchParams.append('width', params.width.toFixed(0)); url.searchParams.append('width', params.width.toFixed(0));
}
if (doesExist(params.height)) {
url.searchParams.append('height', params.height.toFixed(0)); url.searchParams.append('height', params.height.toFixed(0));
}
if (doesExist(params.seed)) {
url.searchParams.append('seed', params.seed);
}
if (doesExist(params.scheduler)) {
url.searchParams.append('scheduler', params.scheduler);
}
url.searchParams.append('prompt', params.prompt); url.searchParams.append('prompt', params.prompt);
pending = f(url).then((res) => { pending = f(url).then((res) => {

View File

@ -1,6 +1,7 @@
import { doesExist } from '@apextoaster/js-utils'; import { doesExist } from '@apextoaster/js-utils';
import { Container, Stack, TextField } from '@mui/material'; import { Stack, TextField } from '@mui/material';
import * as React from 'react'; import * as React from 'react';
import { NumericField } from './NumericField';
export interface ImageParams { export interface ImageParams {
cfg: number; cfg: number;
@ -19,64 +20,64 @@ export function ImageControl(props: ImageControlProps) {
return <Stack spacing={2}> return <Stack spacing={2}>
<Stack direction="row" spacing={4}> <Stack direction="row" spacing={4}>
<TextField <NumericField
label="CFG" label="CFG"
variant="outlined" min={0}
type="number" max={30}
inputProps={{ min: 0, max: 30, step: 1 }} step={1}
value={params.cfg} value={params.cfg}
onChange={(event) => { onChange={(cfg) => {
if (doesExist(props.onChange)) { if (doesExist(props.onChange)) {
props.onChange({ props.onChange({
...params, ...params,
cfg: parseInt(event.target.value, 10), cfg,
}); });
} }
}} }}
/> />
<TextField <NumericField
label="Steps" label="Steps"
variant="outlined" min={1}
type="number" max={150}
inputProps={{ min: 1, max: 150, step: 1 }} step={1}
value={params.steps} value={params.steps}
onChange={(event) => { onChange={(steps) => {
if (doesExist(props.onChange)) { if (doesExist(props.onChange)) {
props.onChange({ props.onChange({
...params, ...params,
steps: parseInt(event.target.value, 10), steps,
}); });
} }
}} }}
/> />
</Stack> </Stack>
<Stack direction="row" spacing={4}> <Stack direction="row" spacing={4}>
<TextField <NumericField
label="Width" label="Width"
variant="outlined" min={1}
type="number" max={512}
inputProps={{ min: 1, max: 512, step: 16 }} step={8}
value={params.width} value={params.width}
onChange={(event) => { onChange={(width) => {
if (doesExist(props.onChange)) { if (doesExist(props.onChange)) {
props.onChange({ props.onChange({
...params, ...params,
width: parseInt(event.target.value, 10), width,
}); });
} }
}} }}
/> />
<TextField <NumericField
label="Height" label="Height"
variant="outlined" min={1}
type="number" max={512}
inputProps={{ min: 1, max: 512, step: 16 }} step={8}
value={params.height} value={params.height}
onChange={(event) => { onChange={(height) => {
if (doesExist(props.onChange)) { if (doesExist(props.onChange)) {
props.onChange({ props.onChange({
...params, ...params,
height: parseInt(event.target.value, 10), height,
}); });
} }
}} }}

View File

@ -0,0 +1,29 @@
import { doesExist } from '@apextoaster/js-utils';
import { TextField } from '@mui/material';
import * as React from 'react';
export interface ImageControlProps {
label: string;
min: number;
max: number;
step: number;
value: number;
onChange?: (value: number) => void;
}
export function NumericField(props: ImageControlProps) {
const { label, min, max, step, value } = props;
return <TextField
label={label}
variant="outlined"
type="number"
inputProps={{ min, max, step }}
value={value}
onChange={(event) => {
if (doesExist(props.onChange)) {
props.onChange(parseInt(event.target.value, 10));
}
}}
/>;
}

View File

@ -1,4 +1,4 @@
import { Box, Button, Stack, TextField } from '@mui/material'; import { Box, Button, MenuItem, Select, Stack, TextField } from '@mui/material';
import * as React from 'react'; import * as React from 'react';
import { ApiClient } from '../api/client.js'; import { ApiClient } from '../api/client.js';
@ -20,10 +20,11 @@ export function Txt2Img(props: Txt2ImgProps) {
steps: 25, steps: 25,
width: 512, width: 512,
height: 512, height: 512,
}) });
const [scheduler, setScheduler] = useState('euler-a');
async function getImage() { async function getImage() {
const image = await client.txt2img({ ...params, prompt }); const image = await client.txt2img({ ...params, prompt, scheduler });
console.log(prompt, image); console.log(prompt, image);
setImage(image); setImage(image);
} }
@ -41,6 +42,21 @@ export function Txt2Img(props: Txt2ImgProps) {
<Box> <Box>
txt2img mode txt2img mode
</Box> </Box>
<Select
value={scheduler}
label="Scheduler"
onChange={(event) => {
setScheduler(event.target.value);
}}
>
<MenuItem value='ddim'>DDIM</MenuItem>
<MenuItem value='ddpm'>DDPM</MenuItem>
<MenuItem value='pndm'>PNDM</MenuItem>
<MenuItem value='lms-discrete'>LMS</MenuItem>
<MenuItem value='euler'>Euler</MenuItem>
<MenuItem value='euler-a'>Euler A</MenuItem>
<MenuItem value='dpm-multi'>DPM</MenuItem>
</Select>
<ImageControl params={params} onChange={(params) => { <ImageControl params={params} onChange={(params) => {
setParams(params); setParams(params);
}} /> }} />