Merge branch 'beta' into refactor

This commit is contained in:
cmdr2 2022-12-12 20:43:29 +05:30
commit ceff4f06c1
5 changed files with 66 additions and 124 deletions

View File

@ -2,12 +2,12 @@
## v2.4
### Major Changes
- **Automatic scanning for malicious model files** - using `picklescan`, and support for `safetensor` model format. Thanks @JeLuf
- **Support for custom VAE models**. You can place your VAE files in the `models/vae` folder, and refresh the browser page to use them. More info: https://github.com/cmdr2/stable-diffusion-ui/wiki/VAE-Variational-Auto-Encoder
- **Use pre-trained hypernetworks** - for improving the quality of images. Thanks @C0bra5
- **Experimental support for multiple GPUs!** It should work automatically. Just open one browser tab per GPU, and spread your tasks across your GPUs. For e.g. open our UI in two browser tabs if you have two GPUs. You can customize which GPUs it should use in the "Settings" tab, otherwise let it automatically pick the best GPUs. Thanks @madrang . More info: https://github.com/cmdr2/stable-diffusion-ui/wiki/Run-on-Multiple-GPUs
- **Image Editor** - for drawing simple images for guiding the AI. Thanks @mdiller
- **Allow reordering the task queue** (by dragging and dropping tasks). Thanks @madrang
- **Automatic scanning for malicious model files** - using `picklescan`, and support for `safetensor` model format. Thanks @JeLuf
- **Image Editor** - for drawing simple images for guiding the AI. Thanks @mdiller
- **Use pre-trained hypernetworks** - for improving the quality of images. Thanks @C0bra5
- **Support for custom VAE models**. You can place your VAE files in the `models/vae` folder, and refresh the browser page to use them. More info: https://github.com/cmdr2/stable-diffusion-ui/wiki/VAE-Variational-Auto-Encoder
- **Experimental support for multiple GPUs!** It should work automatically. Just open one browser tab per GPU, and spread your tasks across your GPUs. For e.g. open our UI in two browser tabs if you have two GPUs. You can customize which GPUs it should use in the "Settings" tab, otherwise let it automatically pick the best GPUs. Thanks @madrang . More info: https://github.com/cmdr2/stable-diffusion-ui/wiki/Run-on-Multiple-GPUs
- **Cleaner UI design** - Show settings and help in new tabs, instead of dropdown popups (which were buggy). Thanks @mdiller
- **Progress bar.** Thanks @mdiller
- **Custom Image Modifiers** - You can now save your custom image modifiers! Your saved modifiers can include special characters like `{}, (), [], |`

View File

@ -47,7 +47,7 @@
<div id="tab-content-wrapper">
<div id="tab-content-main" class="tab-content active flex-container">
<div id="editor" class="scrollbar-editor">
<div id="editor">
<div id="editor-inputs">
<div id="editor-inputs-prompt" class="row">
<label for="prompt"><b>Enter Prompt</b></label> <small>or</small> <button id="promptsFromFileBtn">Load from a file</button>
@ -131,12 +131,6 @@
</select>
<a href="https://github.com/cmdr2/stable-diffusion-ui/wiki/VAE-Variational-Auto-Encoder" target="_blank"><i class="fa-solid fa-circle-question help-btn"><span class="simple-tooltip top-left">Click to learn more about VAEs</span></i></a>
</td></tr>
<tr class="pl-5"><td><label for="hypernetwork_model">Hypernetwork:</i></label></td><td>
<select id="hypernetwork_model" name="hypernetwork_model">
<!-- <option value="" selected>None</option> -->
</select>
</td></tr>
<tr id="hypernetwork_strength_container" class="pl-5"><td><label for="hypernetwork_strength_slider">Hypernetwork Strength:</label></td><td> <input id="hypernetwork_strength_slider" name="hypernetwork_strength_slider" class="editor-slider" value="100" type="range" min="0" max="100"> <input id="hypernetwork_strength" name="hypernetwork_strength" size="4" pattern="^[0-9\.]+$" onkeypress="preventNonNumericalInput(event)"><br/></td></tr></span>
<tr id="samplerSelection" class="pl-5"><td><label for="sampler_name">Sampler:</label></td><td>
<select id="sampler_name" name="sampler_name">
<option value="plms">plms</option>
@ -198,7 +192,16 @@
</td></tr>
<tr class="pl-5"><td><label for="num_inference_steps">Inference Steps:</label></td><td> <input id="num_inference_steps" name="num_inference_steps" size="4" value="25" onkeypress="preventNonNumericalInput(event)"></td></tr>
<tr class="pl-5"><td><label for="guidance_scale_slider">Guidance Scale:</label></td><td> <input id="guidance_scale_slider" name="guidance_scale_slider" class="editor-slider" value="75" type="range" min="10" max="500"> <input id="guidance_scale" name="guidance_scale" size="4" pattern="^[0-9\.]+$" onkeypress="preventNonNumericalInput(event)"></td></tr>
<tr id="prompt_strength_container" class="pl-5"><td><label for="prompt_strength_slider">Prompt Strength:</label></td><td> <input id="prompt_strength_slider" name="prompt_strength_slider" class="editor-slider" value="80" type="range" min="0" max="99"> <input id="prompt_strength" name="prompt_strength" size="4" pattern="^[0-9\.]+$" onkeypress="preventNonNumericalInput(event)"><br/></td></tr></span>
<tr id="prompt_strength_container" class="pl-5"><td><label for="prompt_strength_slider">Prompt Strength:</label></td><td> <input id="prompt_strength_slider" name="prompt_strength_slider" class="editor-slider" value="80" type="range" min="0" max="99"> <input id="prompt_strength" name="prompt_strength" size="4" pattern="^[0-9\.]+$" onkeypress="preventNonNumericalInput(event)"><br/></td></tr>
<tr class="pl-5"><td><label for="hypernetwork_model">Hypernetwork:</i></label></td><td>
<select id="hypernetwork_model" name="hypernetwork_model">
<!-- <option value="" selected>None</option> -->
</select>
</td></tr>
<tr id="hypernetwork_strength_container" class="pl-5">
<td><label for="hypernetwork_strength_slider">Hypernetwork Strength:</label></td>
<td> <input id="hypernetwork_strength_slider" name="hypernetwork_strength_slider" class="editor-slider" value="100" type="range" min="0" max="100"> <input id="hypernetwork_strength" name="hypernetwork_strength" size="4" pattern="^[0-9\.]+$" onkeypress="preventNonNumericalInput(event)"><br/></td>
</tr>
<tr class="pl-5"><td><label for="output_format">Output Format:</label></td><td>
<select id="output_format" name="output_format">
<option value="jpeg" selected>jpeg</option>
@ -206,8 +209,8 @@
</select>
</td></tr>
<tr class="pl-5" id="output_quality_row"><td><label for="output_quality">JPEG Quality:</label></td><td>
<input id="output_quality_slider" name="output_quality" class="editor-slider" value="75" type="range" min="10" max="95"> <input id="output_quality" name="output_quality" size="4" pattern="^[0-9\.]+$" onkeypress="preventNonNumericalInput(event)">
</td></tr>
<input id="output_quality_slider" name="output_quality" class="editor-slider" value="75" type="range" min="10" max="95"> <input id="output_quality" name="output_quality" size="4" pattern="^[0-9\.]+$" onkeypress="preventNonNumericalInput(event)">
</td></tr>
</table></div>
<div><ul>

View File

