stable-diffusion-for-fun/templates/index.html

947 lines
48 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<html>
<head>
<meta charset="utf-8">
<title>Happy Diffusion (Private Access) | 9pm</title>
<meta name="description" content="Stable Diffusion Online">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link href="{{ url_for('static',filename='bootstrap.min.css') }}" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="card mb-3">
<div class="card-body">
<div class="row">
<div class="col-md-8 mb-3">
<div class="input-group">
<label for="apiKey" class="input-group-text" data-en_XX="API Key" data-zh_CN="API 密钥">API
Key</label>
<input type="password" class="form-control" id="apiKey" value="">
</div>
</div>
<div class="col-md-4 mb-3">
<div class="input-group">
<label class="input-group-text" for="language" data-en_XX="Language"
data-zh_CN="语言">Language</label>
<select class="form-select" id="language">
<option value="zh_CN">中文</option>
<option selected value="en_XX">English</option>
</select>
</div>
</div>
</div>
<div class="row mb-3">
<div class="input-group">
<label for="prompt" class="input-group-text" data-en_XX="This image is.."
data-zh_CN="这张图..">This image is..</label>
<input class="form-control" id="prompt" aria-describedby="promptHelp">
</div>
<div id="promptHelp" class="form-text"
data-en_XX="Describe your image. Example: photo of a cat, cute, black and white. Use () to emphasize."
data-zh_CN="形容这张图。比如:一张猫的照片,可爱,黑白色。用括号()强调重要性。">Describe your image. Example: photo of a cat,
cute, black and white. Use () to emphasize.</div>
</div>
<div class="row mb-3">
<div class="input-group">
<label for="negPrompt" class="input-group-text" data-en_XX="This image is NOT.."
data-zh_CN="这张图不是..">This image is NOT..</label>
<input type="text" class="form-control" id="negPrompt" aria-describedby="negPromptHelp">
</div>
<div id="negPromptHelp" class="form-text" data-en_XX="Optional. Describe what's NOT the image."
data-zh_CN="非必填。形容这张图不长什么样。">Optional. Describe what's NOT the image.</div>
</div>
<div class="row">
<div class="col-md-3 mb-3">
<div class="input-group input-group-sm">
<label for="inputSeed" class="input-group-text" data-en_XX="Seed"
data-zh_CN="随机数">Seed</label>
<input type="text" class="form-control" id="inputSeed" aria-describedby="inputSeedHelp">
</div>
<div id="inputSeedHelp" class="form-text"
data-en_XX="Leave it empty or set 0 to use a random seed" data-zh_CN="非必填。留白或填0使用默认随机数">
Leave it empty or set 0 to use a random seed
</div>
</div>
<div class="col-md-3 mb-3">
<div class="input-group input-group-sm">
<label for="guidanceScale" class="input-group-text" data-en_XX="Guidance"
data-zh_CN="指示强度">Guidance</label>
<input type="number" class="form-control" id="inputGuidanceScale"
aria-describedby="inputGuidanceScaleHelp" placeholder="12.5" min="1" max="30">
</div>
<div id="inputGuidanceScaleHelp" class="form-text"
data-en_XX="20 = follow prompt, 7 = creative/artistic. Lower it if you see bad images."
data-zh_CN="20 = 提示词重要7 = 更有创造性。如果结果较差,适当降低该数。">
20 = follow prompt, 7 = creative/artistic. Lower it if you see bad images.
</div>
</div>
<div class="col-md-2 mb-3">
<div class="input-group input-group-sm">
<label for="inputSteps" class="input-group-text" data-en_XX="Steps"
data-zh_CN="迭代次数">Steps</label>
<input type="number" class="form-control" id="inputSteps" aria-describedby="inputStepsHelp"
placeholder="50">
</div>
<div id="inputStepsHelp" class="form-text"
data-en_XX="More steps better image but longer time to generate"
data-zh_CN="迭代次数越多图片越好,但生成时间越久">More steps better image but longer time to generate
</div>
</div>
<div class="col-md-2 mb-3">
<div class="input-group input-group-sm">
<label for="inputWidth" class="input-group-text" data-en_XX="Width"
data-zh_CN="图片宽度">Width</label>
<input type="number" class="form-control" id="inputWidth" placeholder="512" min="1"
max="1024">
</div>
</div>
<div class="col-md-2 mb-3">
<div class="input-group input-group-sm">
<label for="inputHeight" class="input-group-text" data-en_XX="Height"
data-zh_CN="图片高度">Height</label>
<input type="number" class="form-control" id="inputHeight" placeholder="512" min="1"
max="1024">
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<ul class="nav nav-pills card-header-pills">
<li class="nav-item">
<a class="nav-link" href="#card-txt" data-en_XX="Text-to-Image"
data-zh_CN="文字->图片">Text-to-Image</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#card-img" data-en_XX="Image-to-Image"
data-zh_CN="图片->图片">Image-to-Image</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#card-inpainting" data-en_XX="Inpainting"
data-zh_CN="图片修复">Inpainting</a>
</li>
</ul>
</div>
<div class="card-body card-specific" id="card-img" style="display:none">
<div class="row">
<div class="col-md-4">
<div class="card">
<div class="card-header" data-en_XX="1. Choose Reference Image"
data-zh_CN="1. 选择参照图">
1. Choose Reference Image
</div>
<div class="card-body">
<div class="row">
<button id="copy-txt-to-img" class="btn btn-primary mb-3"
data-en_XX="Copy from text-to-image" data-zh_CN="从【文字->图片】结果复制">Copy
from text-to-image</button>
<button id="copy-last-img" class="btn btn-primary mb-3"
data-en_XX="Copy from last image result" data-zh_CN="从【图片->图片】结果复制">Copy
from last image result</button>
<button id="upload-img" class="btn btn-primary mb-3"
data-en_XX="Upload image" data-zh_CN="上传一张图片">Upload
image</button>
</div>
<div class="row mb-3">
<div class="input-group input-group-sm">
<label for="strength" class="input-group-text" data-en_XX="Strength"
data-zh_CN="改变程度">Strength</label>
<input type="number" class="form-control" id="inputStrength"
aria-describedby="inputStrengthHelp" placeholder="0.5" min="0"
max="1">
</div>
<div id="inputStrengthHelp" class="form-text"
data-en_XX="How different from the original image. 0 means the same, 1 means very different."
data-zh_CN="和参照图有多么的不同。0指一样1指非常不一样。">How different from the
original image
</div>
</div>
<div class="row">
<button id="newImg2ImgJob" class="btn btn-primary mb-3"
data-en_XX="Let's Go with Image Below!" data-zh_CN="就用下面的图生成!">Let's
Go with Image Below!</button>
</div>
</div>
<img class="card-img-bottom" id="reference-img">
</div>
</div>
<div class="col-md-8">
<div class="card">
<div class="card-header" data-en_XX="2. Result" data-zh_CN="2. 结果">
2. Result
</div>
<div class="card-body">
<ul class="list-group">
<li
class="list-group-item d-flex justify-content-between align-items-center">
<span id="img2ImgJobUUID"></span>
<span class="badge bg-primary rounded-pill" data-en_XX="Job UUID"
data-zh_CN="图片唯一识别码">Job UUID</span>
</li>
<li
class="list-group-item d-flex justify-content-between align-items-center">
<span id="img2ImgStatus"></span>
<span class="badge bg-primary rounded-pill" data-en_XX="Job Status"
data-zh_CN="生成状态">Job Status</span>
</li>
<li
class="list-group-item d-flex justify-content-between align-items-center">
<span id="img2ImgSeed"></span>
<span class="badge bg-primary rounded-pill" data-en_XX="Job Seed"
data-zh_CN="图片随机数">Job Seed</span>
</li>
</ul>
</div>
<img class="card-img-bottom" id="img2ImgImg">
</div>
</div>
</div>
</div>
<div class="card-body card-specific" id="card-inpainting" style="display:none">
<div class="row">
<div class="col-md-4">
<div class="card">
<div class="card-header" data-en_XX="1. Choose Original Image" data-zh_CN="1. 选择原图">
1. Choose Original Image
</div>
<div class="card-body">
<div class="row">
<button id="copy-txt-to-img-inpaint" class="btn btn-primary mb-3"
data-en_XX="Copy from text-to-image" data-zh_CN="从【文字->图片】结果复制">Copy
from text-to-image</button>
<button id="copy-last-img-inpaint" class="btn btn-primary mb-3"
data-en_XX="Copy from last image result" data-zh_CN="从【图片->图片】结果复制">Copy
from last image result</button>
<button id="upload-img-inpaint" class="btn btn-primary mb-3"
data-en_XX="Upload image" data-zh_CN="上传一张图片">Upload
image</button>
</div>
</div>
<img class="card-img-bottom" id="inpaint-img">
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-header" data-en_XX="2. Remove Area (Mask)"
data-zh_CN="2. 抹去要修复的部分">
2. Remove Area (Mask)
</div>
<div class="card-body">
<div class="row">
<button id="newInpaintingJob" class="btn btn-primary mb-3"
data-en_XX="Let's Go with Image + Mask Below!" data-zh_CN="进行修复!">Let's
Go with Image + Mask Below!</button>
</div>
<div class="input-group mb-3">
<button id="inpaint-reset" class="btn btn-outline-secondary"
data-en_XX="Reset" data-zh_CN="重置">Reset</button>
<button id="inpaint-undo" class="btn btn-outline-secondary"
data-en_XX="Undo" data-zh_CN="撤销">Undo</button>
<button id="inpaint-redo" class="btn btn-outline-secondary"
data-en_XX="Redo" data-zh_CN="重做">Redo</button>
</div>
<div class="form-row">
<label for="inpaint-strike-size" class="form-label" data-en_XX="Strike Size"
data-zh_CN="笔触大小">Strike Size</label>
<input type="range" class="form-range" min="1" max="30"
id="inpaint-strike-size">
<output id='range-value'></output>
</div>
</div>
<div class="card-img-bottom" style="position: relative;">
<img id="inpaint-img-for-mask" width="100%">
<div id="inpaint-mask-canvas-container"
style="cursor: pointer; position: absolute; top: 0; left: 0;">
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-header" data-en_XX="3. Result" data-zh_CN="3. 结果">
3. Result
</div>
<div class="card-body">
<ul class="list-group">
<li
class="list-group-item d-flex justify-content-between align-items-center">
<span id="inpaintJobUUID"></span>
<span class="badge bg-primary rounded-pill" data-en_XX="Job UUID"
data-zh_CN="图片唯一识别码">Job UUID</span>
</li>
<li
class="list-group-item d-flex justify-content-between align-items-center">
<span id="inpaintStatus"></span>
<span class="badge bg-primary rounded-pill" data-en_XX="Job Status"
data-zh_CN="生成状态">Job Status</span>
</li>
<li
class="list-group-item d-flex justify-content-between align-items-center">
<span id="inpaintSeed"></span>
<span class="badge bg-primary rounded-pill" data-en_XX="Job Seed"
data-zh_CN="图片随机数">Job Seed</span>
</li>
</ul>
</div>
<img class="card-img-bottom" id="inpaintImg">
</div>
</div>
</div>
</div>
<div class="card-body card-specific" id="card-txt" style="display:none">
<div class="row mb-3">
<div class="col-md-4">
<div class="card">
<div class="card-header" data-en_XX="1. Options" data-zh_CN="1. 选项">
1. Options
</div>
<div class="card-body">
<div class="row">
<button id="newTxt2ImgJob" class="btn btn-primary mb-3"
data-en_XX="Let's Go!" data-zh_CN="生成图片!">Let's Go!</button>
</div>
</div>
<img class="card-img-bottom" id="reference-img">
</div>
</div>
<div class="col-md-8">
<div class="card">
<div class="card-header" data-en_XX="2. Result" data-zh_CN="2. 结果">
2. Result
</div>
<div class="card-body">
<ul class="list-group">
<li
class="list-group-item d-flex justify-content-between align-items-center">
<span id="txt2ImgJobUUID"></span>
<span class="badge bg-primary rounded-pill" data-en_XX="Job UUID"
data-zh_CN="图片唯一识别码">Job UUID</span>
</li>
<li
class="list-group-item d-flex justify-content-between align-items-center">
<span id="txt2ImgStatus"></span>
<span class="badge bg-primary rounded-pill" data-en_XX="Job Status"
data-zh_CN="生成状态">Job Status</span>
</li>
<li
class="list-group-item d-flex justify-content-between align-items-center">
<span id="txt2ImgSeed"></span>
<span class="badge bg-primary rounded-pill" data-en_XX="Job Seed"
data-zh_CN="图片随机数">Job Seed</span>
</li>
</ul>
</div>
<img class="card-img-bottom" id="txt2ImgImg">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<form>
<div class="input-group mb-3">
<label for="jobuuid" class="input-group-text" data-en_XX="Job UUID" data-zh_CN="图片唯一识别码">Job
UUID</label>
<input type="jobuuid" class="form-control" id="jobuuid" aria-describedby="">
</div>
<button id="getjob" type="submit" class="btn btn-primary" data-en_XX="Get Jobs" data-zh_CN="搜索生成结果"
disabled>Get Jobs</button>
</form>
<table class="table" id="joblist">
</table>
</div>
<script src="{{ url_for('static',filename='jquery-3.6.1.min.js') }}"></script>
<script src="{{ url_for('static',filename='bootstrap.bundle.min.js') }}"></script>
<script src="{{ url_for('static',filename='jsketch.min.js') }}"></script>
<script src="{{ url_for('static',filename='jquery.sketchable.min.js') }}"></script>
<script src="{{ url_for('static',filename='jquery.sketchable.memento.min.js') }}"></script>
<script>
function waitForImage(apikeyVal, uuidValue) {
// Wait until image is done
$.ajax({
type: 'POST',
url: '/get_jobs',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: JSON.stringify({ 'apikey': apikeyVal, 'uuid': uuidValue }),
success: function (response) {
console.log(response);
if (response.jobs.length == 1) {
if (response.jobs[0].type == 'txt') {
$('#txt2ImgStatus').html(response.jobs[0].status);
$('#txt2ImgSeed').html(response.jobs[0].seed);
$('#txt2ImgJobUUID').html(uuidValue);
if (response.jobs[0].status == "done") {
$('#txt2ImgImg').attr('src', response.jobs[0].img);
return;
}
if (response.jobs[0].status == "failed") {
return;
}
} else if (response.jobs[0].type == 'img') {
$('#img2ImgStatus').html(response.jobs[0].status);
$('#img2ImgSeed').html(response.jobs[0].seed);
$('#img2ImgJobUUID').html(uuidValue);
if (response.jobs[0].status == "done") {
$('#img2ImgImg').attr('src', response.jobs[0].img);
return;
}
if (response.jobs[0].status == "failed") {
return;
}
} else if (response.jobs[0].type == 'inpaint') {
$('#inpaintStatus').html(response.jobs[0].status);
$('#inpaintSeed').html(response.jobs[0].seed);
$('#inpaintJobUUID').html(uuidValue);
if (response.jobs[0].status == "done") {
$('#inpaintImg').attr('src', response.jobs[0].img);
return;
}
if (response.jobs[0].status == "failed") {
return;
}
}
}
setTimeout(function () { waitForImage(apikeyVal, uuidValue); }, 1500); // refresh every second
},
error: function (xhr, status, error) {
// Handle error response
console.log(xhr.responseText);
$('#txt2ImgStatus').html('failed');
}
});
}
$(document).ready(function () {
console.log("--- csrf token set ---");
var csrftoken = $("[name=csrfmiddlewaretoken]").val();
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
$('input').each(function () {
var input = $(this);
var key = input.attr('id');
var value = localStorage.getItem(key);
if (value) {
input.val(value);
}
input.on('input', function () {
localStorage.setItem(key, input.val());
});
});
// Cache variable to store the selected image data for img2img
var imageData = null;
$("#copy-txt-to-img").click(function () {
data = $("#txt2ImgImg").attr("src");
if (data == null || data == "") {
alert("nothing found from txt-to-img result");
return;
}
imageData = data;
$("#reference-img").attr("src", imageData);
});
$("#copy-last-img").click(function () {
data = $("#img2ImgImg").attr("src");
if (data == null || data == "") {
alert("nothing found from img-to-img result");
return;
}
imageData = data;
$("#reference-img").attr("src", imageData);
});
$("#upload-img").click(function () {
var input = $("<input type='file' accept='image/*'>");
input.on("change", function () {
var reader = new FileReader();
reader.onload = function (e) {
imageData = e.target.result;
$("#reference-img").attr("src", imageData);
};
reader.readAsDataURL(input[0].files[0]);
});
input.click();
});
var activeLink = localStorage.getItem('activeLink') || $('.nav-link:first').attr('href');
// Set the active link as the current active link
$('.nav-link[href="' + activeLink + '"]').addClass('active');
$(activeLink).show();
$(".nav-link").click(function (e) {
e.preventDefault();
var target = $(this).attr("href"); // get the href value of the clicked link
// hide all card divs and show the corresponding one
$(".card-specific").hide();
$(".nav-link").removeClass("active");
$(this).addClass("active");
$(target).show();
localStorage.setItem('activeLink', target);
});
$('#newTxt2ImgJob').click(function (e) {
e.preventDefault(); // Prevent the default form submission
// Gather input field values
var apikeyVal = $('#apiKey').val();
var promptVal = $('#prompt').val();
var negPromptVal = $('#negPrompt').val();
var seedVal = $('#inputSeed').val();
if (seedVal == "0" || seedVal == "") {
seedVal = "0";
}
var guidanceScaleVal = parseFloat($('#inputGuidanceScale').val())
if (isNaN(guidanceScaleVal)) {
guidanceScaleVal = 12.5;
}
var stepsVal = parseInt($('#inputSteps').val());
if (isNaN(stepsVal)) {
stepsVal = 50;
}
var widthVal = parseInt($('#inputWidth').val());
if (isNaN(widthVal)) {
widthVal = 512;
}
var heightVal = parseInt($('#inputHeight').val());
if (isNaN(heightVal)) {
heightVal = 512;
}
if (promptVal == "") {
alert("missing prompt!");
return;
}
if (guidanceScaleVal < 1 || guidanceScaleVal > 30) {
alert("guidance scale must be between 1 and 30");
return;
}
if (widthVal < 8 || widthVal > 960) {
alert("width must be between 8 and 960!");
return;
}
if (widthVal % 8 != 0) {
alert("width must be divisible by 8!");
return;
}
if (heightVal < 8 || heightVal > 960) {
alert("height must be between 8 and 960!");
return;
}
if (heightVal % 8 != 0) {
alert("height must be divisible by 8!");
return;
}
if (stepsVal > 200 || stepsVal < 1) {
alert("steps value must be between 1 and 200!");
return;
}
$.ajax({
type: 'POST',
url: '/add_job',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: JSON.stringify({
'apikey': apikeyVal,
'type': 'txt',
'prompt': promptVal,
'seed': seedVal,
'steps': stepsVal,
'width': widthVal,
'height': heightVal,
'lang': $("#language option:selected").val(),
'guidance_scale': guidanceScaleVal,
'neg_prompt': negPromptVal
}),
success: function (response) {
console.log(response);
if (response.uuid) {
$('#txt2ImgJobUUID').html(response.uuid);
}
$('#txt2ImgStatus').html('submitting new job..');
waitForImage(apikeyVal, response.uuid);
},
error: function (xhr, status, error) {
// Handle error response
console.log(xhr.responseText);
$('#txt2ImgStatus').html('failed');
}
});
});
$('#newImg2ImgJob').click(function (e) {
e.preventDefault(); // Prevent the default form submission
if (imageData == null) {
alert("No image cached")
return;
}
// Gather input field values
var apikeyVal = $('#apiKey').val();
var promptVal = $('#prompt').val();
var negPromptVal = $('#negPrompt').val();
var seedVal = $('#inputSeed').val();
if (seedVal == "0" || seedVal == "") {
seedVal = "0";
}
var guidanceScaleVal = parseFloat($('#inputGuidanceScale').val())
if (isNaN(guidanceScaleVal)) {
guidanceScaleVal = 25.0;
}
var stepsVal = parseInt($('#inputSteps').val());
if (isNaN(stepsVal)) {
stepsVal = 50;
}
var widthVal = parseInt($('#inputWidth').val());
if (isNaN(widthVal)) {
widthVal = 512;
}
var heightVal = parseInt($('#inputHeight').val());
if (isNaN(heightVal)) {
heightVal = 512;
}
var strengthVal = parseFloat($('#inputStrength').val());
if (isNaN(strengthVal)) {
strengthVal = 0.5;
}
if (promptVal == "") {
alert("missing prompt!");
return;
}
if (guidanceScaleVal < 1 || guidanceScaleVal > 30) {
alert("guidance scale must be between 1 and 30");
return;
}
if (strengthVal < 0 || strengthVal > 1) {
alert("strength must be between 0 and 1");
return;
}
if (widthVal < 8 || widthVal > 960) {
alert("width must be between 8 and 960!");
return;
}
if (widthVal % 8 != 0) {
alert("width must be divisible by 8!");
return;
}
if (heightVal < 8 || heightVal > 960) {
alert("height must be between 8 and 960!");
return;
}
if (heightVal % 8 != 0) {
alert("height must be divisible by 8!");
return;
}
if (stepsVal > 200 || stepsVal < 1) {
alert("steps value must be between 1 and 200!");
return;
}
// Send POST request using Ajax
$.ajax({
type: 'POST',
url: '/add_job',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: JSON.stringify({
'apikey': apikeyVal,
'type': 'img',
'ref_img': imageData,
'prompt': promptVal,
'seed': seedVal,
'steps': stepsVal,
'width': widthVal,
'height': heightVal,
'lang': $("#language option:selected").val(),
'guidance_scale': guidanceScaleVal,
'strength': strengthVal,
'neg_prompt': negPromptVal
}),
success: function (response) {
console.log(response);
if (response.uuid) {
$('#img2ImgJobUUID').html(response.uuid);
}
$('#img2ImgStatus').html('submitting new job..');
waitForImage(apikeyVal, response.uuid);
},
error: function (xhr, status, error) {
// Handle error response
console.log(xhr.responseText);
$('#img2ImgStatus').html('failed');
}
});
});
$('#newInpaintingJob').click(function (e) {
e.preventDefault(); // Prevent the default form submission
if (inpaintOriginalImg == null) {
alert("No image cached")
return;
}
var canvas = $('#inpaint-img-mask')[0];
var ctx = canvas.getContext('2d');
var maskImageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
// Loop through the pixels and change the colors
for (var i = 0; i < maskImageData.data.length; i += 4) {
if (maskImageData.data[i + 3] == 0) { // If pixel is transparent, change to black
maskImageData.data[i] = 0;
maskImageData.data[i + 1] = 0;
maskImageData.data[i + 2] = 0;
maskImageData.data[i + 3] = 255;
} else { // If pixel is not transparent, change to white
maskImageData.data[i] = 255;
maskImageData.data[i + 1] = 255;
maskImageData.data[i + 2] = 255;
maskImageData.data[i + 3] = 255;
}
}
var tempCanvas = document.createElement('canvas'); // Create a new canvas element
tempCanvas.width = canvas.width; // Set the width of the new canvas to match the original canvas
tempCanvas.height = canvas.height; // Set the height of the new canvas to match the original canvas
var tempCtx = tempCanvas.getContext('2d');
tempCtx.putImageData(maskImageData, 0, 0); // Put modified image data onto the new canvas
var inpaintMaskImg = tempCanvas.toDataURL(); // Get the modified base64-encoded image data
// Gather input field values
var apikeyVal = $('#apiKey').val();
var promptVal = $('#prompt').val();
var negPromptVal = $('#negPrompt').val();
var seedVal = $('#inputSeed').val();
if (seedVal == "0" || seedVal == "") {
seedVal = "0";
}
var guidanceScaleVal = parseFloat($('#inputGuidanceScale').val())
if (isNaN(guidanceScaleVal)) {
guidanceScaleVal = 25.0;
}
var stepsVal = parseInt($('#inputSteps').val());
if (isNaN(stepsVal)) {
stepsVal = 50;
}
var widthVal = parseInt($('#inputWidth').val());
if (isNaN(widthVal)) {
widthVal = 512;
}
var heightVal = parseInt($('#inputHeight').val());
if (isNaN(heightVal)) {
heightVal = 512;
}
if (promptVal == "") {
alert("missing prompt!");
return;
}
if (guidanceScaleVal < 1 || guidanceScaleVal > 30) {
alert("guidance scale must be between 1 and 30");
return;
}
if (widthVal < 8 || widthVal > 960) {
alert("width must be between 8 and 960!");
return;
}
if (widthVal % 8 != 0) {
alert("width must be divisible by 8!");
return;
}
if (heightVal < 8 || heightVal > 960) {
alert("height must be between 8 and 960!");
return;
}
if (heightVal % 8 != 0) {
alert("height must be divisible by 8!");
return;
}
if (stepsVal > 200 || stepsVal < 1) {
alert("steps value must be between 1 and 200!");
return;
}
// Send POST request using Ajax
$.ajax({
type: 'POST',
url: '/add_job',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: JSON.stringify({
'apikey': apikeyVal,
'type': 'inpaint',
'ref_img': inpaintOriginalImg,
'mask_img': inpaintMaskImg,
'prompt': promptVal,
'seed': seedVal,
'steps': stepsVal,
'width': widthVal,
'height': heightVal,
'lang': $("#language option:selected").val(),
'guidance_scale': guidanceScaleVal,
'neg_prompt': negPromptVal
}),
success: function (response) {
console.log(response);
if (response.uuid) {
$('#inpaintJobUUID').html(response.uuid);
}
$('#inpaintStatus').html('submitting new job..');
waitForImage(apikeyVal, response.uuid);
},
error: function (xhr, status, error) {
// Handle error response
console.log(xhr.responseText);
$('#inpaintStatus').html('failed');
}
});
});
// Listen for changes to the select element
$("#language").change(function () {
// Get the newly selected value
var newLanguage = $(this).val();
// Store the selected value in cache
localStorage.setItem("selectedLanguage", newLanguage);
$("[data-" + newLanguage + "]").each(function () {
$(this).text($(this).data(newLanguage.toLowerCase()));
});
});
// Get the selected value from cache (if it exists)
var cachedLanguage = localStorage.getItem("selectedLanguage");
if (cachedLanguage) {
// Set the selected value
$("#language").val(cachedLanguage);
// Trigger a change event to update the text and store in cache
$("#language").change();
}
// Cache variable to store the selected image data for inpainting
var inpaintOriginalImg = null;
$("#copy-txt-to-img-inpaint").click(function () {
data = $("#txt2ImgImg").attr("src");
if (data == null || data == "") {
alert("nothing found from txt-to-img result");
return;
}
inpaintOriginalImg = data
$("#inpaint-img").attr("src", inpaintOriginalImg);
$("#inpaint-img").trigger("change");
});
$("#copy-last-img-inpaint").click(function () {
data = $("#img2ImgImg").attr("src");
if (data == null || data == "") {
alert("nothing found from img-to-img result");
return;
}
inpaintOriginalImg = data;
$("#inpaint-img").attr("src", inpaintOriginalImg);
$("#inpaint-img").trigger("change");
});
$("#upload-img-inpaint").click(function () {
var input = $("<input type='file' accept='image/*'>");
input.on("change", function () {
var reader = new FileReader();
reader.onload = function (e) {
inpaintOriginalImg = e.target.result;
$("#inpaint-img").attr("src", inpaintOriginalImg);
var img = new Image();
img.src = inpaintOriginalImg;
img.onload = function () {
$("#inpaint-img").trigger("change");
};
};
reader.readAsDataURL(input[0].files[0]);
});
input.click();
});
$("#inpaint-strike-size").on("input", function () {
$('#range-value').val($(this).val());
});
$('#range-value').val($('#inpaint-strike-size').val());
$("#inpaint-img").on("change", function () {
var src = $(this).attr("src");
$("#inpaint-img-for-mask").attr("src", src);
$("#inpaint-mask-canvas-container").html("<canvas id='inpaint-img-mask' width=" + $(this).width() + " height=" + $(this).height() + ">");
var options = {
graphics: {
firstPointSize: 0,
lineWidth: 10,
strokeStyle: 'black',
}
};
$sketcher = $('#inpaint-img-mask').sketchable(options);
$('#inpaint-reset').click(function () {
$sketcher.sketchable('clear');
});
$('#inpaint-undo').click(function () {
$sketcher.sketchable('memento.undo');
});
$('#inpaint-redo').click(function () {
$sketcher.sketchable('memento.redo');
});
$("#inpaint-strike-size").on("input", function () {
$sketcher.sketchable('config', { graphics: { lineWidth: $(this).val() } });
});
});
});
</script>
</body>
</html>