2022-08-23 22:28:18 +02:00
<!DOCTYPE html>
< html >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< style >
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 11pt;
}
#prompt {
width: 50vw;
height: 50pt;
}
@media screen and (max-width: 600px) {
#prompt {
width: 95%;
}
}
2022-08-24 09:03:35 +02:00
#configHeader {
margin-top: 5px;
margin-bottom: 5px;
font-size: 10pt;
}
#config {
font-size: 9pt;
margin-bottom: 5px;
padding-left: 10px;
}
#outputMsg {
font-size: small;
2022-08-23 22:28:18 +02:00
}
#footer {
margin-top: 5px;
padding-top: 5px;
font-size: small;
}
< / style >
< / html >
< body >
< h3 > Stable Diffusion - Quick UI< / h3 >
< div id = "status" > Server status: < span id = "serverStatus" > checking..< / span > | Request status: < span id = "reqStatus" > n/a< / span > < / div >
< br / >
< b > Prompt:< / b > < br / >
< textarea id = "prompt" > a photograph of an astronaut riding a horse< / textarea > < br / >
2022-08-24 09:03:35 +02:00
< div id = "configHeader" > < b > Advanced settings:< / b > [< a id = "configToggleBtn" href = "#" > show< / a > ]< / div >
< div id = "config" >
< label for = "seed" > Seed:< / label > < input id = "seed" name = "seed" value = "30000" > < small > (use -1 for random seed)< / small > < br / >
< label for = "num_outputs" > Number of outputs:< / label > < select id = "num_outputs" name = "num_outputs" value = "1" > < option value = "1" selected > 1< / option > < option value = "4" > 4< / option > < / select > < br / >
< label for = "width" > Width:< / label > < select id = "width" name = "width" value = "512" > < option value = "128" > 128< / option > < option value = "256" > 256< / option > < option value = "512" selected > 512< / option > < option value = "768" > 768< / option > < option value = "1024" > 1024< / option > < / select > < br / >
< label for = "height" > Height:< / label > < select id = "height" name = "height" value = "512" > < option value = "128" > 128< / option > < option value = "256" > 256< / option > < option value = "512" selected > 512< / option > < option value = "768" > 768< / option > < / select > < br / >
< label for = "num_inference_steps" > Number of inference steps:< / label > < input id = "num_inference_steps" name = "num_inference_steps" value = "50" > < br / >
2022-08-24 09:13:50 +02:00
< label for = "guidance_scale" > Guidance Scale:< / label > < input id = "guidance_scale" name = "guidance_scale" value = "75" type = "range" min = "10" max = "200" > < span id = "guidance_scale_value" > < / span > < / span > < br / >
2022-08-24 09:03:35 +02:00
< / div >
2022-08-23 22:28:18 +02:00
< button id = "makeImage" > Make Image< / button > < br / > < br / >
2022-08-24 09:03:35 +02:00
< div id = "outputMsg" > < / div >
< div id = "images" > < / div >
2022-08-23 22:28:18 +02:00
< div id = "footer" >
2022-08-24 09:35:33 +02:00
< p > Please feel free to < a href = "mailto:sd@cmdr2.org" target = "_blank" > email me< / a > or < a href = "https://github.com/cmdr2/stable-diffusion-ui/issues" target = "_blank" > file an issue< / a > if you have any problems or suggestions in using this interface.< / p >
2022-08-23 22:28:18 +02:00
< p > < b > Disclaimer:< / b > I am not responsible for any images generated using this interface.< / p >
< / div >
< / body >
< script >
const HEALTH_PING_INTERVAL = 5 // seconds
function setStatus(statusType, msg, msgType) {
let el = ''
if (statusType === 'server') {
el = '#serverStatus'
} else if (statusType === 'request') {
el = '#reqStatus'
}
if (msgType == 'error') {
msg = '< span style = "color: red" > ' + msg + '< span > '
} else if (msgType == 'success') {
msg = '< span style = "color: green" > ' + msg + '< span > '
}
if (el) {
document.querySelector(el).innerHTML = msg
}
}
function playSound() {
const audio = new Audio('/ding.mp3')
audio.play()
}
async function healthCheck() {
try {
let res = await fetch('/ping')
res = await res.json()
if (res[0] == 'OK') {
setStatus('server', 'online', 'success')
} else {
setStatus('server', 'offline', 'error')
}
} catch (e) {
setStatus('server', 'offline', 'error')
}
}
async function makeImage() {
setStatus('request', 'fetching..')
let btn = document.querySelector('#makeImage')
btn.innerHTML = 'Processing..'
btn.disabled = true;
2022-08-24 09:03:35 +02:00
let outputMsg = document.querySelector('#outputMsg')
let reqBody = {
prompt: document.querySelector('#prompt').value,
num_outputs: document.querySelector('#num_outputs').value,
num_inference_steps: document.querySelector('#num_inference_steps').value,
2022-08-24 09:13:50 +02:00
guidance_scale: document.querySelector('#guidance_scale').value / 10,
2022-08-24 09:03:35 +02:00
width: document.querySelector('#width').value,
height: document.querySelector('#height').value,
seed: document.querySelector('#seed').value,
}
2022-08-23 22:28:18 +02:00
let res = ''
2022-08-24 09:03:35 +02:00
let time = new Date().getTime()
2022-08-23 22:28:18 +02:00
try {
res = await fetch('/image', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
2022-08-24 09:03:35 +02:00
body: JSON.stringify(reqBody)
2022-08-23 22:28:18 +02:00
})
res = await res.json()
2022-08-24 09:03:35 +02:00
if (res.status !== 'succeeded') {
if (res.detail !== undefined) {
outputMsg.innerHTML = 'Error: ' + res.detail[0].msg + " in " + JSON.stringify(res.detail[0].loc)
} else {
outputMsg.innerHTML = 'Error: ' + res
}
outputMsg.innerHTML = '< span style = "color: red" > ' + outputMsg.innerHTML + '< / span > '
console.log('request error', res)
setStatus('request', 'error', 'error')
res = undefined
}
2022-08-23 22:28:18 +02:00
} catch (e) {
console.log('request error', e)
setStatus('request', 'error', 'error')
}
btn.innerHTML = 'Make Image'
btn.disabled = false;
playSound()
if (!res) {
return
}
2022-08-24 09:03:35 +02:00
time = new Date().getTime() - time
time /= 1000
2022-08-23 22:28:18 +02:00
2022-08-24 09:03:35 +02:00
outputMsg.innerHTML = 'Processed in ' + time + ' seconds'
2022-08-23 22:28:18 +02:00
2022-08-24 09:03:35 +02:00
let images = document.querySelector('#images')
images.innerHTML = ''
for (let idx in res.output) {
let imgBody = ''
try {
imgBody = res.output[idx]
} catch (e) {
console.log(imgBody)
setStatus('request', 'invalid image', 'error')
return
}
let img = document.createElement('img')
img.width = parseInt(reqBody.width)
img.height = parseInt(reqBody.height)
img.src = imgBody
images.appendChild(img)
}
2022-08-23 22:28:18 +02:00
setStatus('request', 'done', 'success')
}
document.querySelector('#makeImage').addEventListener('click', makeImage)
2022-08-24 09:03:35 +02:00
let config = document.querySelector('#config')
config.style.display = 'none'
document.querySelector('#configToggleBtn').addEventListener('click', function() {
config.style.display = (config.style.display === 'none' ? 'block' : 'none')
document.querySelector('#configToggleBtn').innerHTML = (config.style.display === 'none' ? 'show' : 'hide')
return false
})
2022-08-24 09:13:50 +02:00
let guidanceScale = document.querySelector('#guidance_scale')
function updateGuidanceScale() {
let label = document.querySelector('#guidance_scale_value')
label.innerHTML = guidanceScale.value / 10
}
guidanceScale.addEventListener('input', updateGuidanceScale)
updateGuidanceScale()
2022-08-23 22:28:18 +02:00
setInterval(healthCheck, HEALTH_PING_INTERVAL * 1000)
< / script >
< / html >