From 335685d581e9183649dbb026e36ab6d3bf0f8858 Mon Sep 17 00:00:00 2001 From: Qing Date: Mon, 13 Jun 2022 16:50:51 +0800 Subject: [PATCH] add gradually inpainting mode --- lama_cleaner/app/package.json | 1 + lama_cleaner/app/src/adapters/inpainting.ts | 1 - .../app/src/components/Editor/Editor.tsx | 10 ++- .../GraduallyInpaintingSettingBlock.tsx | 32 +++++++++ .../src/components/Settings/SettingBlock.scss | 6 +- .../src/components/Settings/SettingBlock.tsx | 20 +++++- .../src/components/Settings/SettingsModal.tsx | 2 + .../app/src/components/shared/Tooltip.scss | 37 ++++++++++ .../app/src/components/shared/Tooltip.tsx | 29 ++++++++ lama_cleaner/app/src/store/Atoms.tsx | 2 + lama_cleaner/app/src/styles/_Animations.scss | 22 ++++++ lama_cleaner/app/src/styles/_Colors.scss | 5 +- lama_cleaner/app/src/styles/_ColorsDark.scss | 3 + lama_cleaner/app/src/utils.ts | 10 +++ lama_cleaner/app/yarn.lock | 72 +++++++++++++++++++ 15 files changed, 246 insertions(+), 6 deletions(-) create mode 100644 lama_cleaner/app/src/components/Settings/GraduallyInpaintingSettingBlock.tsx create mode 100644 lama_cleaner/app/src/components/shared/Tooltip.tsx diff --git a/lama_cleaner/app/package.json b/lama_cleaner/app/package.json index cb14365..dfddaeb 100644 --- a/lama_cleaner/app/package.json +++ b/lama_cleaner/app/package.json @@ -9,6 +9,7 @@ "@radix-ui/react-select": "0.1.2-rc.27", "@radix-ui/react-switch": "^0.1.5", "@radix-ui/react-toast": "^0.1.1", + "@radix-ui/react-tooltip": "^0.1.7", "@testing-library/jest-dom": "^5.14.1", "@testing-library/react": "^12.1.2", "@testing-library/user-event": "^13.5.0", diff --git a/lama_cleaner/app/src/adapters/inpainting.ts b/lama_cleaner/app/src/adapters/inpainting.ts index 3965d54..9c9e459 100644 --- a/lama_cleaner/app/src/adapters/inpainting.ts +++ b/lama_cleaner/app/src/adapters/inpainting.ts @@ -35,7 +35,6 @@ export default async function inpaint( method: 'POST', body: fd, }).then(async r => { - console.log(r) if (r.ok) { return r.blob() } diff --git a/lama_cleaner/app/src/components/Editor/Editor.tsx b/lama_cleaner/app/src/components/Editor/Editor.tsx index 8d08b8b..79c19f9 100644 --- a/lama_cleaner/app/src/components/Editor/Editor.tsx +++ b/lama_cleaner/app/src/components/Editor/Editor.tsx @@ -26,6 +26,7 @@ import { isMidClick, isRightClick, loadImage, + srcToFile, useImage, } from '../../utils' import { settingState, toastState } from '../../store/Atoms' @@ -150,9 +151,16 @@ export default function Editor(props: EditorProps) { setIsInpaintingLoading(true) drawAllLinesOnMask(newLineGroups) + let targetFile = file + if (settings.graduallyInpainting === true && renders.length > 0) { + console.info('gradually inpainting on last result') + const lastRender = renders[renders.length - 1] + targetFile = await srcToFile(lastRender.currentSrc, file.name, file.type) + } + try { const res = await inpaint( - file, + targetFile, maskCanvas.toDataURL(), settings, sizeLimit.toString() diff --git a/lama_cleaner/app/src/components/Settings/GraduallyInpaintingSettingBlock.tsx b/lama_cleaner/app/src/components/Settings/GraduallyInpaintingSettingBlock.tsx new file mode 100644 index 0000000..7487bb0 --- /dev/null +++ b/lama_cleaner/app/src/components/Settings/GraduallyInpaintingSettingBlock.tsx @@ -0,0 +1,32 @@ +import React from 'react' +import { useRecoilState } from 'recoil' +import { settingState } from '../../store/Atoms' +import { Switch, SwitchThumb } from '../shared/Switch' +import SettingBlock from './SettingBlock' + +const GraduallyInpaintingSettingBlock: React.FC = () => { + const [setting, setSettingState] = useRecoilState(settingState) + + const onCheckChange = (checked: boolean) => { + setSettingState(old => { + return { ...old, graduallyInpainting: checked } + }) + } + + return ( + + + + } + /> + ) +} + +export default GraduallyInpaintingSettingBlock diff --git a/lama_cleaner/app/src/components/Settings/SettingBlock.scss b/lama_cleaner/app/src/components/Settings/SettingBlock.scss index eabc7ae..49fa269 100644 --- a/lama_cleaner/app/src/components/Settings/SettingBlock.scss +++ b/lama_cleaner/app/src/components/Settings/SettingBlock.scss @@ -25,8 +25,10 @@ .setting-block-content-title { display: flex; - flex-direction: column; - justify-content: space-between; + flex-direction: row; + justify-content: center; + align-items: center; + gap: 8px; } .setting-block-desc { diff --git a/lama_cleaner/app/src/components/Settings/SettingBlock.tsx b/lama_cleaner/app/src/components/Settings/SettingBlock.tsx index 30bb7a1..026cde3 100644 --- a/lama_cleaner/app/src/components/Settings/SettingBlock.tsx +++ b/lama_cleaner/app/src/components/Settings/SettingBlock.tsx @@ -1,4 +1,5 @@ import React, { ReactNode } from 'react' +import Tooltip from '../shared/Tooltip' interface SettingBlockProps { title: string @@ -15,7 +16,24 @@ function SettingBlock(props: SettingBlockProps) {
{title} - {desc && {desc}} + {desc && ( + {desc}
}> + + + + + )}
{input} diff --git a/lama_cleaner/app/src/components/Settings/SettingsModal.tsx b/lama_cleaner/app/src/components/Settings/SettingsModal.tsx index 8cec752..06d7033 100644 --- a/lama_cleaner/app/src/components/Settings/SettingsModal.tsx +++ b/lama_cleaner/app/src/components/Settings/SettingsModal.tsx @@ -6,6 +6,7 @@ import Modal from '../shared/Modal' import ManualRunInpaintingSettingBlock from './ManualRunInpaintingSettingBlock' import HDSettingBlock from './HDSettingBlock' import ModelSettingBlock from './ModelSettingBlock' +import GraduallyInpaintingSettingBlock from './GraduallyInpaintingSettingBlock' interface SettingModalProps { onClose: () => void @@ -29,6 +30,7 @@ export default function SettingModal(props: SettingModalProps) { show={setting.show} > + diff --git a/lama_cleaner/app/src/components/shared/Tooltip.scss b/lama_cleaner/app/src/components/shared/Tooltip.scss index b55c253..f182d4f 100644 --- a/lama_cleaner/app/src/components/shared/Tooltip.scss +++ b/lama_cleaner/app/src/components/shared/Tooltip.scss @@ -31,3 +31,40 @@ $tooltip-margin: 1.5rem; margin-top: $tooltip-margin; } } + +// radix-ui +.tooltip-trigger { + all: unset; + display: flex; + justify-content: center; + align-items: center; +} + +.tooltip-content { + color: var(--tooltip-text-color); + background-color: var(--tooltip-bg); + padding: 10px 15px; + border-radius: 4px; + box-shadow: hsl(206 22% 7% / 35%) 0px 10px 38px -10px, + hsl(206 22% 7% / 20%) 0px 10px 20px -15px; + + @media (prefers-reduced-motion: no-preference) { + animation-duration: 400ms; + animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1); + animation-fill-mode: forwards; + will-change: transform, opacity; + + &[data-state='delayed-open'] { + &[data-side='top'] { + animation-name: slideDownAndFade; + } + &[data-side='bottom'] { + animation-name: slideUpAndFade; + } + } + } +} + +.tooltip-arrow { + fill: var(--tooltip-bg); +} diff --git a/lama_cleaner/app/src/components/shared/Tooltip.tsx b/lama_cleaner/app/src/components/shared/Tooltip.tsx new file mode 100644 index 0000000..9d2d995 --- /dev/null +++ b/lama_cleaner/app/src/components/shared/Tooltip.tsx @@ -0,0 +1,29 @@ +import React, { ReactNode } from 'react' +import * as TooltipPrimitive from '@radix-ui/react-tooltip' +import { TooltipProps } from '@radix-ui/react-tooltip' + +interface MyTooltipProps extends TooltipProps { + content: string | ReactNode + children: ReactNode +} + +const Tooltip = (props: MyTooltipProps) => { + const { content, children } = props + + return ( + + + + {children} + + + + {content} + + + + + ) +} + +export default Tooltip diff --git a/lama_cleaner/app/src/store/Atoms.tsx b/lama_cleaner/app/src/store/Atoms.tsx index 5317637..0279b1a 100644 --- a/lama_cleaner/app/src/store/Atoms.tsx +++ b/lama_cleaner/app/src/store/Atoms.tsx @@ -32,6 +32,7 @@ export const shortcutsState = atom({ export interface Settings { show: boolean + graduallyInpainting: boolean runInpaintingManually: boolean model: AIModel @@ -48,6 +49,7 @@ export interface Settings { export const settingStateDefault = { show: false, + graduallyInpainting: false, runInpaintingManually: false, model: AIModel.LAMA, ldmSteps: 50, diff --git a/lama_cleaner/app/src/styles/_Animations.scss b/lama_cleaner/app/src/styles/_Animations.scss index 17a2a7e..951ebd2 100644 --- a/lama_cleaner/app/src/styles/_Animations.scss +++ b/lama_cleaner/app/src/styles/_Animations.scss @@ -55,3 +55,25 @@ transform: rotate(360deg); } } + +@keyframes slideUpAndFade { + 0% { + opacity: 0; + transform: translateY(2px); + } + 100% { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes slideDownAndFade { + 0% { + opacity: 0; + transform: translateY(-2px); + } + 100% { + opacity: 1; + transform: translateY(0); + } +} diff --git a/lama_cleaner/app/src/styles/_Colors.scss b/lama_cleaner/app/src/styles/_Colors.scss index 6abfed1..fe26002 100644 --- a/lama_cleaner/app/src/styles/_Colors.scss +++ b/lama_cleaner/app/src/styles/_Colors.scss @@ -10,7 +10,7 @@ --border-color: rgb(100, 100, 120); --border-color-light: rgba(100, 100, 120, 0.5); --tooltip-bg: rgb(230, 230, 234); - --tooltip-text-color: rgb(0, 0,0); + --tooltip-text-color: rgb(0, 0, 0); --error-color: rgb(239, 68, 68); --success-color: rgb(16, 185, 129); @@ -44,4 +44,7 @@ --switch-root-background-color: rgb(223, 225, 228); --switch-thumb-color: var(--page-bg); --switch-thumb-checked-color: var(--page-bg); + + // tooltip + --tooltip-bg: var(--page-bg); } diff --git a/lama_cleaner/app/src/styles/_ColorsDark.scss b/lama_cleaner/app/src/styles/_ColorsDark.scss index 3fa2dcb..2f12da6 100644 --- a/lama_cleaner/app/src/styles/_ColorsDark.scss +++ b/lama_cleaner/app/src/styles/_ColorsDark.scss @@ -42,4 +42,7 @@ --switch-root-background-color: rgb(60, 63, 68); --switch-thumb-color: rgb(31, 32, 35); --switch-thumb-checked-color: white; + + // tooltip + --tooltip-bg: hsl(197 6.8% 13.6%); } diff --git a/lama_cleaner/app/src/utils.ts b/lama_cleaner/app/src/utils.ts index 7ff4b75..644c4b1 100644 --- a/lama_cleaner/app/src/utils.ts +++ b/lama_cleaner/app/src/utils.ts @@ -192,3 +192,13 @@ export function isMidClick(ev: SyntheticEvent) { const mouseEvent = ev.nativeEvent as MouseEvent return mouseEvent.button === 1 } + +export function srcToFile(src: string, fileName: string, mimeType: string) { + return fetch(src) + .then(function (res) { + return res.arrayBuffer() + }) + .then(function (buf) { + return new File([buf], fileName, { type: mimeType }) + }) +} diff --git a/lama_cleaner/app/yarn.lock b/lama_cleaner/app/yarn.lock index 2fdba23..3944d70 100644 --- a/lama_cleaner/app/yarn.lock +++ b/lama_cleaner/app/yarn.lock @@ -1551,6 +1551,14 @@ dependencies: "@babel/runtime" "^7.13.10" +"@radix-ui/popper@0.1.0": + version "0.1.0" + resolved "https://registry.npmmirror.com/@radix-ui/popper/-/popper-0.1.0.tgz#c387a38f31b7799e1ea0d2bb1ca0c91c2931b063" + integrity sha512-uzYeElL3w7SeNMuQpXiFlBhTT+JyaNMCwDfjKkrzugEcYrf5n52PHqncNdQPUtR42hJh8V9FsqyEDbDxkeNjJQ== + dependencies: + "@babel/runtime" "^7.13.10" + csstype "^3.0.4" + "@radix-ui/primitive@0.1.0": version "0.1.0" resolved "https://registry.npmmirror.com/@radix-ui/primitive/-/primitive-0.1.0.tgz#6206b97d379994f0d1929809db035733b337e543" @@ -1558,6 +1566,14 @@ dependencies: "@babel/runtime" "^7.13.10" +"@radix-ui/react-arrow@0.1.4": + version "0.1.4" + resolved "https://registry.npmmirror.com/@radix-ui/react-arrow/-/react-arrow-0.1.4.tgz#a871448a418cd3507d83840fdd47558cb961672b" + integrity sha512-BB6XzAb7Ml7+wwpFdYVtZpK1BlMgqyafSQNGzhIpSZ4uXvXOHPlR5GP8M449JkeQzgQjv9Mp1AsJxFC0KuOtuA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-primitive" "0.1.4" + "@radix-ui/react-collection@0.1.5-rc.18": version "0.1.5-rc.18" resolved "https://registry.npmmirror.com/@radix-ui/react-collection/-/react-collection-0.1.5-rc.18.tgz#4dc03a8f464643748c0dad781b472f149d671d5c" @@ -1706,6 +1722,21 @@ "@radix-ui/react-id" "0.1.6-rc.18" "@radix-ui/react-primitive" "0.1.5-rc.18" +"@radix-ui/react-popper@0.1.4": + version "0.1.4" + resolved "https://registry.npmmirror.com/@radix-ui/react-popper/-/react-popper-0.1.4.tgz#dfc055dcd7dfae6a2eff7a70d333141d15a5d029" + integrity sha512-18gDYof97t8UQa7zwklG1Dr8jIdj3u+rVOQLzPi9f5i1YQak/pVGkaqw8aY+iDUknKKuZniTk/7jbAJUYlKyOw== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/popper" "0.1.0" + "@radix-ui/react-arrow" "0.1.4" + "@radix-ui/react-compose-refs" "0.1.0" + "@radix-ui/react-context" "0.1.1" + "@radix-ui/react-primitive" "0.1.4" + "@radix-ui/react-use-rect" "0.1.1" + "@radix-ui/react-use-size" "0.1.1" + "@radix-ui/rect" "0.1.1" + "@radix-ui/react-portal@0.1.4": version "0.1.4" resolved "https://registry.npmmirror.com/@radix-ui/react-portal/-/react-portal-0.1.4.tgz#17bdce3d7f1a9a0b35cb5e935ab8bc562441a7d2" @@ -1833,6 +1864,27 @@ "@radix-ui/react-use-layout-effect" "0.1.0" "@radix-ui/react-visually-hidden" "0.1.4" +"@radix-ui/react-tooltip@^0.1.7": + version "0.1.7" + resolved "https://registry.npmmirror.com/@radix-ui/react-tooltip/-/react-tooltip-0.1.7.tgz#6f8c00d6e489565d14abf209ce0fb8853c8c8ee3" + integrity sha512-eiBUsVOHenZ0JR16tl970bB0DafJBz6mFgSGfIGIVpflFj0LIsIDiLMsYyvYdx1KwwsIUDTEZtxcPm/sWjPzqA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "0.1.0" + "@radix-ui/react-compose-refs" "0.1.0" + "@radix-ui/react-context" "0.1.1" + "@radix-ui/react-id" "0.1.5" + "@radix-ui/react-popper" "0.1.4" + "@radix-ui/react-portal" "0.1.4" + "@radix-ui/react-presence" "0.1.2" + "@radix-ui/react-primitive" "0.1.4" + "@radix-ui/react-slot" "0.1.2" + "@radix-ui/react-use-controllable-state" "0.1.0" + "@radix-ui/react-use-escape-keydown" "0.1.0" + "@radix-ui/react-use-previous" "0.1.1" + "@radix-ui/react-use-rect" "0.1.1" + "@radix-ui/react-visually-hidden" "0.1.4" + "@radix-ui/react-use-body-pointer-events@0.1.1": version "0.1.1" resolved "https://registry.npmmirror.com/@radix-ui/react-use-body-pointer-events/-/react-use-body-pointer-events-0.1.1.tgz#63e7fd81ca7ffd30841deb584cd2b7f460df2597" @@ -1923,6 +1975,14 @@ dependencies: "@babel/runtime" "^7.13.10" +"@radix-ui/react-use-rect@0.1.1": + version "0.1.1" + resolved "https://registry.npmmirror.com/@radix-ui/react-use-rect/-/react-use-rect-0.1.1.tgz#6c15384beee59c086e75b89a7e66f3d2e583a856" + integrity sha512-kHNNXAsP3/PeszEmM/nxBBS9Jbo93sO+xuMTcRfwzXsmxT5gDXQzAiKbZQ0EecCPtJIzqvr7dlaQi/aP1PKYqQ== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/rect" "0.1.1" + "@radix-ui/react-use-size@0.1.1": version "0.1.1" resolved "https://registry.npmmirror.com/@radix-ui/react-use-size/-/react-use-size-0.1.1.tgz#f6b75272a5d41c3089ca78c8a2e48e5f204ef90f" @@ -1946,6 +2006,13 @@ "@babel/runtime" "^7.13.10" "@radix-ui/react-primitive" "0.1.5-rc.18" +"@radix-ui/rect@0.1.1": + version "0.1.1" + resolved "https://registry.npmmirror.com/@radix-ui/rect/-/rect-0.1.1.tgz#95b5ba51f469bea6b1b841e2d427e17e37d38419" + integrity sha512-g3hnE/UcOg7REdewduRPAK88EPuLZtaq7sA9ouu8S+YEtnyFRI16jgv6GZYe3VMoQLL1T171ebmEPtDjyxWLzw== + dependencies: + "@babel/runtime" "^7.13.10" + "@rollup/plugin-node-resolve@^7.1.1": version "7.1.3" resolved "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz" @@ -4496,6 +4563,11 @@ csstype@^3.0.2, csstype@^3.0.6: resolved "https://registry.npmjs.org/csstype/-/csstype-3.0.9.tgz" integrity sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw== +csstype@^3.0.4: + version "3.1.0" + resolved "https://registry.npmmirror.com/csstype/-/csstype-3.1.0.tgz#4ddcac3718d787cf9df0d1b7d15033925c8f29f2" + integrity sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA== + cyclist@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz"