1
0
Fork 0

feat(gui): add outpainting dimension controls to inpaint tab

This commit is contained in:
Sean Sube 2023-01-14 17:00:53 -06:00
parent d9bbb9bb5a
commit 9e2921d3de
4 changed files with 106 additions and 13 deletions

View File

@ -1,4 +1,4 @@
import { doesExist, NotImplementedError } from '@apextoaster/js-utils';
import { doesExist } from '@apextoaster/js-utils';
import { ConfigParams } from '../config.js';
@ -43,13 +43,11 @@ export type Txt2ImgResponse = Required<Txt2ImgParams>;
export interface InpaintParams extends BaseImgParams {
mask: Blob;
source: Blob;
}
export interface OutpaintParams extends Img2ImgParams {
up: boolean;
down: boolean;
left: boolean;
right: boolean;
left?: number;
right?: number;
top?: number;
bottom?: number;
}
export interface ApiResponse {
@ -72,9 +70,7 @@ export interface ApiClient {
img2img(params: Img2ImgParams): Promise<ApiResponse>;
txt2img(params: Txt2ImgParams): Promise<ApiResponse>;
inpaint(params: InpaintParams): Promise<ApiResponse>;
outpaint(params: OutpaintParams): Promise<ApiResponse>;
ready(params: ApiResponse): Promise<ApiReady>;
}
@ -214,6 +210,23 @@ export function makeClient(root: string, f = fetch): ApiClient {
const url = makeImageURL(root, 'inpaint', params);
if (doesExist(params.left)) {
url.searchParams.append('left', params.left.toFixed(0));
}
if (doesExist(params.right)) {
url.searchParams.append('right', params.right.toFixed(0));
}
if (doesExist(params.top)) {
url.searchParams.append('top', params.top.toFixed(0));
}
if (doesExist(params.bottom)) {
url.searchParams.append('bottom', params.bottom.toFixed(0));
}
const body = new FormData();
body.append('mask', params.mask, 'mask');
body.append('source', params.source, 'source');
@ -226,9 +239,6 @@ export function makeClient(root: string, f = fetch): ApiClient {
// eslint-disable-next-line no-return-await
return await pending;
},
async outpaint() {
throw new NotImplementedError();
},
async ready(params: ApiResponse): Promise<ApiReady> {
const path = makeApiUrl(root, 'ready');
path.searchParams.append('output', params.output.key);

View File

@ -9,6 +9,7 @@ import { ClientContext, StateContext } from '../state.js';
import { ImageControl } from './ImageControl.js';
import { ImageInput } from './ImageInput.js';
import { MaskCanvas } from './MaskCanvas.js';
import { OutpaintControl } from './OutpaintControl.js';
const { useContext } = React;
@ -88,6 +89,7 @@ export function Inpaint(props: InpaintProps) {
setInpaint(newParams);
}}
/>
<OutpaintControl config={config} />
<Button onClick={() => upload.mutate()}>Generate</Button>
</Stack>
</Box>;

View File

@ -0,0 +1,73 @@
import { mustExist } from '@apextoaster/js-utils';
import { Stack } from '@mui/material';
import * as React from 'react';
import { useContext } from 'react';
import { useStore } from 'zustand';
import { ConfigParams } from '../config.js';
import { StateContext } from '../state.js';
import { NumericField } from './NumericField.js';
export interface OutpaintControlProps {
config: ConfigParams;
}
export function OutpaintControl(props: OutpaintControlProps) {
const { config } = props;
const state = mustExist(useContext(StateContext));
const params = useStore(state, (s) => s.inpaint);
// eslint-disable-next-line @typescript-eslint/unbound-method
const setInpaint = useStore(state, (s) => s.setInpaint);
return <Stack direction='row' spacing={4}>
<NumericField
label='Left'
min={0}
max={config.width.max}
step={config.width.step}
value={params.left}
onChange={(left) => {
setInpaint({
left,
});
}}
/>
<NumericField
label='Right'
min={0}
max={config.width.max}
step={config.width.step}
value={params.right}
onChange={(right) => {
setInpaint({
right,
});
}}
/>
<NumericField
label='Top'
min={0}
max={config.height.max}
step={config.height.step}
value={params.top}
onChange={(top) => {
setInpaint({
top,
});
}}
/>
<NumericField
label='Bottom'
min={0}
max={config.height.max}
step={config.height.step}
value={params.bottom}
onChange={(bottom) => {
setInpaint({
bottom,
});
}}
/>
</Stack>;
}

View File

@ -114,6 +114,10 @@ export function createStateSlices(base: ConfigParams) {
...defaults,
mask: null,
source: null,
left: 0,
right: 0,
top: 0,
bottom: 0,
},
setInpaint(params) {
set((prev) => ({
@ -129,6 +133,10 @@ export function createStateSlices(base: ConfigParams) {
...defaults,
mask: null,
source: null,
left: 0,
right: 0,
top: 0,
bottom: 0,
},
});
},