@ -139,7 +139,7 @@ code {
padding: 16px;
display: flex;
flex-direction: column;
flex: 0 0 370pt;
flex: 0 0 380pt;
}
#editor label {
font-weight: normal;
@ -783,6 +783,9 @@ input::file-selector-button {
}
@media (min-width: 700px) {
/* #editor {
max-width: 480px;
}*/
.float-container {
padding: 20px;
}
@ -791,53 +794,6 @@ input::file-selector-button {
float: left;
padding: 20px;
}
#editor {
position: fixed;
overflow-y: auto;
top: 0;
bottom: 0;
overflow-x: hidden;
padding-right: 8px;
z-index: 1;
width: 374pt;
}
#preview {
padding-left: 380pt;
margin-right: 10pt;
left: 0;
right:0;
min-height: 80vh;
}
#preview-pane {
display: none;
overflow-y: auto;
margin-top: 8pt;
left: 0;
right:0;
}
#preview-tools {
background: var(--background-color1);
position: sticky;
top: 0;
transition: 0.25s;
z-index: 1;
padding-top:10px;
padding-bottom: 10px;
-webkit-mask-image: linear-gradient(to bottom, black 0%, black 90%, transparent 100%);
mask-image: linear-gradient(to bottom, black 0%, black 50%, transparent 100%);
}
#editor-modifiers {
overflow-y: initial;
overflow-x: initial;
}
.image_preview_container {
padding: 6px;
width: 454px;
}
}
.help-btn {
@ -1124,36 +1080,3 @@ button#save-system-settings-btn {
#ip-info div {
line-height: 200%;
}
/* SCROLLBARS */
:root {
--scrollbar-width: 14px;
--scrollbar-radius: 10px;
}
.scrollbar-editor::-webkit-scrollbar {
width: 8px;
}
.scrollbar-editor::-webkit-scrollbar-track {
border-radius: 10px;
}
.scrollbar-editor::-webkit-scrollbar-thumb {
background: --background-color2;
border-radius: 10px;
}
::-webkit-scrollbar {
width: var(--scrollbar-width);
}
::-webkit-scrollbar-track {
box-shadow: inset 0 0 5px var(--input-border-color);
border-radius: var(--input-border-radius);
}
::-webkit-scrollbar-thumb {
background: var(--background-color2);
border-radius: var(--scrollbar-radius);
}

View File

