each model has its own hdsettings

This commit is contained in:
Qing 2022-07-18 22:43:55 +08:00
parent 8b1f7a672e
commit b0c5d22a5a
7 changed files with 104 additions and 52 deletions

View File

@ -14,10 +14,12 @@
"@testing-library/react": "^12.1.2", "@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.0.2", "@types/jest": "^27.0.2",
"@types/lodash": "^4.14.182",
"@types/node": "^16.11.1", "@types/node": "^16.11.1",
"@types/react": "^17.0.30", "@types/react": "^17.0.30",
"@types/react-dom": "^17.0.9", "@types/react-dom": "^17.0.9",
"cross-env": "7.x", "cross-env": "7.x",
"lodash": "^4.17.21",
"nanoid": "^4.0.0", "nanoid": "^4.0.0",
"npm-run-all": "4.x", "npm-run-all": "4.x",
"react": "^17.0.2", "react": "^17.0.2",

View File

@ -15,16 +15,20 @@ export default async function inpaint(
const mask = dataURItoBlob(maskBase64) const mask = dataURItoBlob(maskBase64)
fd.append('mask', mask) fd.append('mask', mask)
const hdSettings = settings.hdSettings[settings.model]
fd.append('ldmSteps', settings.ldmSteps.toString()) fd.append('ldmSteps', settings.ldmSteps.toString())
fd.append('ldmSampler', settings.ldmSampler.toString()) fd.append('ldmSampler', settings.ldmSampler.toString())
fd.append('zitsWireframe', settings.zitsWireframe.toString()) fd.append('zitsWireframe', settings.zitsWireframe.toString())
fd.append('hdStrategy', settings.hdStrategy) fd.append('hdStrategy', hdSettings.hdStrategy)
fd.append('hdStrategyCropMargin', settings.hdStrategyCropMargin.toString()) fd.append('hdStrategyCropMargin', hdSettings.hdStrategyCropMargin.toString())
fd.append( fd.append(
'hdStrategyCropTrigerSize', 'hdStrategyCropTrigerSize',
settings.hdStrategyCropTrigerSize.toString() hdSettings.hdStrategyCropTrigerSize.toString()
)
fd.append(
'hdStrategyResizeLimit',
hdSettings.hdStrategyResizeLimit.toString()
) )
fd.append('hdStrategyResizeLimit', settings.hdStrategyResizeLimit.toString())
if (sizeLimit === undefined) { if (sizeLimit === undefined) {
fd.append('sizeLimit', '1080') fd.append('sizeLimit', '1080')

View File

@ -1,6 +1,6 @@
import React, { ReactNode } from 'react' import React, { ReactNode } from 'react'
import { useRecoilState } from 'recoil' import { useRecoilState } from 'recoil'
import { settingState } from '../../store/Atoms' import { hdSettingsState, settingState } from '../../store/Atoms'
import Selector from '../shared/Selector' import Selector from '../shared/Selector'
import NumberInputSetting from './NumberInputSetting' import NumberInputSetting from './NumberInputSetting'
import SettingBlock from './SettingBlock' import SettingBlock from './SettingBlock'
@ -17,33 +17,25 @@ export enum LDMSampler {
} }
function HDSettingBlock() { function HDSettingBlock() {
const [setting, setSettingState] = useRecoilState(settingState) const [hdSettings, setHDSettings] = useRecoilState(hdSettingsState)
const onStrategyChange = (value: HDStrategy) => { const onStrategyChange = (value: HDStrategy) => {
setSettingState(old => { setHDSettings({ hdStrategy: value })
return { ...old, hdStrategy: value }
})
} }
const onResizeLimitChange = (value: string) => { const onResizeLimitChange = (value: string) => {
const val = value.length === 0 ? 0 : parseInt(value, 10) const val = value.length === 0 ? 0 : parseInt(value, 10)
setSettingState(old => { setHDSettings({ hdStrategyResizeLimit: val })
return { ...old, hdStrategyResizeLimit: val }
})
} }
const onCropTriggerSizeChange = (value: string) => { const onCropTriggerSizeChange = (value: string) => {
const val = value.length === 0 ? 0 : parseInt(value, 10) const val = value.length === 0 ? 0 : parseInt(value, 10)
setSettingState(old => { setHDSettings({ hdStrategyCropTrigerSize: val })
return { ...old, hdStrategyCropTrigerSize: val }
})
} }
const onCropMarginChange = (value: string) => { const onCropMarginChange = (value: string) => {
const val = value.length === 0 ? 0 : parseInt(value, 10) const val = value.length === 0 ? 0 : parseInt(value, 10)
setSettingState(old => { setHDSettings({ hdStrategyCropMargin: val })
return { ...old, hdStrategyCropMargin: val }
})
} }
const renderOriginalOptionDesc = () => { const renderOriginalOptionDesc = () => {
@ -73,7 +65,7 @@ function HDSettingBlock() {
</div> </div>
<NumberInputSetting <NumberInputSetting
title="Size limit" title="Size limit"
value={`${setting.hdStrategyResizeLimit}`} value={`${hdSettings.hdStrategyResizeLimit}`}
suffix="pixel" suffix="pixel"
onValue={onResizeLimitChange} onValue={onResizeLimitChange}
/> />
@ -91,13 +83,13 @@ function HDSettingBlock() {
</div> </div>
<NumberInputSetting <NumberInputSetting
title="Trigger size" title="Trigger size"
value={`${setting.hdStrategyCropTrigerSize}`} value={`${hdSettings.hdStrategyCropTrigerSize}`}
suffix="pixel" suffix="pixel"
onValue={onCropTriggerSizeChange} onValue={onCropTriggerSizeChange}
/> />
<NumberInputSetting <NumberInputSetting
title="Crop margin" title="Crop margin"
value={`${setting.hdStrategyCropMargin}`} value={`${hdSettings.hdStrategyCropMargin}`}
suffix="pixel" suffix="pixel"
onValue={onCropMarginChange} onValue={onCropMarginChange}
/> />
@ -106,7 +98,7 @@ function HDSettingBlock() {
} }
const renderHDStrategyOptionDesc = (): ReactNode => { const renderHDStrategyOptionDesc = (): ReactNode => {
switch (setting.hdStrategy) { switch (hdSettings.hdStrategy) {
case HDStrategy.ORIGINAL: case HDStrategy.ORIGINAL:
return renderOriginalOptionDesc() return renderOriginalOptionDesc()
case HDStrategy.CROP: case HDStrategy.CROP:
@ -125,7 +117,7 @@ function HDSettingBlock() {
input={ input={
<Selector <Selector
width={80} width={80}
value={setting.hdStrategy as string} value={hdSettings.hdStrategy as string}
options={Object.values(HDStrategy)} options={Object.values(HDStrategy)}
onChange={val => onStrategyChange(val as HDStrategy)} onChange={val => onStrategyChange(val as HDStrategy)}
/> />

View File

@ -1,6 +1,6 @@
import React, { ReactNode } from 'react' import React, { ReactNode } from 'react'
import { useRecoilState } from 'recoil' import { useRecoilState } from 'recoil'
import { settingState } from '../../store/Atoms' import { AIModel, settingState } from '../../store/Atoms'
import Selector from '../shared/Selector' import Selector from '../shared/Selector'
import { Switch, SwitchThumb } from '../shared/Switch' import { Switch, SwitchThumb } from '../shared/Switch'
import Tooltip from '../shared/Tooltip' import Tooltip from '../shared/Tooltip'
@ -8,12 +8,6 @@ import { LDMSampler } from './HDSettingBlock'
import NumberInputSetting from './NumberInputSetting' import NumberInputSetting from './NumberInputSetting'
import SettingBlock from './SettingBlock' import SettingBlock from './SettingBlock'
export enum AIModel {
LAMA = 'lama',
LDM = 'ldm',
ZITS = 'zits',
}
function ModelSettingBlock() { function ModelSettingBlock() {
const [setting, setSettingState] = useRecoilState(settingState) const [setting, setSettingState] = useRecoilState(settingState)

View File

@ -4,13 +4,12 @@ import Editor from './Editor/Editor'
import ShortcutsModal from './Shortcuts/ShortcutsModal' import ShortcutsModal from './Shortcuts/ShortcutsModal'
import SettingModal from './Settings/SettingsModal' import SettingModal from './Settings/SettingsModal'
import Toast from './shared/Toast' import Toast from './shared/Toast'
import { settingState, toastState } from '../store/Atoms' import { AIModel, settingState, toastState } from '../store/Atoms'
import { import {
currentModel, currentModel,
modelDownloaded, modelDownloaded,
switchModel, switchModel,
} from '../adapters/inpainting' } from '../adapters/inpainting'
import { AIModel } from './Settings/ModelSettingBlock'
interface WorkspaceProps { interface WorkspaceProps {
file: File file: File

View File

@ -1,8 +1,14 @@
import { atom } from 'recoil' import { atom, selector } from 'recoil'
import _ from 'lodash'
import { HDStrategy, LDMSampler } from '../components/Settings/HDSettingBlock' import { HDStrategy, LDMSampler } from '../components/Settings/HDSettingBlock'
import { AIModel } from '../components/Settings/ModelSettingBlock'
import { ToastState } from '../components/shared/Toast' import { ToastState } from '../components/shared/Toast'
export enum AIModel {
LAMA = 'lama',
LDM = 'ldm',
ZITS = 'zits',
}
export const fileState = atom<File | undefined>({ export const fileState = atom<File | undefined>({
key: 'fileState', key: 'fileState',
default: undefined, default: undefined,
@ -30,18 +36,22 @@ export const shortcutsState = atom<boolean>({
default: false, default: false,
}) })
export interface HDSettings {
hdStrategy: HDStrategy
hdStrategyResizeLimit: number
hdStrategyCropTrigerSize: number
hdStrategyCropMargin: number
}
type ModelsHDSettings = { [key in AIModel]: HDSettings }
export interface Settings { export interface Settings {
show: boolean show: boolean
downloadMask: boolean downloadMask: boolean
graduallyInpainting: boolean graduallyInpainting: boolean
runInpaintingManually: boolean runInpaintingManually: boolean
model: AIModel model: AIModel
hdSettings: ModelsHDSettings
// For LaMa
hdStrategy: HDStrategy
hdStrategyResizeLimit: number
hdStrategyCropTrigerSize: number
hdStrategyCropMargin: number
// For LDM // For LDM
ldmSteps: number ldmSteps: number
@ -51,22 +61,39 @@ export interface Settings {
zitsWireframe: boolean zitsWireframe: boolean
} }
export const settingStateDefault = { const defaultHDSettings: ModelsHDSettings = {
[AIModel.LAMA]: {
hdStrategy: HDStrategy.RESIZE,
hdStrategyResizeLimit: 2048,
hdStrategyCropTrigerSize: 2048,
hdStrategyCropMargin: 128,
},
[AIModel.LDM]: {
hdStrategy: HDStrategy.CROP,
hdStrategyResizeLimit: 1080,
hdStrategyCropTrigerSize: 1080,
hdStrategyCropMargin: 128,
},
[AIModel.ZITS]: {
hdStrategy: HDStrategy.CROP,
hdStrategyResizeLimit: 1024,
hdStrategyCropTrigerSize: 1024,
hdStrategyCropMargin: 128,
},
}
export const settingStateDefault: Settings = {
show: false, show: false,
downloadMask: false, downloadMask: false,
graduallyInpainting: true, graduallyInpainting: true,
runInpaintingManually: false, runInpaintingManually: false,
model: AIModel.LAMA, model: AIModel.LAMA,
hdSettings: defaultHDSettings,
ldmSteps: 50, ldmSteps: 25,
ldmSampler: LDMSampler.plms, ldmSampler: LDMSampler.plms,
zitsWireframe: true, zitsWireframe: true,
hdStrategy: HDStrategy.RESIZE,
hdStrategyResizeLimit: 2048,
hdStrategyCropTrigerSize: 2048,
hdStrategyCropMargin: 128,
} }
const localStorageEffect = const localStorageEffect =
@ -76,20 +103,44 @@ const localStorageEffect =
if (savedValue != null) { if (savedValue != null) {
const storageSettings = JSON.parse(savedValue) const storageSettings = JSON.parse(savedValue)
storageSettings.show = false storageSettings.show = false
setSelf({ ...settingStateDefault, ...storageSettings })
const restored = _.merge(
_.cloneDeep(settingStateDefault),
storageSettings
)
setSelf(restored)
} }
onSet((newValue: Settings, _: string, isReset: boolean) => onSet((newValue: Settings, val: string, isReset: boolean) =>
isReset isReset
? localStorage.removeItem(key) ? localStorage.removeItem(key)
: localStorage.setItem(key, JSON.stringify(newValue)) : localStorage.setItem(key, JSON.stringify(newValue))
) )
} }
const ROOT_STATE_KEY = 'settingsState2'
// Each atom can reference an array of these atom effect functions which are called in priority order when the atom is initialized // Each atom can reference an array of these atom effect functions which are called in priority order when the atom is initialized
// https://recoiljs.org/docs/guides/atom-effects/#local-storage-persistence // https://recoiljs.org/docs/guides/atom-effects/#local-storage-persistence
export const settingState = atom<Settings>({ export const settingState = atom<Settings>({
key: 'settingsState', key: ROOT_STATE_KEY,
default: settingStateDefault, default: settingStateDefault,
effects: [localStorageEffect('settingsState')], effects: [localStorageEffect(ROOT_STATE_KEY)],
})
export const hdSettingsState = selector({
key: 'hdSettings',
get: ({ get }) => {
const settings = get(settingState)
return settings.hdSettings[settings.model]
},
set: ({ get, set }, newValue: any) => {
const settings = get(settingState)
const hdSettings = settings.hdSettings[settings.model]
const newHDSettings = { ...hdSettings, ...newValue }
set(settingState, {
...settings,
hdSettings: { ...settings.hdSettings, [settings.model]: newHDSettings },
})
},
}) })

View File

@ -2333,6 +2333,11 @@
resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz"
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
"@types/lodash@^4.14.182":
version "4.14.182"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.182.tgz#05301a4d5e62963227eaafe0ce04dd77c54ea5c2"
integrity sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==
"@types/minimatch@*": "@types/minimatch@*":
version "3.0.5" version "3.0.5"
resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz" resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz"
@ -7780,11 +7785,16 @@ lodash.uniq@^4.5.0:
resolved "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz" resolved "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz"
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
"lodash@>=3.5 <5", lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.5, lodash@^4.7.0: "lodash@>=3.5 <5", lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.5, lodash@^4.7.0:
version "4.17.21" version "4.17.21"
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
loglevel@^1.6.8: loglevel@^1.6.8:
version "1.7.1" version "1.7.1"
resolved "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz" resolved "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz"