mirror of
https://github.com/easydiffusion/easydiffusion.git
synced 2025-04-23 10:58:25 +02:00
commit
a3b0cde59d
@ -70,38 +70,36 @@ label {
|
|||||||
font-size: 8pt;
|
font-size: 8pt;
|
||||||
}
|
}
|
||||||
.imgSeedLabel {
|
.imgSeedLabel {
|
||||||
position: absolute;
|
font-size: 1em;
|
||||||
transform: translateX(-100%);
|
background-color: rgb(44, 45, 48);
|
||||||
margin-top: 5pt;
|
border-radius: 5px;
|
||||||
margin-left: -5pt;
|
padding: 5px;
|
||||||
font-size: 10pt;
|
|
||||||
|
|
||||||
background-color: #333;
|
|
||||||
opacity: 0.8;
|
|
||||||
color: #ddd;
|
|
||||||
border-radius: 3pt;
|
|
||||||
padding: 1pt 3pt;
|
|
||||||
}
|
|
||||||
.imgUseBtn {
|
|
||||||
position: absolute;
|
|
||||||
transform: translateX(-100%);
|
|
||||||
margin-top: 30pt;
|
|
||||||
margin-left: -5pt;
|
|
||||||
}
|
|
||||||
.imgSaveBtn {
|
|
||||||
position: absolute;
|
|
||||||
transform: translateX(-100%);
|
|
||||||
margin-top: 55pt;
|
|
||||||
margin-left: -5pt;
|
|
||||||
}
|
}
|
||||||
.imgItem {
|
.imgItem {
|
||||||
display: inline;
|
display: inline-block;
|
||||||
padding-right: 10px;
|
margin-top: 1em;
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
.imgContainer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
.imgItemInfo {
|
.imgItemInfo {
|
||||||
opacity: 0.5;
|
padding-bottom: 0.5em;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
flex-direction: column;
|
||||||
|
position: absolute;
|
||||||
|
padding: 5px;
|
||||||
|
opacity: 0.25;
|
||||||
|
transition: 0.1s all;
|
||||||
|
}
|
||||||
|
.imgContainer:hover > .imgItemInfo {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.imgItemInfo * {
|
||||||
|
margin-bottom: 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#container {
|
#container {
|
||||||
width: 90%;
|
width: 90%;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
|
186
ui/media/main.js
186
ui/media/main.js
@ -259,18 +259,84 @@ async function healthCheck() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeImageElement(width, height, outputContainer) {
|
function showImages(req, res, livePreview) {
|
||||||
let imgItem = document.createElement('div')
|
res.output.forEach((result, index) => {
|
||||||
imgItem.className = 'imgItem'
|
if(typeof res != 'object') return;
|
||||||
|
|
||||||
let img = document.createElement('img')
|
const imageData = result?.data || result?.path + '?t=' + new Date().getTime(),
|
||||||
img.width = parseInt(width)
|
imageSeed = req.seed,
|
||||||
img.height = parseInt(height)
|
imageWidth = req.width,
|
||||||
|
imageHeight = req.height,
|
||||||
|
imageIdentifier = 'IMG_ID_' + (imageSeed + '').replace(/\d/g, c => 'SUOMIPERKL'[c]) + 'X'.repeat(index);
|
||||||
|
|
||||||
imgItem.appendChild(img)
|
if (!imageData.includes('/')) {
|
||||||
outputContainer.insertBefore(imgItem, outputContainer.firstChild)
|
// res contained no data for the image, stop execution
|
||||||
|
|
||||||
return imgItem
|
setStatus('request', 'invalid image', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let imageItemElem = document.querySelector('#' + imageIdentifier);
|
||||||
|
|
||||||
|
if(!imageItemElem) {
|
||||||
|
imageItemElem = document.createElement('div');
|
||||||
|
imageItemElem.className = 'imgItem';
|
||||||
|
imageItemElem.id = imageIdentifier;
|
||||||
|
imageItemElem.innerHTML = `
|
||||||
|
<div class="imgContainer">
|
||||||
|
<img/>
|
||||||
|
<div class="imgItemInfo">
|
||||||
|
<span class="imgSeedLabel"></span>
|
||||||
|
<button class="imgUseBtn">Use as Input</button>
|
||||||
|
<button class="imgSaveBtn">Download</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const useAsInputBtn = imageItemElem.querySelector('.imgUseBtn'),
|
||||||
|
saveImageBtn = imageItemElem.querySelector('.imgSaveBtn');
|
||||||
|
|
||||||
|
useAsInputBtn.addEventListener('click', e => {
|
||||||
|
const imgData = e.path.find(x => x == imageItemElem).querySelector('img').src;
|
||||||
|
|
||||||
|
initImageSelector.value = null;
|
||||||
|
initImagePreview.src = imgData;
|
||||||
|
|
||||||
|
initImagePreviewContainer.style.display = 'block';
|
||||||
|
inpaintingEditorContainer.style.display = 'none';
|
||||||
|
promptStrengthContainer.style.display = 'block';
|
||||||
|
maskSetting.checked = false;
|
||||||
|
|
||||||
|
// maskSetting.style.display = 'block';
|
||||||
|
|
||||||
|
randomSeedField.checked = false;
|
||||||
|
seedField.value = imageSeed;
|
||||||
|
seedField.disabled = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
saveImageBtn.addEventListener('click', e => {
|
||||||
|
const imgData = e.path.find(x => x == imageItemElem).querySelector('img').src;
|
||||||
|
|
||||||
|
const imgDownload = document.createElement('a');
|
||||||
|
imgDownload.download = createFileName(imageSeed);
|
||||||
|
imgDownload.href = imgData;
|
||||||
|
imgDownload.click();
|
||||||
|
});
|
||||||
|
|
||||||
|
imagesContainer.appendChild(imageItemElem);
|
||||||
|
}
|
||||||
|
|
||||||
|
const imageElem = imageItemElem.querySelector('img'),
|
||||||
|
imageSeedLabel = imageItemElem.querySelector('.imgSeedLabel');
|
||||||
|
|
||||||
|
imageElem.src = imageData;
|
||||||
|
imageElem.width = parseInt(imageWidth);
|
||||||
|
imageElem.height = parseInt(imageHeight);
|
||||||
|
|
||||||
|
imageSeedLabel.innerText = livePreview
|
||||||
|
? '(Live Preview)'
|
||||||
|
: 'Seed: ' + imageSeed;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// makes a single image. don't call this directly, use makeImage() instead
|
// makes a single image. don't call this directly, use makeImage() instead
|
||||||
@ -291,14 +357,6 @@ async function doMakeImage(task) {
|
|||||||
let seed = reqBody['seed']
|
let seed = reqBody['seed']
|
||||||
let numOutputs = parseInt(reqBody['num_outputs'])
|
let numOutputs = parseInt(reqBody['num_outputs'])
|
||||||
|
|
||||||
let images = []
|
|
||||||
|
|
||||||
function makeImageContainers(numImages) {
|
|
||||||
for (let i = images.length; i < numImages; i++) {
|
|
||||||
images.push(makeImageElement(reqBody.width, reqBody.height, outputContainer))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
res = await fetch('/image', {
|
res = await fetch('/image', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -351,14 +409,7 @@ async function doMakeImage(task) {
|
|||||||
outputMsg.style.display = 'block'
|
outputMsg.style.display = 'block'
|
||||||
|
|
||||||
if (stepUpdate.output !== undefined) {
|
if (stepUpdate.output !== undefined) {
|
||||||
makeImageContainers(numOutputs)
|
showImages(reqBody, stepUpdate, true);
|
||||||
|
|
||||||
for (idx in stepUpdate.output) {
|
|
||||||
let imgItem = images[idx]
|
|
||||||
let img = imgItem.firstChild
|
|
||||||
let tmpImageData = stepUpdate.output[idx]
|
|
||||||
img.src = tmpImageData['path'] + '?t=' + new Date().getTime()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -426,87 +477,13 @@ async function doMakeImage(task) {
|
|||||||
res = undefined
|
res = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!res) {
|
if (!res) return false;
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
lastPromptUsed = reqBody['prompt']
|
lastPromptUsed = reqBody['prompt'];
|
||||||
|
|
||||||
makeImageContainers(res.output.length)
|
showImages(reqBody, res, false);
|
||||||
|
|
||||||
for (let idx in res.output) {
|
return true;
|
||||||
let imgBody = ''
|
|
||||||
let seed = 0
|
|
||||||
|
|
||||||
try {
|
|
||||||
let imgData = res.output[idx]
|
|
||||||
imgBody = imgData.data
|
|
||||||
seed = imgData.seed
|
|
||||||
} catch (e) {
|
|
||||||
console.log(imgBody)
|
|
||||||
setStatus('request', 'invalid image', 'error')
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
let imgItem = images[idx]
|
|
||||||
let img = imgItem.firstChild
|
|
||||||
|
|
||||||
img.src = imgBody
|
|
||||||
|
|
||||||
let imgItemInfo = document.createElement('span')
|
|
||||||
imgItemInfo.className = 'imgItemInfo'
|
|
||||||
imgItemInfo.style.opacity = 0
|
|
||||||
|
|
||||||
let imgSeedLabel = document.createElement('span')
|
|
||||||
imgSeedLabel.className = 'imgSeedLabel'
|
|
||||||
imgSeedLabel.innerText = 'Seed: ' + seed
|
|
||||||
|
|
||||||
let imgUseBtn = document.createElement('button')
|
|
||||||
imgUseBtn.className = 'imgUseBtn'
|
|
||||||
imgUseBtn.innerText = 'Use as Input'
|
|
||||||
|
|
||||||
let imgSaveBtn = document.createElement('button')
|
|
||||||
imgSaveBtn.className = 'imgSaveBtn'
|
|
||||||
imgSaveBtn.innerText = 'Download'
|
|
||||||
|
|
||||||
imgItem.appendChild(imgItemInfo)
|
|
||||||
imgItemInfo.appendChild(imgSeedLabel)
|
|
||||||
imgItemInfo.appendChild(imgUseBtn)
|
|
||||||
imgItemInfo.appendChild(imgSaveBtn)
|
|
||||||
|
|
||||||
imgUseBtn.addEventListener('click', function() {
|
|
||||||
initImageSelector.value = null
|
|
||||||
initImagePreview.src = imgBody
|
|
||||||
|
|
||||||
initImagePreviewContainer.style.display = 'block'
|
|
||||||
inpaintingEditorContainer.style.display = 'none'
|
|
||||||
promptStrengthContainer.style.display = 'block'
|
|
||||||
maskSetting.checked = false
|
|
||||||
|
|
||||||
// maskSetting.style.display = 'block'
|
|
||||||
|
|
||||||
randomSeedField.checked = false
|
|
||||||
seedField.value = seed
|
|
||||||
seedField.disabled = false
|
|
||||||
})
|
|
||||||
|
|
||||||
imgSaveBtn.addEventListener('click', function() {
|
|
||||||
let imgDownload = document.createElement('a')
|
|
||||||
imgDownload.download = createFileName();
|
|
||||||
imgDownload.href = imgBody
|
|
||||||
imgDownload.click()
|
|
||||||
})
|
|
||||||
|
|
||||||
imgItem.addEventListener('mouseenter', function() {
|
|
||||||
imgItemInfo.style.opacity = 1
|
|
||||||
})
|
|
||||||
|
|
||||||
imgItem.addEventListener('mouseleave', function() {
|
|
||||||
imgItemInfo.style.opacity = 0
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function checkTasks() {
|
async function checkTasks() {
|
||||||
@ -734,12 +711,11 @@ async function makeImage() {
|
|||||||
|
|
||||||
// create a file name with embedded prompt and metadata
|
// create a file name with embedded prompt and metadata
|
||||||
// for easier cateloging and comparison
|
// for easier cateloging and comparison
|
||||||
function createFileName() {
|
function createFileName(seed) {
|
||||||
|
|
||||||
// Most important information is the prompt
|
// Most important information is the prompt
|
||||||
let underscoreName = lastPromptUsed.replace(/[^a-zA-Z0-9]/g, '_')
|
let underscoreName = lastPromptUsed.replace(/[^a-zA-Z0-9]/g, '_')
|
||||||
underscoreName = underscoreName.substring(0, 100)
|
underscoreName = underscoreName.substring(0, 100)
|
||||||
const seed = seedField.value
|
|
||||||
const steps = numInferenceStepsField.value
|
const steps = numInferenceStepsField.value
|
||||||
const guidance = guidanceScaleField.value
|
const guidance = guidanceScaleField.value
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user