Add User Input Image Support

Users can now supply the --input argument to load their image by default to the application.
This commit is contained in:
blessedcoolant 2022-03-25 07:33:13 +13:00
parent 481e956c3a
commit d0f025f2d4
6 changed files with 56 additions and 6 deletions

View File

@ -1,7 +1,7 @@
{
"files": {
"main.css": "/static/css/main.0a04cd80.chunk.css",
"main.js": "/static/js/main.288df200.chunk.js",
"main.js": "/static/js/main.9e3e6c89.chunk.js",
"runtime-main.js": "/static/js/runtime-main.5e86ac81.js",
"static/js/2.d3149f41.chunk.js": "/static/js/2.d3149f41.chunk.js",
"index.html": "/index.html",
@ -11,6 +11,6 @@
"static/js/runtime-main.5e86ac81.js",
"static/js/2.d3149f41.chunk.js",
"static/css/main.0a04cd80.chunk.css",
"static/js/main.288df200.chunk.js"
"static/js/main.9e3e6c89.chunk.js"
]
}

View File

@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"/><meta name="theme-color" content="#ffffff"/><title>lama-cleaner - Image inpainting powered by LaMa</title><link href="/static/css/main.0a04cd80.chunk.css" rel="stylesheet"></head><body class="h-screen"><noscript>You need to enable JavaScript to run this app.</noscript><div id="root" class="h-full"></div><script>"localhost"===location.hostname&&(self.FIREBASE_APPCHECK_DEBUG_TOKEN=!0)</script><script>!function(e){function r(r){for(var n,l,a=r[0],f=r[1],i=r[2],p=0,s=[];p<a.length;p++)l=a[p],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in f)Object.prototype.hasOwnProperty.call(f,n)&&(e[n]=f[n]);for(c&&c(r);s.length;)s.shift()();return u.push.apply(u,i||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,a=1;a<t.length;a++){var f=t[a];0!==o[f]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="/";var a=this["webpackJsonplama-cleaner"]=this["webpackJsonplama-cleaner"]||[],f=a.push.bind(a);a.push=r,a=a.slice();for(var i=0;i<a.length;i++)r(a[i]);var c=f;t()}([])</script><script src="/static/js/2.d3149f41.chunk.js"></script><script src="/static/js/main.288df200.chunk.js"></script></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"/><meta name="theme-color" content="#ffffff"/><title>lama-cleaner - Image inpainting powered by LaMa</title><link href="/static/css/main.0a04cd80.chunk.css" rel="stylesheet"></head><body class="h-screen"><noscript>You need to enable JavaScript to run this app.</noscript><div id="root" class="h-full"></div><script>"localhost"===location.hostname&&(self.FIREBASE_APPCHECK_DEBUG_TOKEN=!0)</script><script>!function(e){function r(r){for(var n,l,a=r[0],f=r[1],i=r[2],p=0,s=[];p<a.length;p++)l=a[p],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in f)Object.prototype.hasOwnProperty.call(f,n)&&(e[n]=f[n]);for(c&&c(r);s.length;)s.shift()();return u.push.apply(u,i||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,a=1;a<t.length;a++){var f=t[a];0!==o[f]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="/";var a=this["webpackJsonplama-cleaner"]=this["webpackJsonplama-cleaner"]||[],f=a.push.bind(a);a.push=r,a=a.slice();for(var i=0;i<a.length;i++)r(a[i]);var c=f;t()}([])</script><script src="/static/js/2.d3149f41.chunk.js"></script><script src="/static/js/main.9e3e6c89.chunk.js"></script></body></html>

View File

@ -1,8 +1,9 @@
import { ArrowLeftIcon } from '@heroicons/react/outline'
import React, { useState } from 'react'
import React, { useEffect, useState } from 'react'
import { useToggle, useWindowSize } from 'react-use'
import Button from './components/Button'
import FileSelect from './components/FileSelect'
import useInputImage from './components/hooks/useInputImage'
import ShortcutsModal from './components/ShortcutsModal'
import Editor from './Editor'
@ -31,6 +32,11 @@ function App() {
const [file, setFile] = useState<File>()
const [showShortcuts, toggleShowShortcuts] = useToggle(false)
const windowSize = useWindowSize()
const userInputImage = useInputImage()
useEffect(() => {
setFile(userInputImage)
}, [userInputImage])
return (
<div className="h-full full-visible-h-safari flex flex-col">

View File

@ -0,0 +1,22 @@
import { useCallback, useEffect, useState } from 'react'
export default function useInputImage() {
const [inputImage, setInputImage] = useState()
const fetchInputImage = useCallback(() => {
fetch('/inputimage')
.then(res => res.blob())
.then(data => {
if (data && data.type.startsWith('image')) {
const userInput = new File([data], 'inputImage')
setInputImage(userInput)
}
})
}, [setInputImage])
useEffect(() => {
fetchInputImage()
}, [])
return inputImage
}

24
main.py
View File

@ -5,6 +5,7 @@ import io
import multiprocessing
import os
import time
import imghdr
from typing import Union
import cv2
@ -98,8 +99,24 @@ def index():
return send_file(os.path.join(BUILD_DIR, "index.html"))
@app.route('/inputimage')
def set_input_photo():
filename = os.path.join(os.path.dirname(__file__), input_image)
if (os.path.exists(filename)):
if (imghdr.what(filename) is not None):
with open(filename, 'rb') as f:
byte_im = f.read()
return send_file(io.BytesIO(byte_im), mimetype='image/jpeg')
else:
return 'Invalid Input'
else:
return 'Invalid Input'
def get_args_parser():
parser = argparse.ArgumentParser()
parser.add_argument(
"--input", default='', type=str, help="Path to image you want to load by default")
parser.add_argument("--port", default=8080, type=int)
parser.add_argument("--model", default="lama", choices=["lama", "ldm"])
parser.add_argument("--crop-trigger-size", nargs=2, type=int,
@ -128,11 +145,16 @@ def get_args_parser():
def main():
global model
global device
global input_image
args = get_args_parser()
device = torch.device(args.device)
input_image = args.input
if args.model == "lama":
model = LaMa(crop_trigger_size=args.crop_trigger_size, crop_margin=args.crop_margin, device=device)
model = LaMa(crop_trigger_size=args.crop_trigger_size,
crop_margin=args.crop_margin, device=device)
elif args.model == "ldm":
model = LDM(device, steps=args.ldm_steps)
else: