removed redundant overmask toggle
overmaskpx = 0 effectively disables it anyway sets overmaskpx to a localstorage option removes moot "plain" mask monitor
This commit is contained in:
parent
c4b1627386
commit
aefd45f436
3 changed files with 19 additions and 46 deletions
|
@ -17,7 +17,7 @@ this is a completely vanilla javascript and html canvas outpainting convenience
|
||||||
- easily change samplers/steps/CFG/etc options for each dream summoned from the latent void
|
- easily change samplers/steps/CFG/etc options for each dream summoned from the latent void
|
||||||
- optional right-click to erase output image under cursor
|
- optional right-click to erase output image under cursor
|
||||||
- optional grid snapping for precision
|
- optional grid snapping for precision
|
||||||
- optional overmasking for potentially better seams between outpaints and it _sorta_ works currently but it needs fixing
|
- optional overmasking for potentially better seams between outpaints and it _sorta_ works currently but it needs fixing - set overmask px value to 0 to disable the feature
|
||||||
- optional hi-res fix for blank/txt2img dreams which, if enabled, uses image width/height / 2 as firstpass size
|
- optional hi-res fix for blank/txt2img dreams which, if enabled, uses image width/height / 2 as firstpass size
|
||||||
- import arbitrary images and superimpose on the canvas wherever you'd like ([extra fun with transparent .pngs!](#arbitrary_transparent))
|
- import arbitrary images and superimpose on the canvas wherever you'd like ([extra fun with transparent .pngs!](#arbitrary_transparent))
|
||||||
- "temporary" monitors at the bottom to see exactly what mask/image you're feeding img2img, no i'm certainly not using them as actual imagedata sources or anything
|
- "temporary" monitors at the bottom to see exactly what mask/image you're feeding img2img, no i'm certainly not using them as actual imagedata sources or anything
|
||||||
|
|
10
index.html
10
index.html
|
@ -73,9 +73,7 @@
|
||||||
<input type="checkbox" id="cbxErase" onchange="changeEraseMode()" disabled="disabled"><br />
|
<input type="checkbox" id="cbxErase" onchange="changeEraseMode()" disabled="disabled"><br />
|
||||||
<label for="cbxHRFix">Auto txt2img HRfix?</label>
|
<label for="cbxHRFix">Auto txt2img HRfix?</label>
|
||||||
<input type="checkbox" id="cbxHRFix" onchange="changeHiResFix()"><br />
|
<input type="checkbox" id="cbxHRFix" onchange="changeHiResFix()"><br />
|
||||||
<label for="cbxOverMask">Overmasking?</label>
|
<label for="overMaskPx">Overmask px (0 to disable):</label>
|
||||||
<input type="checkbox" id="cbxOverMask" onchange="changeOverMask()" checked="checked"><br />
|
|
||||||
<label for="overMaskPx">Overmask px:</label>
|
|
||||||
<input type="number" id="overMaskPx" onchange="changeOverMaskPx()" min="0" max="128" value="16"
|
<input type="number" id="overMaskPx" onchange="changeOverMaskPx()" min="0" max="128" value="16"
|
||||||
step="1" /><br />
|
step="1" /><br />
|
||||||
<label for="maskBlur">Mask blur:</label>
|
<label for="maskBlur">Mask blur:</label>
|
||||||
|
@ -158,9 +156,9 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="masks" class="masks">
|
<div id="masks" class="masks">
|
||||||
<div>
|
<div>
|
||||||
<canvas id="maskCanvasMonitor" class="maskCanvasMonitor" width="512" height="512">
|
<!-- <canvas id="maskCanvasMonitor" class="maskCanvasMonitor" width="512" height="512">
|
||||||
<p>lol ur browser sucks</p>
|
<p>lol ur browser sucks</p>
|
||||||
</canvas><br />
|
</canvas><br /> -->
|
||||||
<canvas id="overMaskCanvasMonitor" class="overMaskCanvasMonitor" width="512" height="512">
|
<canvas id="overMaskCanvasMonitor" class="overMaskCanvasMonitor" width="512" height="512">
|
||||||
<p>lol ur browser sucks</p>
|
<p>lol ur browser sucks</p>
|
||||||
</canvas><br />
|
</canvas><br />
|
||||||
|
|
53
js/index.js
53
js/index.js
|
@ -107,9 +107,7 @@ var backupMaskChunk = null;
|
||||||
var backupMaskX = null;
|
var backupMaskX = null;
|
||||||
var backupMaskY = null;
|
var backupMaskY = null;
|
||||||
var totalImagesReturned;
|
var totalImagesReturned;
|
||||||
// var maskEdgePixels = {};
|
var overMaskPx = 16;
|
||||||
var overMask = true;
|
|
||||||
var overMaskPx = 10;
|
|
||||||
var drawTargets = []; // is this needed? i only draw the last one anyway...
|
var drawTargets = []; // is this needed? i only draw the last one anyway...
|
||||||
var dropTargets = []; // uhhh yeah similar to the above but for arbitrary dropped images
|
var dropTargets = []; // uhhh yeah similar to the above but for arbitrary dropped images
|
||||||
var arbitraryImage;
|
var arbitraryImage;
|
||||||
|
@ -156,7 +154,6 @@ function startup() {
|
||||||
changeSnapMode();
|
changeSnapMode();
|
||||||
changeMaskBlur();
|
changeMaskBlur();
|
||||||
changeSeed();
|
changeSeed();
|
||||||
changeOverMask();
|
|
||||||
changeOverMaskPx();
|
changeOverMaskPx();
|
||||||
changeHiResFix();
|
changeHiResFix();
|
||||||
changeEnableErasing();
|
changeEnableErasing();
|
||||||
|
@ -530,21 +527,18 @@ function mouseUp(evt) {
|
||||||
//check if there's image data already there
|
//check if there's image data already there
|
||||||
// console.log(downX + ":" + downY + " :: " + this.isCanvasBlank(downX, downY));
|
// console.log(downX + ":" + downY + " :: " + this.isCanvasBlank(downX, downY));
|
||||||
if (!isCanvasBlank(drawIt.x, drawIt.y, drawIt.w, drawIt.h, imgCanvas)) {
|
if (!isCanvasBlank(drawIt.x, drawIt.y, drawIt.w, drawIt.h, imgCanvas)) {
|
||||||
// img2img
|
// image exists, set up for img2img
|
||||||
var mainCanvasCtx = document.getElementById("canvas").getContext("2d");
|
var mainCanvasCtx = document.getElementById("canvas").getContext("2d");
|
||||||
const imgChunk = mainCanvasCtx.getImageData(drawIt.x, drawIt.y, drawIt.w, drawIt.h); // imagedata object of the image being outpainted
|
const imgChunk = mainCanvasCtx.getImageData(drawIt.x, drawIt.y, drawIt.w, drawIt.h); // imagedata object of the image being outpainted
|
||||||
const imgChunkData = imgChunk.data; // imagedata.data object, a big inconvenient uint8clampedarray
|
const imgChunkData = imgChunk.data; // imagedata.data object, a big inconvenient uint8clampedarray
|
||||||
// these are the 3 mask monitors on the bottom of the page
|
// these are the 3 mask monitors on the bottom of the page
|
||||||
var maskCanvas = document.getElementById("maskCanvasMonitor");
|
|
||||||
var initImgCanvas = document.getElementById("initImgCanvasMonitor");
|
var initImgCanvas = document.getElementById("initImgCanvasMonitor");
|
||||||
var overMaskCanvas = document.getElementById("overMaskCanvasMonitor");
|
var overMaskCanvas = document.getElementById("overMaskCanvasMonitor");
|
||||||
overMaskCanvas.width = initImgCanvas.width = maskCanvas.width = target.w;
|
overMaskCanvas.width = initImgCanvas.width = target.w; //maskCanvas.width = target.w;
|
||||||
overMaskCanvas.height = initImgCanvas.height = maskCanvas.height = target.h;
|
overMaskCanvas.height = initImgCanvas.height = target.h; //maskCanvas.height = target.h;
|
||||||
var maskCanvasCtx = maskCanvas.getContext("2d");
|
|
||||||
var initImgCanvasCtx = initImgCanvas.getContext("2d");
|
var initImgCanvasCtx = initImgCanvas.getContext("2d");
|
||||||
var overMaskCanvasCtx = overMaskCanvas.getContext("2d");
|
var overMaskCanvasCtx = overMaskCanvas.getContext("2d");
|
||||||
// get blank pixels to use as mask
|
// get blank pixels to use as mask
|
||||||
const maskImgData = maskCanvasCtx.createImageData(drawIt.w, drawIt.h);
|
|
||||||
const initImgData = mainCanvasCtx.createImageData(drawIt.w, drawIt.h);
|
const initImgData = mainCanvasCtx.createImageData(drawIt.w, drawIt.h);
|
||||||
const overMaskImgData = overMaskCanvasCtx.createImageData(drawIt.w, drawIt.h);
|
const overMaskImgData = overMaskCanvasCtx.createImageData(drawIt.w, drawIt.h);
|
||||||
// cover entire masks in black before adding masked areas
|
// cover entire masks in black before adding masked areas
|
||||||
|
@ -553,12 +547,7 @@ function mouseUp(evt) {
|
||||||
// l->r, top->bottom, R G B A pixel values in a big ol array
|
// l->r, top->bottom, R G B A pixel values in a big ol array
|
||||||
// make a simple mask
|
// make a simple mask
|
||||||
if (imgChunkData[i + 3] == 0) { // rgba pixel values, 4th one is alpha, if it's 0 there's "nothing there" in the image display canvas and its time to outpaint
|
if (imgChunkData[i + 3] == 0) { // rgba pixel values, 4th one is alpha, if it's 0 there's "nothing there" in the image display canvas and its time to outpaint
|
||||||
maskImgData.data[i] = 255; // white mask gets painted over
|
overMaskImgData.data[i] = 255; // white mask gets painted over
|
||||||
maskImgData.data[i + 1] = 255;
|
|
||||||
maskImgData.data[i + 2] = 255;
|
|
||||||
maskImgData.data[i + 3] = 255;
|
|
||||||
|
|
||||||
overMaskImgData.data[i] = 255; //lets just set this up now
|
|
||||||
overMaskImgData.data[i + 1] = 255;
|
overMaskImgData.data[i + 1] = 255;
|
||||||
overMaskImgData.data[i + 2] = 255;
|
overMaskImgData.data[i + 2] = 255;
|
||||||
overMaskImgData.data[i + 3] = 255;
|
overMaskImgData.data[i + 3] = 255;
|
||||||
|
@ -569,15 +558,10 @@ function mouseUp(evt) {
|
||||||
initImgData.data[i + 2] = 0;
|
initImgData.data[i + 2] = 0;
|
||||||
initImgData.data[i + 3] = 255;
|
initImgData.data[i + 3] = 255;
|
||||||
} else { // leave these pixels alone
|
} else { // leave these pixels alone
|
||||||
maskImgData.data[i] = 0; // black mask gets ignored for in/outpainting
|
overMaskImgData.data[i] = 0; // black mask gets ignored for in/outpainting
|
||||||
maskImgData.data[i + 1] = 0;
|
|
||||||
maskImgData.data[i + 2] = 0;
|
|
||||||
maskImgData.data[i + 3] = 255; // but it still needs an opaque alpha channel
|
|
||||||
|
|
||||||
overMaskImgData.data[i] = 0;
|
|
||||||
overMaskImgData.data[i + 1] = 0;
|
overMaskImgData.data[i + 1] = 0;
|
||||||
overMaskImgData.data[i + 2] = 0;
|
overMaskImgData.data[i + 2] = 0;
|
||||||
overMaskImgData.data[i + 3] = 255;
|
overMaskImgData.data[i + 3] = 255; // but it still needs an opaque alpha channel
|
||||||
|
|
||||||
initImgData.data[i] = imgChunkData[i]; // put the original picture back in the painted area
|
initImgData.data[i] = imgChunkData[i]; // put the original picture back in the painted area
|
||||||
initImgData.data[i + 1] = imgChunkData[i + 1];
|
initImgData.data[i + 1] = imgChunkData[i + 1];
|
||||||
|
@ -693,10 +677,6 @@ function mouseUp(evt) {
|
||||||
const maskChunkData = maskChunk.data;
|
const maskChunkData = maskChunk.data;
|
||||||
for (let i = 0; i < maskChunkData.length; i += 4) {
|
for (let i = 0; i < maskChunkData.length; i += 4) {
|
||||||
if (maskChunkData[i + 3] != 0) {
|
if (maskChunkData[i + 3] != 0) {
|
||||||
maskImgData.data[i] = 255;
|
|
||||||
maskImgData.data[i + 1] = 255;
|
|
||||||
maskImgData.data[i + 2] = 255;
|
|
||||||
maskImgData.data[i + 3] = 255;
|
|
||||||
overMaskImgData.data[i] = 255;
|
overMaskImgData.data[i] = 255;
|
||||||
overMaskImgData.data[i + 1] = 255;
|
overMaskImgData.data[i + 1] = 255;
|
||||||
overMaskImgData.data[i + 2] = 255;
|
overMaskImgData.data[i + 2] = 255;
|
||||||
|
@ -715,21 +695,17 @@ function mouseUp(evt) {
|
||||||
}
|
}
|
||||||
maskPaintCtx.putImageData(clearArea, drawIt.x, drawIt.y);
|
maskPaintCtx.putImageData(clearArea, drawIt.x, drawIt.y);
|
||||||
// mask monitors
|
// mask monitors
|
||||||
maskCanvasCtx.putImageData(maskImgData, 0, 0);
|
|
||||||
var maskBase64 = maskCanvas.toDataURL();
|
|
||||||
overMaskCanvasCtx.putImageData(overMaskImgData, 0, 0); // :pray:
|
overMaskCanvasCtx.putImageData(overMaskImgData, 0, 0); // :pray:
|
||||||
var overMaskBase64 = overMaskCanvas.toDataURL();
|
var overMaskBase64 = overMaskCanvas.toDataURL();
|
||||||
initImgCanvasCtx.putImageData(initImgData, 0, 0);
|
initImgCanvasCtx.putImageData(initImgData, 0, 0);
|
||||||
var initImgBase64 = initImgCanvas.toDataURL();
|
var initImgBase64 = initImgCanvas.toDataURL();
|
||||||
// img2img
|
// anyway all that to say NOW let's run img2img
|
||||||
endpoint = "img2img";
|
endpoint = "img2img";
|
||||||
var selectedMask = overMask ? overMaskBase64 : maskBase64;
|
stableDiffusionData.mask = overMaskBase64;
|
||||||
stableDiffusionData.mask = selectedMask;
|
|
||||||
// stableDiffusionData.mask = maskBase64;
|
|
||||||
stableDiffusionData.init_images = [initImgBase64];
|
stableDiffusionData.init_images = [initImgBase64];
|
||||||
// slightly more involved than txt2img
|
// slightly more involved than txt2img
|
||||||
} else {
|
} else {
|
||||||
// txt2img
|
// time to run txt2img
|
||||||
endpoint = "txt2img";
|
endpoint = "txt2img";
|
||||||
// easy enough
|
// easy enough
|
||||||
}
|
}
|
||||||
|
@ -790,12 +766,9 @@ function changeSeed() {
|
||||||
localStorage.setItem("seed", stableDiffusionData.seed);
|
localStorage.setItem("seed", stableDiffusionData.seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeOverMask() {
|
|
||||||
overMask = document.getElementById("cbxOverMask").checked;
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeOverMaskPx() {
|
function changeOverMaskPx() {
|
||||||
overMaskPx = document.getElementById("overMaskPx").value;
|
overMaskPx = document.getElementById("overMaskPx").value;
|
||||||
|
localStorage.setItem("overmask_px", overMaskPx);
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeHiResFix() {
|
function changeHiResFix() {
|
||||||
|
@ -920,12 +893,13 @@ function checkIfWebuiIsRunning() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadSettings() {
|
function loadSettings() {
|
||||||
// set default values if not set DEFAULTS
|
// set default values if not set
|
||||||
var _sampler = localStorage.getItem("sampler") == null ? "DDIM" : localStorage.getItem("sampler");
|
var _sampler = localStorage.getItem("sampler") == null ? "DDIM" : localStorage.getItem("sampler");
|
||||||
var _mask_blur = localStorage.getItem("mask_blur") == null ? 0 : localStorage.getItem("mask_blur");
|
var _mask_blur = localStorage.getItem("mask_blur") == null ? 0 : localStorage.getItem("mask_blur");
|
||||||
var _seed = localStorage.getItem("seed") == null ? -1 : localStorage.getItem("seed");
|
var _seed = localStorage.getItem("seed") == null ? -1 : localStorage.getItem("seed");
|
||||||
var _enable_hr = Boolean(localStorage.getItem("enable_hr") == (null || "false") ? false : localStorage.getItem("enable_hr"));
|
var _enable_hr = Boolean(localStorage.getItem("enable_hr") == (null || "false") ? false : localStorage.getItem("enable_hr"));
|
||||||
var _enable_erase = Boolean(localStorage.getItem("enable_erase") == (null || "false") ? false : localStorage.getItem("enable_erase"));
|
var _enable_erase = Boolean(localStorage.getItem("enable_erase") == (null || "false") ? false : localStorage.getItem("enable_erase"));
|
||||||
|
var _overmask_px = localStorage.getItem("overmask_px") == null ? 0 : localStorage.getItem("overmask_px");
|
||||||
|
|
||||||
// set the values into the UI
|
// set the values into the UI
|
||||||
document.getElementById("samplerSelect").value = String(_sampler);
|
document.getElementById("samplerSelect").value = String(_sampler);
|
||||||
|
@ -933,4 +907,5 @@ function loadSettings() {
|
||||||
document.getElementById("seed").value = Number(_seed);
|
document.getElementById("seed").value = Number(_seed);
|
||||||
document.getElementById("cbxHRFix").checked = Boolean(_enable_hr);
|
document.getElementById("cbxHRFix").checked = Boolean(_enable_hr);
|
||||||
document.getElementById("cbxEnableErasing").checked = Boolean(_enable_erase);
|
document.getElementById("cbxEnableErasing").checked = Boolean(_enable_erase);
|
||||||
|
document.getElementById("overMaskPx").value = Number(_overmask_px);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue