Skip to content

Commit

Permalink
feat: img2img
Browse files Browse the repository at this point in the history
  • Loading branch information
p1atdev authored and ddPn08 committed Feb 8, 2023
1 parent 1ce51bb commit e45c691
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 24 deletions.
2 changes: 1 addition & 1 deletion frontend/src/atoms/generationParameters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ export const generationParametersAtom = atom<GenerationParamertersForm>({
batch_count: 1,
steps: 50,
seed: -1,
strength: 1,
strength: 0.7,
img: undefined,
})
10 changes: 5 additions & 5 deletions frontend/src/components/gallery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ const Gallery = ({ images, isLoading }: Props) => {
cols={3}
breakpoints={[
{ maxWidth: 'xs', cols: 2 },
{ maxWidth: 'sm', cols: 3 },
{ minWidth: 'sm', cols: 3 },
{ minWidth: 'md', cols: 3 },
{ minWidth: 'lg', cols: 4 },
{ minWidth: 'xl', cols: 5 },
{ maxWidth: 'sm', cols: 2 },
{ minWidth: 'sm', cols: 2 },
{ minWidth: 'md', cols: 2 },
{ minWidth: 'lg', cols: 3 },
{ minWidth: 'xl', cols: 4 },
]}
>
{images.map((image, i) => {
Expand Down
3 changes: 1 addition & 2 deletions frontend/src/components/overlayPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ const OverlayPreview = ({ images, initialIndex, onClose }: Props) => {
const [currentInfo, setCurrentInfo] = useState(images[initialIndex].info)

const onSlideChange = (index: number) => {
console.log('slide change', index)
setCurrentIndex(index)
setCurrentInfo(images[index].info)
}
Expand Down Expand Up @@ -91,7 +90,7 @@ const OverlayPreview = ({ images, initialIndex, onClose }: Props) => {
return (
<tr key={key}>
<td>{key}</td>
<td>{value == '' ? 'none' : value}</td>
<td>{String(value) == '' ? 'none' : value}</td>
</tr>
)
})}
Expand Down
11 changes: 8 additions & 3 deletions frontend/src/components/parameters.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Flex, NativeSelect } from '@mantine/core'
import { Divider, NativeSelect, Stack } from '@mantine/core'
import { useAtom } from 'jotai'

import ImageParameter from './parameters/imageParameter'
import ImageSizeParameter from './parameters/imageSizeParameter'
import ModelParameter from './parameters/modelParameter'
import SeedParameter from './parameters/seedParameter'
Expand All @@ -13,7 +14,7 @@ const Parameters = () => {
const [parameters, setParameters] = useAtom(generationParametersAtom)

return (
<Flex w={'100%'} direction={'column'} p={'md'} gap={'md'}>
<Stack w={'100%'} p={'md'} spacing={'md'}>
<ModelParameter />

<ImageSizeParameter />
Expand Down Expand Up @@ -65,7 +66,11 @@ const Parameters = () => {
}
}}
/>
</Flex>

<Divider />

<ImageParameter />
</Stack>
)
}

Expand Down
114 changes: 114 additions & 0 deletions frontend/src/components/parameters/imageParameter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { Box, Button, CloseButton, FileButton, Group, Image, Stack, Text } from '@mantine/core'
import { Dropzone, IMAGE_MIME_TYPE } from '@mantine/dropzone'
import { IconPhoto, IconUpload, IconX } from '@tabler/icons-react'
import { useAtom } from 'jotai'
import { useState } from 'react'

import NumberSliderInput from '../ui/numberSliderInput'

import { generationParametersAtom } from '~/atoms/generationParameters'
import { arrayBufferToBase64 } from '~/utils/base64'

