adds controls for background removal parameters

also exposes a bug with how layer deletion works, will file bug report
This commit is contained in:
tim h 2023-02-18 12:00:10 -06:00
parent b17c8baa0e
commit 34bdfbf1b7
3 changed files with 97 additions and 12 deletions

View file

@ -428,7 +428,7 @@
<script src="js/defaults.js?v=5b06818" type="text/javascript"></script> <script src="js/defaults.js?v=5b06818" type="text/javascript"></script>
<!-- Base Libs --> <!-- Base Libs -->
<script src="js/lib/util.js?v=24130a5" type="text/javascript"></script> <script src="js/lib/util.js?v=379aef7" type="text/javascript"></script>
<script <script
src="js/lib/notifications.js?v=80eb976" src="js/lib/notifications.js?v=80eb976"
type="text/javascript"></script> type="text/javascript"></script>
@ -465,7 +465,7 @@
src="js/ui/tool/generic.js?v=3e678e0" src="js/ui/tool/generic.js?v=3e678e0"
type="text/javascript"></script> type="text/javascript"></script>
<script src="js/ui/tool/dream.js?v=b52bb0e" type="text/javascript"></script> <script src="js/ui/tool/dream.js?v=022cb3a" type="text/javascript"></script>
<script <script
src="js/ui/tool/maskbrush.js?v=d88810f" src="js/ui/tool/maskbrush.js?v=d88810f"
type="text/javascript"></script> type="text/javascript"></script>

View file

@ -483,7 +483,7 @@ const makeElement = (
* @param {number}} blur * @param {number}} blur
* @returns {HTMLCanvasElement} * @returns {HTMLCanvasElement}
*/ */
const subtractBackground = (canvas, bb, bgImg, blur = 0) => { const subtractBackground = (canvas, bb, bgImg, blur = 0, threshold = 10) => {
// set up temp canvases // set up temp canvases
const bgCanvas = document.createElement("canvas"); const bgCanvas = document.createElement("canvas");
const fgCanvas = document.createElement("canvas"); const fgCanvas = document.createElement("canvas");
@ -503,19 +503,22 @@ const subtractBackground = (canvas, bb, bgImg, blur = 0) => {
// draw new image // draw new image
fgCtx.drawImage(canvas, 0, 0); fgCtx.drawImage(canvas, 0, 0);
const fgImgData = fgCtx.getImageData(0, 0, bb.w, bb.h); const fgImgData = fgCtx.getImageData(0, 0, bb.w, bb.h);
// const blendImgData = blendCtx.getImageData(0, 0, bb.w, bb.h);
for (var i = 0; i < bgImgData.data.length; i += 4) { for (var i = 0; i < bgImgData.data.length; i += 4) {
// one of these days i'm gonna learn how to use map reduce or whatever and stop iterating in for loops :(
// a la https://adamwathan.me/refactoring-to-collections/
// background rgb
var bgr = bgImgData.data[i]; var bgr = bgImgData.data[i];
var bgg = bgImgData.data[i + 1]; var bgg = bgImgData.data[i + 1];
var bgb = bgImgData.data[i + 2]; var bgb = bgImgData.data[i + 2];
// foreground rgb
var fgr = fgImgData.data[i]; var fgr = fgImgData.data[i];
var fgb = fgImgData.data[i + 1]; var fgb = fgImgData.data[i + 1];
var fgd = fgImgData.data[i + 2]; var fgd = fgImgData.data[i + 2];
// delta rgb
const dr = Math.abs(bgr - fgr) > 10 ? fgr : 0; const dr = Math.abs(bgr - fgr) > threshold ? fgr : 0;
const dg = Math.abs(bgg - fgb) > 10 ? fgb : 0; const dg = Math.abs(bgg - fgb) > threshold ? fgb : 0;
const db = Math.abs(bgb - fgd) > 10 ? fgd : 0; const db = Math.abs(bgb - fgd) > threshold ? fgd : 0;
const pxChanged = dr > 0 && dg > 0 && db > 0; const pxChanged = dr > 0 && dg > 0 && db > 0;

View file

@ -538,7 +538,13 @@ const _generate = async (endpoint, request, bb, options = {}) => {
endpoint == "img2img" && endpoint == "img2img" &&
toolbar._current_tool.state.removeBackground toolbar._current_tool.state.removeBackground
) { ) {
canvas = subtractBackground(canvas, bb, dreamData.bgImg, 0); canvas = subtractBackground(
canvas,
bb,
dreamData.bgImg,
toolbar._current_tool.state.carve_blur,
toolbar._current_tool.state.carve_threshold
);
} }
commands.runCommand("drawImage", "Image Dream", { commands.runCommand("drawImage", "Image Dream", {
@ -1760,7 +1766,16 @@ const dreamTool = () =>
state, state,
"removeBackground", "removeBackground",
"Remove Identical/BG Pixels", "Remove Identical/BG Pixels",
"icon-slice" "icon-slice",
() => {
if (state.removeBackground) {
state.ctxmenu.carveBlurLabel.classList.remove("invisible");
state.ctxmenu.carveThresholdLabel.classList.remove("invisible");
} else {
state.ctxmenu.carveBlurLabel.classList.add("invisible");
state.ctxmenu.carveThresholdLabel.classList.add("invisible");
}
}
).checkbox; ).checkbox;
// Overmasking Slider // Overmasking Slider
@ -1788,6 +1803,32 @@ const dreamTool = () =>
textStep: 1, textStep: 1,
} }
).slider; ).slider;
// bg carve blur
state.ctxmenu.carveBlurLabel = _toolbar_input.slider(
state,
"carve_blur",
"BG Remove Blur",
{
min: 0,
max: 30,
step: 2,
textStep: 1,
}
).slider;
state.ctxmenu.carveBlurLabel.classList.add("invisible");
// bg carve threshold
state.ctxmenu.carveThresholdLabel = _toolbar_input.slider(
state,
"carve_threshold",
"BG Remove Threshold",
{
min: 0,
max: 255,
step: 5,
textStep: 1,
}
).slider;
state.ctxmenu.carveThresholdLabel.classList.add("invisible");
} }
menu.appendChild(state.ctxmenu.cursorSizeSlider); menu.appendChild(state.ctxmenu.cursorSizeSlider);
@ -1805,6 +1846,8 @@ const dreamTool = () =>
// menu.appendChild(state.ctxmenu.keepUnmaskedBlurSliderLinebreak); // menu.appendChild(state.ctxmenu.keepUnmaskedBlurSliderLinebreak);
// menu.appendChild(state.ctxmenu.preserveMasksLabel); // menu.appendChild(state.ctxmenu.preserveMasksLabel);
// menu.appendChild(document.createElement("br")); // menu.appendChild(document.createElement("br"));
menu.appendChild(state.ctxmenu.carveBlurLabel);
menu.appendChild(state.ctxmenu.carveThresholdLabel);
menu.appendChild(state.ctxmenu.outpaintTypeSelect); menu.appendChild(state.ctxmenu.outpaintTypeSelect);
menu.appendChild(state.ctxmenu.overMaskPxLabel); menu.appendChild(state.ctxmenu.overMaskPxLabel);
menu.appendChild(state.ctxmenu.eagerGenerateCountLabel); menu.appendChild(state.ctxmenu.eagerGenerateCountLabel);
@ -2326,7 +2369,16 @@ const img2imgTool = () =>
state, state,
"removeBackground", "removeBackground",
"Remove Identical/BG Pixels", "Remove Identical/BG Pixels",
"icon-slice" "icon-slice",
() => {
if (state.removeBackground) {
state.ctxmenu.carveBlurLabel.classList.remove("invisible");
state.ctxmenu.carveThresholdLabel.classList.remove("invisible");
} else {
state.ctxmenu.carveBlurLabel.classList.add("invisible");
state.ctxmenu.carveThresholdLabel.classList.add("invisible");
}
}
).checkbox; ).checkbox;
// Border Mask Size Slider // Border Mask Size Slider
@ -2387,6 +2439,34 @@ const img2imgTool = () =>
state.ctxmenu.instructPix2PixImgCfgLabel.classList.add( state.ctxmenu.instructPix2PixImgCfgLabel.classList.add(
"instruct-pix2pix-img-cfg" "instruct-pix2pix-img-cfg"
); );
// bg carve blur
state.ctxmenu.carveBlurLabel = _toolbar_input.slider(
state,
"carve_blur",
"BG Remove Blur",
{
min: 0,
max: 30,
step: 2,
textStep: 1,
}
).slider;
state.ctxmenu.carveBlurLabel.classList.add("invisible");
// bg carve threshold
state.ctxmenu.carveThresholdLabel = _toolbar_input.slider(
state,
"carve_threshold",
"BG Remove Threshold",
{
min: 0,
max: 255,
step: 5,
textStep: 1,
}
).slider;
state.ctxmenu.carveThresholdLabel.classList.add("invisible");
} }
menu.appendChild(state.ctxmenu.cursorSizeSlider); menu.appendChild(state.ctxmenu.cursorSizeSlider);
@ -2400,6 +2480,8 @@ const img2imgTool = () =>
menu.appendChild(array); menu.appendChild(array);
menu.appendChild(state.ctxmenu.keepUnmaskedBlurSlider); menu.appendChild(state.ctxmenu.keepUnmaskedBlurSlider);
// menu.appendChild(state.ctxmenu.keepUnmaskedBlurSliderLinebreak); // menu.appendChild(state.ctxmenu.keepUnmaskedBlurSliderLinebreak);
menu.appendChild(state.ctxmenu.carveBlurLabel);
menu.appendChild(state.ctxmenu.carveThresholdLabel);
menu.appendChild(state.ctxmenu.inpaintTypeSelect); menu.appendChild(state.ctxmenu.inpaintTypeSelect);
menu.appendChild(state.ctxmenu.denoisingStrengthSlider); menu.appendChild(state.ctxmenu.denoisingStrengthSlider);
menu.appendChild(state.ctxmenu.instructPix2PixImgCfgLabel); menu.appendChild(state.ctxmenu.instructPix2PixImgCfgLabel);