From 4e3f247ec2e6e4f3010a7b8015398bf6deb7989a Mon Sep 17 00:00:00 2001 From: Abdullah Alfaraj Date: Sat, 23 Sep 2023 09:14:57 +0300 Subject: [PATCH] convert lasso selection into square selection with offset --- index.js | 15 ++++----- selection.js | 59 +++++++++++++++++++++++++++-------- typescripts/sd_tab/sd_tab.tsx | 59 +++++++++++++++++++++++++++++------ typescripts/sd_tab/util.ts | 6 ++++ typescripts/session/modes.ts | 4 ++- 5 files changed, 112 insertions(+), 31 deletions(-) diff --git a/index.js b/index.js index 555be63..4bb11f1 100644 --- a/index.js +++ b/index.js @@ -193,21 +193,24 @@ async function hasSessionSelectionChanged() { } } -async function calcWidthHeightFromSelection() { +async function calcWidthHeightFromSelection(selectionInfo) { //set the width and height, hrWidth, and hrHeight using selection info and selection mode const selection_mode = sd_tab_store.data.selection_mode if (selection_mode === 'ratio') { //change (width and height) and (hrWidth, hrHeight) to match the ratio of selection const base_size = sd_tab_util.helper_store.data.base_size const [width, height, hr_width, hr_height] = - await selection.selectionToFinalWidthHeight(base_size, base_size) + await selection.selectionToFinalWidthHeight( + selectionInfo, + base_size, + base_size + ) // console.log('width,height: ', width, height) html_manip.autoFillInWidth(width) html_manip.autoFillInHeight(height) html_manip.autoFillInHRWidth(hr_width) html_manip.autoFillInHRHeight(hr_height) } else if (selection_mode === 'precise') { - const selectionInfo = await psapi.getSelectionInfoExe() const [width, height, hr_width, hr_height] = [ selectionInfo.width, selectionInfo.height, @@ -230,9 +233,7 @@ const eventHandler = async (event, descriptor) => { // const isSelectionActive = await psapi.checkIfSelectionAreaIsActive() if (new_selection_info) { - const current_selection = new_selection_info // Note: don't use checkIfSelectionAreaIsActive to return the selection object, change this. - - await calcWidthHeightFromSelection() + await calcWidthHeightFromSelection(new_selection_info) } } catch (e) { console.warn(e) @@ -668,7 +669,7 @@ document.addEventListener('mouseenter', async (event) => { ) { // if there is an active selection and if the selection has changed - await calcWidthHeightFromSelection() + await calcWidthHeightFromSelection(new_selection) } else { // sessionStartHtml(true)//generate more, green color //if you didn't move the selection. diff --git a/selection.js b/selection.js index 11643b7..412b606 100644 --- a/selection.js +++ b/selection.js @@ -31,10 +31,14 @@ function finalWidthHeight( return [finalWidth, finalHeight] } -async function selectionToFinalWidthHeight(minWidth = 512, minHeight = 512) { +async function selectionToFinalWidthHeight( + selectionInfo, + minWidth = 512, + minHeight = 512 +) { // const { getSelectionInfoExe } = require('./psapi') try { - const selectionInfo = await psapi.getSelectionInfoExe() + // const selectionInfo = await psapi.getSelectionInfoExe() const [finalWidth, finalHeight] = finalWidthHeight( selectionInfo.width, selectionInfo.height, @@ -319,15 +323,47 @@ async function channelToSelectionExe(channel_name = 'mask') { console.warn(e) } } -async function inpaintLassoInitImageAndMask(channel_name = 'mask') { + +function makeSquare(selectionInfo, offset) { + // Calculate the current width and height + let width = selectionInfo.right - selectionInfo.left + let height = selectionInfo.bottom - selectionInfo.top + + // Determine the maximum dimension + let maxDim = Math.max(width, height) + + // Calculate the difference for width and height + let diffWidth = maxDim - width + let diffHeight = maxDim - height + + // Add half the difference to 'right' and 'bottom', subtract the rest from 'left' and 'top' + selectionInfo.right += Math.floor(diffWidth / 2) + offset + selectionInfo.left -= diffWidth - Math.floor(diffWidth / 2) + offset + selectionInfo.bottom += Math.floor(diffHeight / 2) + offset + selectionInfo.top -= diffHeight - Math.floor(diffHeight / 2) + offset + + // Update width and height + selectionInfo.width = maxDim + 2 * offset + selectionInfo.height = maxDim + 2 * offset + + return selectionInfo +} + +async function inpaintLassoInitImageAndMask(channel_name = 'mask', offset = 0) { + const selectionInfo = await psapi.getSelectionInfoExe() + //convert the selection box into square box so that you have best output results + const squareSelection = makeSquare(selectionInfo, offset) + //correct width and height sliders, since this is lasso mode. + await calcWidthHeightFromSelection(squareSelection) + async function getImageFromCanvas() { const width = html_manip.getWidth() const height = html_manip.getHeight() - const selectionInfo = await psapi.getSelectionInfoExe() + const base64 = await io.IO.getSelectionFromCanvasAsBase64Interface_New( width, height, - selectionInfo, + squareSelection, true ) return base64 @@ -348,7 +384,7 @@ async function inpaintLassoInitImageAndMask(channel_name = 'mask') { // ) // const selection_info = await psapi.getSelectionInfoExe() // }) - await selectionToChannel('mask') //lasso selection to channel called 'mask' + await selectionToChannel(channel_name) //lasso selection to channel called 'mask' const init_base64 = await getImageFromCanvas() @@ -360,7 +396,7 @@ async function inpaintLassoInitImageAndMask(channel_name = 'mask') { synchronousExecution: true, }) // const selection_info = await psapi.getSelectionInfoExe() - mask_base64 = await fillSelectionWhiteOutsideBlack() + mask_base64 = await fillSelectionWhiteOutsideBlack(squareSelection) }) //save laso selection to channel @@ -385,7 +421,7 @@ async function inpaintLassoInitImageAndMask(channel_name = 'mask') { //mask } -async function fillSelectionWhiteOutsideBlack() { +async function fillSelectionWhiteOutsideBlack(selectionInfo) { // Create a new layer const layer_name = 'mask' const getSelectionDesc = () => ({ @@ -495,10 +531,7 @@ async function fillSelectionWhiteOutsideBlack() { { modalBehavior: 'execute' } ) - //get the rectangular bounding box selection - - const rect_selection_info = await psapi.getSelectionInfoExe() - await psapi.reSelectMarqueeExe(rect_selection_info) + await psapi.reSelectMarqueeExe(selectionInfo) const width = html_manip.getWidth() const height = html_manip.getHeight() @@ -506,7 +539,7 @@ async function fillSelectionWhiteOutsideBlack() { const base64 = await io.IO.getSelectionFromCanvasAsBase64Interface_New( width, height, - rect_selection_info, + selectionInfo, true, layer_name + '.png' ) diff --git a/typescripts/sd_tab/sd_tab.tsx b/typescripts/sd_tab/sd_tab.tsx index 49355ce..bb2bccb 100644 --- a/typescripts/sd_tab/sd_tab.tsx +++ b/typescripts/sd_tab/sd_tab.tsx @@ -86,14 +86,43 @@ const Modes = observer(() => { ].includes(store.data.mode) ) { return ( - - Lasso Mode - + <> +
+ + Lasso Mode + + + { + helper_store.data.lasso_offset = Number( + evt.target.value + ) + }} + style={{ + display: store.data.is_lasso_mode + ? void 0 + : 'none', + }} + > + + Lasso Offset: + + + {helper_store.data.lasso_offset} + + +
+ // // lasso mode @@ -574,8 +603,13 @@ class SDTab extends React.Component<{}> { store.data.selection_mode = selection_mode.value try { + const selectionInfo = + //@ts-ignore + await psapi.getSelectionInfoExe() //@ts-ignore - await calcWidthHeightFromSelection() + await calcWidthHeightFromSelection( + selectionInfo + ) } catch (e) { console.warn(e) } @@ -663,8 +697,13 @@ class SDTab extends React.Component<{}> { base_size try { + const selectionInfo = + //@ts-ignore + await psapi.getSelectionInfoExe() //@ts-ignore - await calcWidthHeightFromSelection() + await calcWidthHeightFromSelection( + selectionInfo + ) } catch (e) { console.warn(e) } diff --git a/typescripts/sd_tab/util.ts b/typescripts/sd_tab/util.ts index 954a1c5..39a7bca 100644 --- a/typescripts/sd_tab/util.ts +++ b/typescripts/sd_tab/util.ts @@ -182,6 +182,7 @@ export const helper_store = new AStore({ previous_height: 512, native_presets: {}, base_size: 512 as number, + lasso_offset: 10 as number, }) export async function refreshModels() { let b_result = false @@ -683,3 +684,8 @@ export function loadPresetSettings(preset: any) { // io_ts.presetToStore(preset?.controlnet_tab_preset, store) } } + +export default { + store: store, + helper_store: helper_store, +} diff --git a/typescripts/session/modes.ts b/typescripts/session/modes.ts index 587c766..06075ab 100644 --- a/typescripts/session/modes.ts +++ b/typescripts/session/modes.ts @@ -3,6 +3,7 @@ import * as scripts from '../ultimate_sd_upscaler/scripts' import * as control_net from '../controlnet/entry' import { store as session_store } from '../session/session_store' +import sd_tab_util from '../sd_tab/util' import { html_manip, @@ -492,7 +493,8 @@ export class LassoInpaintMode extends Img2ImgMode { console.warn(e) } const [init_image, mask] = await selection.inpaintLassoInitImageAndMask( - 'mask' + 'mask', + sd_tab_util.helper_store.data.lasso_offset ) const selectionInfo = await psapi.getSelectionInfoExe()