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

View File

@ -1,6 +1,7 @@
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 { NumericField } from './NumericField';
export interface ImageParams {
cfg: number;
@ -19,64 +20,64 @@ export function ImageControl(props: ImageControlProps) {
return <Stack spacing={2}>
<Stack direction="row" spacing={4}>
<TextField
<NumericField
label="CFG"
variant="outlined"
type="number"
inputProps={{ min: 0, max: 30, step: 1 }}
min={0}
max={30}
step={1}
value={params.cfg}
onChange={(event) => {
onChange={(cfg) => {
if (doesExist(props.onChange)) {
props.onChange({
...params,
cfg: parseInt(event.target.value, 10),
cfg,
});
}
}}
/>
<TextField
<NumericField
label="Steps"
variant="outlined"
type="number"
inputProps={{ min: 1, max: 150, step: 1 }}
min={1}
max={150}
step={1}
value={params.steps}
onChange={(event) => {
onChange={(steps) => {
if (doesExist(props.onChange)) {
props.onChange({
...params,
steps: parseInt(event.target.value, 10),
steps,
});
}
}}
/>
</Stack>
<Stack direction="row" spacing={4}>
<TextField
<NumericField
label="Width"
variant="outlined"
type="number"
inputProps={{ min: 1, max: 512, step: 16 }}
min={1}
max={512}
step={8}
value={params.width}
onChange={(event) => {
onChange={(width) => {
if (doesExist(props.onChange)) {
props.onChange({
...params,
width: parseInt(event.target.value, 10),
width,
});
}
}}
/>
<TextField
<NumericField
label="Height"
variant="outlined"
type="number"
inputProps={{ min: 1, max: 512, step: 16 }}
min={1}
max={512}
step={8}
value={params.height}
onChange={(event) => {
onChange={(height) => {
if (doesExist(props.onChange)) {
props.onChange({
...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 { ApiClient } from '../api/client.js';
@ -20,10 +20,11 @@ export function Txt2Img(props: Txt2ImgProps) {
steps: 25,
width: 512,
height: 512,
})
});
const [scheduler, setScheduler] = useState('euler-a');
async function getImage() {
const image = await client.txt2img({ ...params, prompt });
const image = await client.txt2img({ ...params, prompt, scheduler });
console.log(prompt, image);
setImage(image);
}
@ -41,6 +42,21 @@ export function Txt2Img(props: Txt2ImgProps) {
<Box>
txt2img mode
</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) => {
setParams(params);
}} />