@ -194,6 +194,28 @@ const TASK_MAPPING = {
readUI: () => vaeModelField.value,
parse: (val) => val
},
use_hypernetwork_model: { name: 'Hypernetwork model',
setUI: (use_hypernetwork_model) => {
const oldVal = hypernetworkModelField.value
if (use_hypernetwork_model !== '') {
use_hypernetwork_model = getModelPath(use_hypernetwork_model, ['.pt'])
use_hypernetwork_model = use_hypernetwork_model !== '' ? use_hypernetwork_model : oldVal
}
hypernetworkModelField.value = use_hypernetwork_model
hypernetworkModelField.dispatchEvent(new Event('change'))
},
readUI: () => hypernetworkModelField.value,
parse: (val) => val
},
hypernetwork_strength: { name: 'Hypernetwork Strength',
setUI: (hypernetwork_strength) => {
hypernetworkStrengthField.value = hypernetwork_strength
updateHypernetworkStrengthSlider()
},
readUI: () => parseFloat(hypernetworkStrengthField.value),
parse: (val) => parseFloat(val)
},
num_outputs: { name: 'Parallel Images',
setUI: (num_outputs) => {
@ -331,7 +353,9 @@ const TASK_TEXT_MAPPING = {
use_upscale: 'Use Upscaling',
sampler: 'Sampler',
negative_prompt: 'Negative Prompt',
use_stable_diffusion_model: 'Stable Diffusion model'
use_stable_diffusion_model: 'Stable Diffusion model',
use_hypernetwork_model: 'Hypernetwork model',
hypernetwork_strength: 'Hypernetwork Strength'
}
const afterPromptRe = /^\s*Width\s*:\s*\d+\s*(?:\r\n|\r|\n)+\s*Height\s*:\s*\d+\s*(\r\n|\r|\n)+Seed\s*:\s*\d+\s*$/igm
function parseTaskFromText(str) {

View File

@ -61,29 +61,6 @@ let maskSetting = document.querySelector('#enable_mask')
const processOrder = document.querySelector('#process_order_toggle')
const editorContainer = document.querySelector('#editor')
window.addEventListener("scroll", updatePreviewSize)
let lastScrollTop = 0
updatePreviewSize()
// update preview pane size and position
function updatePreviewSize() {
const scrollTop = window.pageYOffset || document.documentElement.scrollTop
if (scrollTop > lastScrollTop) {
previewTools.style.top = -previewTools.offsetHeight + 'px'
}
else if (scrollTop < lastScrollTop) {
const elem = preview.getElementsByClassName('img-batch')[0]
if (elem !== undefined && Math.round(window.scrollY) !== Math.round(elem.closest(".imageTaskContainer").offsetTop)) {
previewTools.style.top = '0'
}
}
lastScrollTop = scrollTop
$('#editor').css('top', Math.max(-window.pageYOffset + $("#tab-container").offset().top + $('#tab-container').outerHeight(true), 0) + 'px')
$('#editor').css('bottom', Math.max($(window).height() - ($("#footer .line-separator").offset().top - $(document).scrollTop()), 0) + 'px')
};
let imagePreview = document.querySelector("#preview")
imagePreview.addEventListener('drop', function(ev) {
const data = ev.dataTransfer?.getData("text/plain");
@ -292,9 +269,9 @@ function showImages(reqBody, res, outputContainer, livePreview) {
imageElem.setAttribute('data-steps', imageInferenceSteps)
imageElem.setAttribute('data-guidance', imageGuidanceScale)
const imageInfo = imageItemElem.querySelector('.imgItemInfo')
imageInfo.style.visibility = (livePreview ? 'hidden' : 'visible')
updatePreviewSize()
if ('seed' in result && !imageElem.hasAttribute('data-seed')) {
const req = Object.assign({}, reqBody, {
@ -436,7 +413,11 @@ function getUncompletedTaskEntries() {
document.querySelectorAll('#preview .imageTaskContainer .taskStatusLabel')
).filter((taskLabel) => taskLabel.style.display !== 'none'
).map(function(taskLabel) {
return taskLabel.closest('.imageTaskContainer')
let imageTaskContainer = taskLabel.parentNode
while(!imageTaskContainer.classList.contains('imageTaskContainer') && imageTaskContainer.parentNode) {
imageTaskContainer = imageTaskContainer.parentNode
}
return imageTaskContainer
})
if (!processOrder.checked) {
taskEntries.reverse()
@ -845,10 +826,12 @@ function createTask(task) {
task['stopTask'] = taskEntry.querySelector('.stopTask')
task['stopTask'].addEventListener('click', (e) => {
e.stopPropagation()
let question = (task['isProcessing'] ? "Stop this task?" : "Remove this task?")
shiftOrConfirm(e, question, async function(e) {
if (task.batchesDone <= 0 || !task.isProcessing) {
removeTask(taskEntry)
taskEntry.remove()
}
abortTask(task)
})
@ -1079,7 +1062,6 @@ function removeTask(taskToRemove) {
previewTools.style.display = 'none'
initialText.style.display = 'block'
}
updatePreviewSize()
}
clearAllPreviewsBtn.addEventListener('click', (e) => { shiftOrConfirm(e, "Clear all the results and tasks in this window?", async function() {
@ -1201,6 +1183,12 @@ hypernetworkStrengthSlider.addEventListener('input', updateHypernetworkStrength)
hypernetworkStrengthField.addEventListener('input', updateHypernetworkStrengthSlider)
updateHypernetworkStrength()
function updateHypernetworkStrengthContainer() {
document.querySelector("#hypernetwork_strength_container").style.display = (hypernetworkModelField.value === "" ? 'none' : '')
}
hypernetworkModelField.addEventListener('change', updateHypernetworkStrengthContainer)
updateHypernetworkStrengthContainer()
/********************* JPEG Quality **********************/
function updateOutputQuality() {
outputQualityField.value = 0 | outputQualitySlider.value
@ -1275,6 +1263,10 @@ async function getModels() {
vaeOptions.forEach(createModelOptions(vaeModelField, selectedVaeModel))
hypernetworkOptions.forEach(createModelOptions(hypernetworkModelField, selectedHypernetworkModel))
stableDiffusionModelField.dispatchEvent(new Event('change'))
vaeModelField.dispatchEvent(new Event('change'))
hypernetworkModelField.dispatchEvent(new Event('change'))
// TODO: set default for model here too
SETTINGS[sd_model_setting_key].default = stableDiffusionOptions[0]
if (getSetting(sd_model_setting_key) == '' || SETTINGS[sd_model_setting_key].value == '') {