const ImageParameter = () => {
const [file, setFile] = useState<File | null>(null)
const [parameters, setParameters] = useAtom(generationParametersAtom)

const onFileChange = async (file: File | null) => {
setFile(file)
if (file) {
const arrayBuffer = await file.arrayBuffer()
const base64 = arrayBufferToBase64(arrayBuffer)
setParameters((prev) => ({ ...prev, img: base64 }))
} else {
setParameters((prev) => ({ ...prev, img: undefined }))
}
}

return (
<Stack>
{file && (
<NumberSliderInput
label={'Strength'}
defaultValue={parameters.strength}
min={0.01}
max={1.0}
step={0.01}
precision={2}
onChange={(e) => {
if (e) {
setParameters((p) => ({ ...p, strength: e }))
}
}}
/>
)}

<FileButton onChange={onFileChange} accept={'image/*'}>
{(props) => (
<Button leftIcon={<IconUpload />} variant={'subtle'} {...props}>
Upload image (or drag and drop)
</Button>
)}
</FileButton>

{file && (
<Box pos={'relative'}>
<Image src={URL.createObjectURL(file)} radius={'xs'} />
<CloseButton
variant={'filled'}
color={'blue'}
pos={'absolute'}
m={'xs'}
top={0}
right={0}
onClick={() => onFileChange(null)}
/>
</Box>
)}

<Dropzone.FullScreen
accept={IMAGE_MIME_TYPE}
onDrop={(files) => {
if (files.length > 0) {
onFileChange(files[0])
}
}}
m={'xl'}
>
<Dropzone.Accept>
<Group position={'center'} spacing={'xl'}>
<IconUpload size={50} stroke={1.5} />

<Box>
<Text size="xl">Drop the image here!</Text>
<Text size="sm"></Text>
</Box>
</Group>
</Dropzone.Accept>

<Dropzone.Reject>
<Group position={'center'} spacing={'xl'}>
<IconX size={50} stroke={1.5} />

<Box>
<Text size={'xl'}>This file type is not supported</Text>
<Text size={'sm'}>(╯°□°)╯︵ ┻━┻</Text>
</Box>
</Group>
</Dropzone.Reject>

<Dropzone.Idle>
<Group position={'center'} spacing={'xl'} h={'80%'}>
<IconPhoto size={50} stroke={1.5} />

<Box>
<Text size="xl">Drag and drop your image here...</Text>
<Text size="sm"></Text>
</Box>
</Group>
</Dropzone.Idle>
</Dropzone.FullScreen>
</Stack>
)
}

export default ImageParameter
1 change: 1 addition & 0 deletions frontend/src/components/ui/numberSliderInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const NumberSliderInput = ({
<Input.Wrapper label={label}>
<Flex align={'center'} gap={'sm'}>
<Slider
label={value}
defaultValue={defaultValue}
value={value}
min={min}
Expand Down
19 changes: 8 additions & 11 deletions frontend/src/tabs/gemerator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ const Generator = () => {
setIsLoading(true)
setErrorMessage(null)
setPerformance(null)

console.log(requestBody)
const res = await api.generateImage({
generateImageRequest: requestBody,
})
Expand Down Expand Up @@ -104,15 +106,7 @@ const Generator = () => {
}}
>
<Flex h={'100%'} w={'100%'} direction={isLargeScreen ? 'row' : 'column'}>
<Stack
w={'100%'}
p={'md'}
sx={
{
// overflow: 'hidden',
}
}
>
<Stack w={'100%'} p={'md'}>
<Stack w={'100%'}>
<Textarea
label={'Positive'}
Expand Down Expand Up @@ -143,7 +137,7 @@ const Generator = () => {
cursor: isLoading ? 'not-allowed' : 'pointer',
}}
>
Generate
<Text>{parameters.img ? 'Generate (img2img mode)' : 'Generate'}</Text>
</Button>

{performance && <Text align="end">Time: {performance.toFixed(2)}s</Text>}
Expand All @@ -152,7 +146,7 @@ const Generator = () => {
mah={isLargeScreen ? '80%' : '480px'}
pos={'relative'}
sx={{
overflow: 'scroll',
overflowY: 'scroll',
}}
>
<Gallery images={images} isLoading={isLoading} />
Expand All @@ -170,6 +164,9 @@ const Generator = () => {
}
: '100%'
}
sx={{
overflow: 'scroll',
}}
>
<Parameters />
</Box>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/types/generatedImage.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export interface GeneratedImage {
url: string
info: Record<string, string>
info: Record<string, any>
}
2 changes: 1 addition & 1 deletion frontend/src/utils/base64.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const fileToBase64 = (buffer: ArrayBuffer) => {
export const arrayBufferToBase64 = (buffer: ArrayBuffer) => {
let binary = ''
const bytes = new Uint8Array(buffer)
const len = bytes.byteLength
Expand Down

0 comments on commit e45c691

Please sign in to comment.