Delete old code
parent
fd134ef7b2
commit
04cbbdd484
109
index.html
109
index.html
|
|
@ -869,116 +869,9 @@
|
|||
</sp-radio-group>
|
||||
</div>
|
||||
<div id="viewerSubTab">
|
||||
<div class="flexContainer">
|
||||
<sp-label slot="label"
|
||||
>View your generated images on the canvas</sp-label
|
||||
>
|
||||
</div>
|
||||
<div class="flexContainer"></div>
|
||||
<div></div>
|
||||
<div>
|
||||
<button
|
||||
class="btnSquare"
|
||||
id="btnSetMaskViewer"
|
||||
style="display: none"
|
||||
>
|
||||
Set Mask
|
||||
</button>
|
||||
<button
|
||||
class="btnSquare"
|
||||
id="btnSetInitImageViewer"
|
||||
style="display: none"
|
||||
>
|
||||
Set Init Image
|
||||
</button>
|
||||
<button
|
||||
class="btnSquare btnGenerateClass"
|
||||
id="btnGenerate"
|
||||
style="display: none"
|
||||
>
|
||||
Generate txt2img
|
||||
</button>
|
||||
<button
|
||||
class="btnSquare btnInterruptClass"
|
||||
id="btnInterruptViewer"
|
||||
style="display: none"
|
||||
>
|
||||
Interrupt
|
||||
</button>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
padding-top: 3px;
|
||||
"
|
||||
>
|
||||
<button
|
||||
title="Keep all generated images on the canvas"
|
||||
class="btnSquare acceptClass acceptAllImgBtn"
|
||||
style="display: none; margin-right: 3px"
|
||||
></button>
|
||||
<button
|
||||
title="Delete all generated images from the canvas"
|
||||
class="btnSquare discardClass discardAllImgBtn"
|
||||
style="display: none; margin-right: 3px"
|
||||
></button>
|
||||
<button
|
||||
title="Keep only the highlighted images"
|
||||
class="btnSquare acceptSelectedClass acceptSelectedImgBtn"
|
||||
style="display: none; margin-right: 3px"
|
||||
></button>
|
||||
<button
|
||||
title="Delete only the highlighted images"
|
||||
class="btnSquare discardSelectedClass discardSelectedImgBtn"
|
||||
style="display: none; margin-right: 3px"
|
||||
></button>
|
||||
</div>
|
||||
|
||||
<div style="display: inline-flex">
|
||||
<div id="batchNumberViewerTabContainer">
|
||||
<!-- we will append here batch number field here -->
|
||||
<!-- <sp-label>Images:</sp-label> -->
|
||||
<!-- <sp-textfield id="tiNumberOfImages" type="number" placeholder="1"
|
||||
value="1"></sp-textfield> -->
|
||||
</div>
|
||||
<sp-progressbar
|
||||
class="pProgressBars"
|
||||
id="pViewerProgressBar"
|
||||
max="100"
|
||||
value="0"
|
||||
style="margin-left: 10px; width: 100px"
|
||||
>
|
||||
<sp-label slot="label" class="lProgressLabel"
|
||||
>Progress...</sp-label
|
||||
>
|
||||
</sp-progressbar>
|
||||
<input
|
||||
title="Toggle the visibility of the Preview Image on the canvas"
|
||||
type="checkbox"
|
||||
name="optionCheckbox"
|
||||
class="chLiveProgressImageClass"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- <button class="btnSquare" id="btnLoadViewer">Load</button> -->
|
||||
</div>
|
||||
<div style="display: flex">
|
||||
<sp-slider
|
||||
show-value="true"
|
||||
id="slThumbnailSize"
|
||||
min="1"
|
||||
max="10"
|
||||
value="5"
|
||||
style="width: 100%"
|
||||
>
|
||||
<sp-label slot="label">Thumbnail Size:</sp-label>
|
||||
</sp-slider>
|
||||
<sp-checkbox
|
||||
class="checkbox"
|
||||
id="chSquareThumbnail"
|
||||
style="margin-left: 20px"
|
||||
>Square 1:1</sp-checkbox
|
||||
>
|
||||
</div>
|
||||
<div class="" id="divProgressImageViewerContainer">
|
||||
<!-- <img
|
||||
class=""
|
||||
|
|
|
|||
515
outpaint.js
515
outpaint.js
|
|
@ -1,515 +0,0 @@
|
|||
const app = window.require('photoshop').app
|
||||
|
||||
const batchPlay = require('photoshop').action.batchPlay
|
||||
const psapi = require('./psapi')
|
||||
|
||||
async function moveLayersToGroup(group_id) {
|
||||
const activeLayers = await app.activeDocument.activeLayers
|
||||
const layerIDs = activeLayers.map((layer) => layer.id)
|
||||
const { executeAsModal } = require('photoshop').core
|
||||
await executeAsModal(async () => {
|
||||
await psapi.moveToGroupCommand(group_id, layerIDs)
|
||||
})
|
||||
}
|
||||
|
||||
async function createSnapshot() {
|
||||
const { executeAsModal } = require('photoshop').core
|
||||
//get all layers,
|
||||
//duplicate the layers
|
||||
//create a group
|
||||
//move the duplicate layers to the group
|
||||
let snapshotLayer, snapshotGroup
|
||||
try {
|
||||
const selectionInfo = await psapi.getSelectionInfoExe()
|
||||
await psapi.unSelectMarqueeExe()
|
||||
|
||||
//get all layers
|
||||
const allLayers = await app.activeDocument.layers
|
||||
|
||||
// const allLayerNames = allLayers.map(
|
||||
// layer => `${layer.name} (${layer.opacity} %)`
|
||||
// )
|
||||
// for (layer of allLayerNames){
|
||||
// console.log(layer)
|
||||
// }
|
||||
//duplicate the layers
|
||||
let duplicatedLayers = []
|
||||
|
||||
// const group_id = await createGroup()
|
||||
const groupLayer = await psapi.createEmptyGroup()
|
||||
|
||||
console.log('createSnapshot(), group_id:', groupLayer.id)
|
||||
// let bHasBackground = false
|
||||
let indexOffset = 0
|
||||
|
||||
const result1 = await executeAsModal(async () => {
|
||||
for (layer of allLayers) {
|
||||
if (layer.id == 1) {
|
||||
//skip the background layer
|
||||
// bHasBackground = true
|
||||
indexOffset = 1
|
||||
continue
|
||||
}
|
||||
if (layer.visible) {
|
||||
const copyLayer = await layer.duplicate()
|
||||
duplicatedLayers.push(copyLayer)
|
||||
}
|
||||
}
|
||||
|
||||
const layerIDs = duplicatedLayers.map((layer) => layer.id)
|
||||
console.log('createSnapshot, layerIDs:', layerIDs)
|
||||
|
||||
//select the layer since layerIDs don't seem to have an affect on moveToGroupCommand(), don't know why!!!!
|
||||
psapi.selectLayers(duplicatedLayers)
|
||||
let group_index = await psapi.getLayerIndex(groupLayer.id)
|
||||
|
||||
await psapi.moveToGroupCommand(group_index - indexOffset, layerIDs)
|
||||
|
||||
await psapi.collapseGroup(duplicatedLayers[0])
|
||||
snapshotLayer = app.activeDocument.activeLayers[0]
|
||||
await psapi.createSolidLayer(255, 255, 255)
|
||||
const whiteSolidLayer = app.activeDocument.activeLayers[0]
|
||||
await snapshotLayer.moveAbove(whiteSolidLayer)
|
||||
snapshotGroup = await psapi.createEmptyGroup()
|
||||
let snapshot_group_index = await psapi.getLayerIndex(
|
||||
snapshotGroup.id
|
||||
)
|
||||
|
||||
await psapi.selectLayers([snapshotLayer, whiteSolidLayer])
|
||||
await psapi.moveToGroupCommand(
|
||||
snapshot_group_index - indexOffset,
|
||||
[]
|
||||
)
|
||||
await psapi.selectLayers([snapshotGroup])
|
||||
await psapi.reSelectMarqueeExe(selectionInfo)
|
||||
await psapi.createMaskExe()
|
||||
// await psapi.selectLayerChannelCommand()
|
||||
// await psapi.createSolidLayer(0, 0, 0)
|
||||
})
|
||||
|
||||
return [snapshotLayer, snapshotGroup]
|
||||
} catch (e) {
|
||||
console.warn('createSnapshot Error:', e)
|
||||
}
|
||||
}
|
||||
|
||||
function executeCommand(batchPlayCommandFunc) {
|
||||
const { executeAsModal } = require('photoshop').core
|
||||
try {
|
||||
executeAsModal(async () => {
|
||||
await batchPlayCommandFunc()
|
||||
})
|
||||
} catch (e) {
|
||||
console.warn('executeCommand error:', e)
|
||||
}
|
||||
}
|
||||
|
||||
async function snapAndFillExe(session_id) {
|
||||
//create a snapshot of canvas
|
||||
//select opaque pixel and create black fill layer
|
||||
//create a snapshot of mask
|
||||
//set initial image
|
||||
//set mask image
|
||||
|
||||
try {
|
||||
let snapAndFillLayers = []
|
||||
await executeAsModal(async (context) => {
|
||||
const history_id = await context.hostControl.suspendHistory({
|
||||
documentID: app.activeDocument.id, //TODO: change this to the session document id
|
||||
name: 'Img2Img layers',
|
||||
})
|
||||
const selectionInfo = await psapi.getSelectionInfoExe()
|
||||
// await psapi.unSelectMarqueeExe()
|
||||
|
||||
//create a snapshot of canvas
|
||||
// let [snapshotLayer,snapshotGroup] = await createSnapshot()
|
||||
await psapi.snapshot_layerExe()
|
||||
const snapshotLayer = await app.activeDocument.activeLayers[0]
|
||||
const snapshotGroup = await psapi.createEmptyGroup()
|
||||
snapshotLayer.name = 'Init Image Snapshot -- temporary'
|
||||
snapshotGroup.name = 'Init Image Group -- temporary'
|
||||
|
||||
// snapshotGroup.name = `${snapshotGroup.name}_init_image`
|
||||
await psapi.createSolidLayer(255, 255, 255)
|
||||
const whiteSolidLayer = await app.activeDocument.activeLayers[0]
|
||||
whiteSolidLayer.name = 'Background Color -- temporary'
|
||||
snapshotLayer.moveAbove(whiteSolidLayer)
|
||||
console.log('[snapshotLayer,snapshotGroup]:', [
|
||||
snapshotLayer,
|
||||
snapshotGroup,
|
||||
])
|
||||
|
||||
//create a snapshot of mask
|
||||
await psapi.reSelectMarqueeExe(selectionInfo)
|
||||
// let [snapshotMaskLayer,snapshotMaskGroup] = await createSnapshot()
|
||||
|
||||
await psapi.selectLayers([snapshotGroup])
|
||||
await psapi.reSelectMarqueeExe(selectionInfo)
|
||||
await psapi.createClippingMaskExe()
|
||||
|
||||
await psapi.selectLayers([snapshotGroup])
|
||||
|
||||
snapAndFillLayers = [snapshotLayer, snapshotGroup, whiteSolidLayer]
|
||||
|
||||
// g_init_image_related_layers['init_image_group'] = snapshotGroup
|
||||
// g_init_image_related_layers['init_image_layer'] = snapshotLayer
|
||||
// g_init_image_related_layers['solid_white'] = whiteSolidLayer
|
||||
|
||||
const image_info = await psapi.silentSetInitImage(
|
||||
snapshotGroup,
|
||||
session_id
|
||||
)
|
||||
const image_name = image_info['name']
|
||||
const path = `./server/python_server/init_images/${image_name}`
|
||||
|
||||
g_viewer_manager.initializeInitImage(
|
||||
snapshotGroup,
|
||||
snapshotLayer,
|
||||
whiteSolidLayer,
|
||||
path
|
||||
) //this will be called once a session and will add the first init image to th viewer manager
|
||||
|
||||
for (layer of snapAndFillLayers) {
|
||||
layer.visible = false
|
||||
}
|
||||
await psapi.reSelectMarqueeExe(selectionInfo)
|
||||
const layer_util = require('./utility/layer')
|
||||
await layer_util.collapseFolderExe([snapshotGroup], false)
|
||||
await context.hostControl.resumeHistory(history_id)
|
||||
})
|
||||
console.log('snapAndFillLayers: ', snapAndFillLayers)
|
||||
return snapAndFillLayers
|
||||
} catch (e) {
|
||||
console.error(`snapAndFill error: ${e}`)
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
async function addClippingMaskToLayer(layer, selectionInfo) {
|
||||
await psapi.selectLayers([layer]) //select the layer
|
||||
await psapi.reSelectMarqueeExe(selectionInfo) //reselect the selection
|
||||
await psapi.createClippingMaskExe() //this will create an cliping mask and select the mask of the layer
|
||||
await psapi.selectLayers([layer]) //reselect the layer instead of the mask
|
||||
await psapi.reSelectMarqueeExe(selectionInfo) //reselect the selection
|
||||
|
||||
////test addClippingMaskToLayer
|
||||
// await executeAsModal(
|
||||
// async ()=>{
|
||||
// await outpaint.addClippingMaskToLayer(await app.activeDocument.activeLayers[0],await psapi.getSelectionInfoExe()
|
||||
// )})
|
||||
}
|
||||
|
||||
async function outpaintExe(session_id) {
|
||||
//create a snapshot of canvas
|
||||
//select opaque pixel and create black fill layer
|
||||
//create a snapshot of mask
|
||||
//set initial image
|
||||
//set mask image
|
||||
|
||||
try {
|
||||
let outpaintLayers = []
|
||||
await executeAsModal(async (context) => {
|
||||
const history_id = await context.hostControl.suspendHistory({
|
||||
documentID: app.activeDocument.id, //TODO: change this to the session document id
|
||||
name: 'Outpaint Mask Related layers',
|
||||
})
|
||||
const selectionInfo = await psapi.getSelectionInfoExe()
|
||||
// await psapi.unSelectMarqueeExe()
|
||||
|
||||
//create a snapshot of canvas
|
||||
// let [snapshotLayer,snapshotGroup] = await createSnapshot()
|
||||
await psapi.snapshot_layerExe()
|
||||
const snapshotLayer = await app.activeDocument.activeLayers[0]
|
||||
snapshotLayer.name = 'Init Image Snapshot -- temporary'
|
||||
const snapshotGroup = await psapi.createEmptyGroup()
|
||||
// snapshotGroup.name = `${snapshotGroup.name}_init_image`
|
||||
snapshotGroup.name = 'Init Image Group -- temporary'
|
||||
await psapi.createSolidLayer(255, 255, 255) //solid white inside the Init Image Group
|
||||
const whiteSolidLayer = await app.activeDocument.activeLayers[0]
|
||||
whiteSolidLayer.name = 'Background Color -- temporary'
|
||||
snapshotLayer.moveAbove(whiteSolidLayer) //move the snapshot layer to be the first layer in "Init Image Group"
|
||||
console.log('[snapshotLayer,snapshotGroup]:', [
|
||||
snapshotLayer,
|
||||
snapshotGroup,
|
||||
])
|
||||
|
||||
//select opaque pixel and create black fill layer
|
||||
await psapi.selectLayers([snapshotLayer])
|
||||
await psapi.selectLayerChannelCommand()
|
||||
const snapshotMaskGroup = await psapi.createEmptyGroup()
|
||||
|
||||
await psapi.createSolidLayer(0, 0, 0)
|
||||
let solid_black_layer = app.activeDocument.activeLayers[0]
|
||||
//create a snapshot of mask
|
||||
await psapi.reSelectMarqueeExe(selectionInfo)
|
||||
// let [snapshotMaskLayer,snapshotMaskGroup] = await createSnapshot()
|
||||
await psapi.snapshot_layerExe()
|
||||
const snapshotMaskLayer = await app.activeDocument.activeLayers[0]
|
||||
snapshotMaskLayer.name = 'Mask -- Paint White to Mask -- temporary'
|
||||
// const snapshotMaskGroup = await psapi.createEmptyGroup()
|
||||
|
||||
// snapshotMaskGroup.name = `${snapshotMaskGroup.name}_mask`
|
||||
snapshotMaskGroup.name = 'Mask Group -- temporary'
|
||||
snapshotMaskLayer.moveBelow(solid_black_layer)
|
||||
await snapshotMaskGroup.moveAbove(snapshotGroup)
|
||||
await solid_black_layer.delete() //
|
||||
|
||||
await addClippingMaskToLayer(snapshotGroup, selectionInfo)
|
||||
|
||||
const mask_info = await psapi.silentSetInitImageMask(
|
||||
snapshotMaskGroup,
|
||||
session_id
|
||||
)
|
||||
snapshotMaskGroup.visible = false
|
||||
|
||||
const image_info = await psapi.silentSetInitImage(
|
||||
snapshotGroup,
|
||||
session_id
|
||||
)
|
||||
snapshotGroup.visible = false
|
||||
|
||||
const init_image_name = image_info['name']
|
||||
const init_path = `./server/python_server/init_images/${init_image_name}`
|
||||
|
||||
await psapi.reSelectMarqueeExe(selectionInfo)
|
||||
|
||||
await addClippingMaskToLayer(snapshotMaskGroup, selectionInfo)
|
||||
|
||||
await psapi.reSelectMarqueeExe(selectionInfo)
|
||||
|
||||
const mask_name = mask_info['name']
|
||||
const mask_path = `./server/python_server/init_images/${mask_name}`
|
||||
await psapi.reSelectMarqueeExe(selectionInfo)
|
||||
//set initial image
|
||||
//set mask image
|
||||
outpaintLayers = [
|
||||
snapshotMaskGroup,
|
||||
snapshotMaskLayer,
|
||||
snapshotLayer,
|
||||
snapshotGroup,
|
||||
whiteSolidLayer,
|
||||
]
|
||||
// g_mask_related_layers['mask_group'] = snapshotMaskGroup
|
||||
// g_mask_related_layers['white_mark'] = snapshotMaskLayer
|
||||
// // g_mask_related_layers['solid_black'] = blackSolidLayer
|
||||
g_viewer_manager.initializeMask(
|
||||
snapshotMaskGroup,
|
||||
snapshotMaskLayer,
|
||||
null,
|
||||
mask_path,
|
||||
mask_info['base64']
|
||||
)
|
||||
// g_init_image_related_layers['init_image_group'] = snapshotGroup
|
||||
// g_init_image_related_layers['init_image_layer'] = snapshotLayer
|
||||
// g_init_image_related_layers['solid_white'] = whiteSolidLayer
|
||||
g_viewer_manager.initializeInitImage(
|
||||
snapshotGroup,
|
||||
snapshotLayer,
|
||||
whiteSolidLayer,
|
||||
init_path
|
||||
) //this will be called once a session and will add the first init image to th viewer manager
|
||||
|
||||
for (layer of outpaintLayers) {
|
||||
layer.visible = false
|
||||
}
|
||||
|
||||
//collapse the folders
|
||||
const layer_util = require('./utility/layer')
|
||||
await layer_util.collapseFolderExe(
|
||||
[snapshotGroup, snapshotMaskGroup],
|
||||
false
|
||||
)
|
||||
await context.hostControl.resumeHistory(history_id)
|
||||
})
|
||||
console.log('outpaintLayers 2: ', outpaintLayers)
|
||||
return outpaintLayers
|
||||
} catch (e) {
|
||||
console.error(`outpaintExe error: ${e}`)
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
async function inpaintFasterExe(session_id) {
|
||||
//create a snapshot of canvas
|
||||
//select opaque pixel and create black fill layer
|
||||
//create a snapshot of mask
|
||||
//set initial image
|
||||
//set mask image
|
||||
try {
|
||||
let inpaintLayers = []
|
||||
await executeAsModal(async (context) => {
|
||||
const history_id = await context.hostControl.suspendHistory({
|
||||
documentID: app.activeDocument.id,
|
||||
name: 'Inpaint Mask Related layers',
|
||||
})
|
||||
const original_white_mark_layer = await app.activeDocument
|
||||
.activeLayers[0]
|
||||
original_white_mark_layer.visible = false
|
||||
|
||||
const selectionInfo = await psapi.getSelectionInfoExe()
|
||||
|
||||
//duplicate the current active layer and use it as the white mark layer
|
||||
const white_mark_layer =
|
||||
await app.activeDocument.activeLayers[0].duplicate()
|
||||
white_mark_layer.visible = true
|
||||
const mask_layer_opacity = await white_mark_layer.opacity
|
||||
white_mark_layer.opacity = 100 //make sure the opacity is full
|
||||
await psapi.selectLayers([white_mark_layer])
|
||||
await psapi.reSelectMarqueeExe(selectionInfo)
|
||||
await psapi.createClippingMaskExe()
|
||||
await psapi.reSelectMarqueeExe(selectionInfo)
|
||||
|
||||
white_mark_layer.visible = false
|
||||
white_mark_layer.name = 'Mask -- Paint White to Mask -- temporary'
|
||||
// white_mark_layer.visible = true
|
||||
|
||||
//create a snapshot of canvas
|
||||
|
||||
// let [snapshotLayer,snapshotGroup] = await createSnapshot()
|
||||
// await psapi.snapshot_layer()
|
||||
await psapi.unselectActiveLayersExe() //invisible layer will cause problem with merging "command is not available" type of error
|
||||
// await psapi.mergeVisibleExe()
|
||||
await psapi.snapshot_layerExe()
|
||||
|
||||
const snapshotLayer = await app.activeDocument.activeLayers[0]
|
||||
snapshotLayer.name = 'Init Image Snapshot -- temporary'
|
||||
const snapshotGroup = await psapi.createEmptyGroup()
|
||||
snapshotGroup.name = 'Init Image Group -- temporary'
|
||||
await psapi.createSolidLayer(255, 255, 255)
|
||||
const whiteSolidLayer = await app.activeDocument.activeLayers[0]
|
||||
whiteSolidLayer.name = 'Background Color -- temporary'
|
||||
await snapshotLayer.moveAbove(whiteSolidLayer)
|
||||
|
||||
await psapi.selectLayers([snapshotGroup])
|
||||
await psapi.reSelectMarqueeExe(selectionInfo)
|
||||
await psapi.createClippingMaskExe()
|
||||
await psapi.reSelectMarqueeExe(selectionInfo)
|
||||
|
||||
const maskGroup = await psapi.createEmptyGroup()
|
||||
// maskGroup.name = `${maskGroup.name}_mask`
|
||||
|
||||
maskGroup.name = 'Mask Group -- temporary'
|
||||
|
||||
await psapi.createSolidLayer(0, 0, 0)
|
||||
const blackSolidLayer = await app.activeDocument.activeLayers[0]
|
||||
blackSolidLayer.name = "Don't Edit -- temporary"
|
||||
// snapshotLayer.moveAbove(blackSolidLayer)
|
||||
white_mark_layer.moveAbove(blackSolidLayer)
|
||||
white_mark_layer.visible = true
|
||||
await psapi.reSelectMarqueeExe(selectionInfo)
|
||||
|
||||
console.log('[snapshotLayer,maskGroup]:', [
|
||||
snapshotLayer,
|
||||
maskGroup,
|
||||
])
|
||||
// //select opaque pixel and create black fill layer
|
||||
// await psapi.selectLayers([snapshotLayer])
|
||||
// await psapi.selectLayerChannelCommand()
|
||||
// const snapshotMaskGroup = await psapi.createEmptyGroup()
|
||||
|
||||
// await psapi.createSolidLayer(0, 0, 0)
|
||||
// let solid_black_layer = app.activeDocument.activeLayers[0]
|
||||
// //create a snapshot of mask
|
||||
// await psapi.reSelectMarqueeExe(selectionInfo)
|
||||
// // let [snapshotMaskLayer,snapshotMaskGroup] = await createSnapshot()
|
||||
// await psapi.snapshot_layer()
|
||||
// const snapshotMaskLayer = await app.activeDocument.activeLayers[0]
|
||||
// // const snapshotMaskGroup = await psapi.createEmptyGroup()
|
||||
|
||||
// snapshotMaskGroup.name = `${snapshotMaskGroup.name}_mask`
|
||||
// snapshotMaskLayer.moveBelow(solid_black_layer)
|
||||
// await snapshotMaskGroup.moveAbove(snapshotGroup)
|
||||
// solid_black_layer.delete()
|
||||
|
||||
await psapi.selectLayers([maskGroup])
|
||||
await psapi.reSelectMarqueeExe(selectionInfo)
|
||||
await psapi.createClippingMaskExe()
|
||||
await psapi.reSelectMarqueeExe(selectionInfo)
|
||||
|
||||
// await psapi.selectLayers([snapshotGroup])
|
||||
|
||||
await psapi.selectLayers([maskGroup])
|
||||
|
||||
const mask_info = await psapi.silentSetInitImageMask(
|
||||
maskGroup,
|
||||
session_id
|
||||
)
|
||||
maskGroup.visible = false
|
||||
//hide the mask so you can take screenshot of the init image
|
||||
const mask_name = mask_info['name']
|
||||
const mask_path = `./server/python_server/init_images/${mask_name}`
|
||||
|
||||
await psapi.reSelectMarqueeExe(selectionInfo)
|
||||
await psapi.selectLayers([snapshotGroup])
|
||||
|
||||
const image_info = await psapi.silentSetInitImage(
|
||||
snapshotGroup,
|
||||
session_id
|
||||
)
|
||||
const image_name = image_info['name']
|
||||
const path = `./server/python_server/init_images/${image_name}`
|
||||
|
||||
await psapi.reSelectMarqueeExe(selectionInfo)
|
||||
// await psapi.selectLayers([snapshotMaskGroup])
|
||||
// await psapi.setInitImageMask(snapshotMaskGroup)
|
||||
// //set initial image
|
||||
// //set mask image
|
||||
|
||||
await psapi.selectLayers([maskGroup])
|
||||
inpaintLayers = [
|
||||
maskGroup,
|
||||
white_mark_layer,
|
||||
blackSolidLayer,
|
||||
snapshotGroup,
|
||||
snapshotLayer,
|
||||
whiteSolidLayer,
|
||||
]
|
||||
// g_mask_related_layers['mask_group'] = maskGroup
|
||||
// g_mask_related_layers['white_mark'] = white_mark_layer
|
||||
// g_mask_related_layers['solid_black'] = blackSolidLayer
|
||||
g_viewer_manager.initializeMask(
|
||||
maskGroup,
|
||||
white_mark_layer,
|
||||
blackSolidLayer,
|
||||
mask_path,
|
||||
mask_info['bases64']
|
||||
)
|
||||
// g_init_image_related_layers['init_image_group'] = snapshotGroup
|
||||
// g_init_image_related_layers['init_image_layer'] = snapshotLayer
|
||||
// g_init_image_related_layers['solid_white'] = whiteSolidLayer
|
||||
g_viewer_manager.initializeInitImage(
|
||||
snapshotGroup,
|
||||
snapshotLayer,
|
||||
whiteSolidLayer,
|
||||
path
|
||||
) //this will be called once a session and will add the first init image to th viewer manager
|
||||
for (layer of inpaintLayers) {
|
||||
layer.visible = false
|
||||
}
|
||||
const layer_util = require('./utility/layer')
|
||||
|
||||
await layer_util.collapseFolderExe(
|
||||
[snapshotGroup, maskGroup],
|
||||
false
|
||||
)
|
||||
white_mark_layer.opacity = mask_layer_opacity // restore the opacity
|
||||
// original_white_mark_layer.visible = true// leave it off so we can toggle using the viewer manager
|
||||
await context.hostControl.resumeHistory(history_id)
|
||||
})
|
||||
return inpaintLayers
|
||||
} catch (e) {
|
||||
console.warn('inpaintFasterExe error:', e)
|
||||
}
|
||||
return []
|
||||
}
|
||||
module.exports = {
|
||||
createSnapshot,
|
||||
|
||||
moveLayersToGroup,
|
||||
executeCommand,
|
||||
outpaintExe,
|
||||
// outpaintFasterExe,
|
||||
inpaintFasterExe,
|
||||
snapAndFillExe,
|
||||
addClippingMaskToLayer,
|
||||
}
|
||||
2
psapi.js
2
psapi.js
|
|
@ -931,7 +931,7 @@ async function silentSetInitImageMask(layer, session_id) {
|
|||
async function cleanLayers(layers) {
|
||||
// g_init_image_related_layers = {}
|
||||
// g_mask_related_layers = {}
|
||||
// await loadViewerImages()// we should move loadViewerImages to a new file viewer.js
|
||||
|
||||
console.log('cleanLayers() -> layers:', layers)
|
||||
for (layer of layers) {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -24,13 +24,13 @@ const elemSelectorForLocale = {
|
|||
'#rbLexica': 'Lexica',
|
||||
'#viewerSubTab .flexContainer sp-label':
|
||||
'View your generated images on the canvas',
|
||||
'#btnSetMaskViewer': 'Set Mask',
|
||||
'#btnSetInitImageViewer': 'Set Init Image',
|
||||
// '#btnSetMaskViewer': 'Set Mask',
|
||||
// '#btnSetInitImageViewer': 'Set Init Image',
|
||||
'#btnInterruptViewer': 'Interrupt',
|
||||
// '#btnSelectionArea': 'Selection Area',
|
||||
|
||||
// extra tab
|
||||
'#slThumbnailSize sp-label': 'Thumbnail Size',
|
||||
// '#slThumbnailSize sp-label': 'Thumbnail Size',
|
||||
'#chSquareThumbnail': 'Square 1:1',
|
||||
'#btnGenerateUpscale': 'Generate upscale',
|
||||
'#btnInterruptUpscale': 'Interrupt',
|
||||
|
|
|
|||
|
|
@ -585,18 +585,6 @@ function setInitImageMaskSrc(image_src) {
|
|||
|
||||
////// Start Generate Buttons //////////
|
||||
|
||||
function getGenerateButtonsElements() {
|
||||
generate_buttons = [...document.getElementsByClassName('btnGenerateClass')]
|
||||
return generate_buttons
|
||||
}
|
||||
function setGenerateButtonsColor(addClassName, removeClassName) {
|
||||
const buttons = getGenerateButtonsElements()
|
||||
buttons.forEach((button) => {
|
||||
button.classList.add(addClassName)
|
||||
button.classList.remove(removeClassName)
|
||||
})
|
||||
}
|
||||
|
||||
////// End Generate Buttons //////////
|
||||
|
||||
////// Start Servers Status //////////
|
||||
|
|
@ -1105,7 +1093,7 @@ module.exports = {
|
|||
getMode,
|
||||
setInitImageSrc,
|
||||
setInitImageMaskSrc,
|
||||
setGenerateButtonsColor,
|
||||
|
||||
setAutomaticStatus,
|
||||
setProxyServerStatus,
|
||||
defaultSettings,
|
||||
|
|
|
|||
|
|
@ -312,9 +312,7 @@ class hordeGenerator {
|
|||
console.warn(e)
|
||||
}
|
||||
}
|
||||
async postGeneration() {
|
||||
toggleTwoButtonsByClass(false, 'btnGenerateClass', 'btnInterruptClass')
|
||||
}
|
||||
|
||||
async processHordeResult() {
|
||||
//*) get the result from the horde server
|
||||
//*) save them locally to output directory
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ const { cleanLayers } = require('../psapi')
|
|||
const psapi = require('../psapi')
|
||||
const io = require('./io')
|
||||
const Enum = require('../enum')
|
||||
const { ViewerManager } = require('../viewer')
|
||||
|
||||
const { base64ToBase64Url } = require('./general')
|
||||
const html_manip = require('./html_manip')
|
||||
const layer_util = require('./layer')
|
||||
|
|
@ -59,95 +59,7 @@ class GenerationSession {
|
|||
name() {
|
||||
return `session - ${this.id}`
|
||||
}
|
||||
async startSession() {
|
||||
this.id += 1 //increment the session id for each session we start
|
||||
this.activate()
|
||||
this.isFirstGeneration = true // only before the first generation is requested should this be true
|
||||
|
||||
console.log('current session id: ', this.id)
|
||||
try {
|
||||
const session_name = this.name()
|
||||
const activeLayers = await app.activeDocument.activeLayers
|
||||
await psapi.unselectActiveLayersExe() // unselect all layer so the create group is place at the top of the document
|
||||
this.prevOutputGroup = this.outputGroup
|
||||
const outputGroup = await psapi.createEmptyGroup(session_name)
|
||||
await executeAsModal(async () => {
|
||||
outputGroup.allLocked = true //lock the session folder so that it can't move
|
||||
})
|
||||
this.outputGroup = outputGroup
|
||||
await psapi.selectLayersExe(activeLayers)
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
|
||||
async endSession(garbage_collection_state) {
|
||||
try {
|
||||
if (!this.isActive()) {
|
||||
//return if the session is not active
|
||||
return null
|
||||
}
|
||||
this.state = SessionState['Inactive'] // end the session by deactivate it
|
||||
|
||||
this.deactivate()
|
||||
|
||||
if (garbage_collection_state === GarbageCollectionState['Accept']) {
|
||||
await acceptAll()
|
||||
} else if (
|
||||
garbage_collection_state === GarbageCollectionState['Discard']
|
||||
) {
|
||||
//this should be discardAll()
|
||||
|
||||
await discardAll()
|
||||
} else if (
|
||||
garbage_collection_state ===
|
||||
GarbageCollectionState['DiscardSelected']
|
||||
) {
|
||||
//this should be discardAllExcept(selectedLayers)
|
||||
await discardSelected() //this will discard what is not been highlighted
|
||||
} else if (
|
||||
garbage_collection_state ===
|
||||
GarbageCollectionState['AcceptSelected']
|
||||
) {
|
||||
//this should be discardAllExcept(selectedLayers)
|
||||
await discard() //this will discard what is not been highlighted
|
||||
}
|
||||
|
||||
//delete the old selection area
|
||||
// g_generation_session.selectionInfo = {}
|
||||
|
||||
this.isFirstGeneration = true // only before the first generation is requested should this be true
|
||||
// const is_visible = await this.outputGroup.visible
|
||||
g_viewer_manager.last_selected_viewer_obj = null // TODO: move this in viewerManager endSession()
|
||||
g_viewer_manager.onSessionEnd()
|
||||
await layer_util.collapseFolderExe([this.outputGroup], false) // close the folder group
|
||||
await executeAsModal(async () => {
|
||||
this.outputGroup.allLocked = false //unlock the session folder on session end
|
||||
})
|
||||
// this.outputGroup.visible = is_visible
|
||||
|
||||
if (
|
||||
this.mode === generationMode['Inpaint'] &&
|
||||
g_sd_mode === generationMode['Inpaint']
|
||||
) {
|
||||
//create "Mask -- Paint White to Mask -- temporary" layer if current session was inpiant and the selected session is inpaint
|
||||
// the current inpaint session ended on inpaint
|
||||
g_b_mask_layer_exist = false
|
||||
await layer_util.deleteLayers([g_inpaint_mask_layer])
|
||||
await createTempInpaintMaskLayer()
|
||||
}
|
||||
//delete controlNet image, Note: don't delete control net, let the user disable controlNet if doesn't want to use it
|
||||
// this.controlNetImage = null
|
||||
// html_manip.setControlImageSrc('https://source.unsplash.com/random')
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
// initializeInitImage(group, snapshot, solid_background, path) {
|
||||
// this.initGroup = group
|
||||
// this.init_solid_background = solid_background
|
||||
// this.InitSnapshot = snapshot
|
||||
// }
|
||||
deleteInitImageLayers() {}
|
||||
async closePreviousOutputGroup() {
|
||||
try {
|
||||
|
|
|
|||
122
utility/ui.js
122
utility/ui.js
|
|
@ -7,130 +7,8 @@ const { executeAsModal } = require('photoshop').core
|
|||
|
||||
class UI {
|
||||
constructor() {}
|
||||
|
||||
onStartSessionUI() {
|
||||
// will toggle the buttons needed when a generation session start
|
||||
|
||||
const accept_class_btns = Array.from(
|
||||
document.getElementsByClassName('acceptClass')
|
||||
)
|
||||
|
||||
const discard_class_btns = Array.from(
|
||||
document.getElementsByClassName('discardClass')
|
||||
)
|
||||
|
||||
const discard_selected_class_btns = Array.from(
|
||||
document.getElementsByClassName('discardSelectedClass')
|
||||
)
|
||||
|
||||
const accept_selected_class_btns = Array.from(
|
||||
document.getElementsByClassName('acceptSelectedClass')
|
||||
)
|
||||
|
||||
//show the accept and discard buttons when a new session is active
|
||||
accept_class_btns.forEach(
|
||||
(element) => (element.style.display = 'inline-block')
|
||||
)
|
||||
discard_class_btns.forEach(
|
||||
(element) => (element.style.display = 'inline-block')
|
||||
)
|
||||
discard_selected_class_btns.forEach(
|
||||
(element) => (element.style.display = 'inline-block')
|
||||
)
|
||||
accept_selected_class_btns.forEach(
|
||||
(element) => (element.style.display = 'inline-block')
|
||||
)
|
||||
|
||||
this.generateMoreUI()
|
||||
}
|
||||
onActiveSessionUI() {}
|
||||
generateModeUI(mode) {
|
||||
const generate_btns = Array.from(
|
||||
document.getElementsByClassName('btnGenerateClass')
|
||||
)
|
||||
generate_btns.forEach((element) => {
|
||||
element.textContent = `Generate ${mode}`
|
||||
})
|
||||
html_manip.setGenerateButtonsColor('generate', 'generate-more')
|
||||
}
|
||||
generateMoreUI() {
|
||||
const generate_btns = Array.from(
|
||||
document.getElementsByClassName('btnGenerateClass')
|
||||
)
|
||||
const generation_mode = g_generation_session.mode
|
||||
const generation_name = getCurrentGenerationModeByValue(generation_mode)
|
||||
generate_btns.forEach((element) => {
|
||||
element.textContent = `Generate More ${generation_name}`
|
||||
})
|
||||
html_manip.setGenerateButtonsColor('generate-more', 'generate')
|
||||
}
|
||||
|
||||
onEndSessionUI() {
|
||||
const accept_class_btns = Array.from(
|
||||
document.getElementsByClassName('acceptClass')
|
||||
)
|
||||
|
||||
const discard_class_btns = Array.from(
|
||||
document.getElementsByClassName('discardClass')
|
||||
)
|
||||
const discard_selected_class_btns = Array.from(
|
||||
document.getElementsByClassName('discardSelectedClass')
|
||||
)
|
||||
|
||||
const accept_selected_class_btns = Array.from(
|
||||
//Node: change customClass to acceptSelectedClass
|
||||
document.getElementsByClassName('acceptSelectedClass')
|
||||
)
|
||||
|
||||
accept_class_btns.forEach((element) => (element.style.display = 'none'))
|
||||
discard_class_btns.forEach(
|
||||
(element) => (element.style.display = 'none')
|
||||
)
|
||||
discard_selected_class_btns.forEach(
|
||||
(element) => (element.style.display = 'none')
|
||||
)
|
||||
|
||||
accept_selected_class_btns.forEach(
|
||||
(element) => (element.style.display = 'none')
|
||||
)
|
||||
|
||||
this.generateModeUI(g_sd_mode)
|
||||
}
|
||||
|
||||
setGenerateBtnText(textContent) {
|
||||
const generate_btns = Array.from(
|
||||
document.getElementsByClassName('btnGenerateClass')
|
||||
)
|
||||
generate_btns.forEach((element) => {
|
||||
element.textContent = textContent
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// const defaultSettings = {
|
||||
// model: null,
|
||||
// prompt_shortcut: null,
|
||||
// positive_prompt: "",
|
||||
// negative_prompt: "",
|
||||
// selection_mode: null,
|
||||
// batch_number: 1,
|
||||
// steps: 20,
|
||||
// width: 512 ,
|
||||
// height:512,
|
||||
// firstphase_width:512,
|
||||
// firstphase_height:512,
|
||||
// cfg:7,
|
||||
// denoising_strength:0.7,
|
||||
// hi_res_denoising_strength:0.7,
|
||||
// mask_blur: 8,
|
||||
// inpaint_at_full_res: false,
|
||||
// hi_res_fix:false,
|
||||
// inpaint_padding:0,
|
||||
// seed:-1,
|
||||
// samplers: null,
|
||||
// mask_content:null
|
||||
// }
|
||||
|
||||
class UIElement {
|
||||
constructor() {
|
||||
this.name
|
||||
|
|
|
|||
860
viewer.js
860
viewer.js
|
|
@ -1,860 +0,0 @@
|
|||
// output image class: one image to one layer
|
||||
// * path:
|
||||
// * image layer
|
||||
// * viewer()
|
||||
// * select()
|
||||
|
||||
// * init image class: has three layers
|
||||
// * path :
|
||||
// * init image group layer
|
||||
// * init image layer
|
||||
// * background layer
|
||||
|
||||
// * mask class:
|
||||
// * path
|
||||
// * mask group
|
||||
// * white mask
|
||||
// * balck layer
|
||||
// * select()
|
||||
// * viewe()
|
||||
const general = require('./utility/general')
|
||||
const Enum = require('./enum')
|
||||
const psapi = require('./psapi')
|
||||
const layer_util = require('./utility/layer')
|
||||
const thumbnail = require('./thumbnail')
|
||||
const ViewerObjState = {
|
||||
Delete: 'delete',
|
||||
Unlink: 'unlink',
|
||||
}
|
||||
|
||||
class ViewerImage {
|
||||
constructor() {
|
||||
this.img_html = null //
|
||||
this.thumbnail_container = null
|
||||
this.is_highlighted = false
|
||||
this.can_highlight = true
|
||||
this.is_active = false // active is a temporary highlight , the yellow/orang highlight
|
||||
this.state = ViewerObjState['Unlink']
|
||||
|
||||
// true will delete the layers from the layer stacks when the session ends,
|
||||
// false mean use this.state to determine whither you delete the layer or not
|
||||
this.autoDelete = false
|
||||
this.viewerManager = null // store link to the viewer manager of this document
|
||||
this.viewerObjectType
|
||||
this.objectId
|
||||
}
|
||||
info() {
|
||||
console.log('state: ', this.state)
|
||||
}
|
||||
visible(visibleOn) {}
|
||||
select() {}
|
||||
isActive() {
|
||||
return this.is_active
|
||||
}
|
||||
active(isActive) {
|
||||
if (isActive) {
|
||||
//unlink it if it's active
|
||||
// this.state = ViewerObjState['Unlink']
|
||||
|
||||
this.img_html.classList.add('viewerImgActive')
|
||||
} else {
|
||||
if (this.getHighlight() === false) {
|
||||
// if it's not active and it's not highlighted
|
||||
// this.state = ViewerObjState['Delete']
|
||||
} else {
|
||||
// this.state = ViewerObjState['Unlink'] //it's not active but it's highlighted then keep it
|
||||
}
|
||||
this.img_html.classList.remove('viewerImgActive')
|
||||
}
|
||||
this.is_active = isActive
|
||||
}
|
||||
setAutoDelete(auto_delete) {
|
||||
this.autoDelete = auto_delete
|
||||
}
|
||||
|
||||
isSameLayer(layer_id) {}
|
||||
setHighlight(is_highlighted) {
|
||||
if (this.can_highlight) {
|
||||
this.is_highlighted = is_highlighted
|
||||
if (this.is_highlighted) {
|
||||
// this.state = ViewerObjState['Unlink']
|
||||
this.img_html.classList.add('viewerImgSelected')
|
||||
} else {
|
||||
this.img_html.classList.remove('viewerImgSelected')
|
||||
// this.state = ViewerObjState["Delete"]
|
||||
}
|
||||
}
|
||||
}
|
||||
getHighlight() {
|
||||
return this.is_highlighted
|
||||
}
|
||||
toggleHighlight() {
|
||||
const toggle_value = !this.getHighlight()
|
||||
this.setHighlight(toggle_value)
|
||||
// this.is_highlighted = !this.is_highlighted
|
||||
// this.img_html.classList.toggle("viewerImgSelected")
|
||||
}
|
||||
setImgHtml() {}
|
||||
|
||||
async delete() {
|
||||
try {
|
||||
if (this.img_html) {
|
||||
this.img_html.remove() //delete the img html element
|
||||
}
|
||||
if (this.thumbnail_container) {
|
||||
this.thumbnail_container.remove()
|
||||
}
|
||||
|
||||
//1) it's output layer // can_highlight && this.getHighlight()
|
||||
//2) it init or mask relate layers // this.autoDelete
|
||||
//3) it output layer that been used as init layer // !can_highlight && !this.autoDelete
|
||||
|
||||
// do 1) and 2) here . test for 3) in InitImage
|
||||
|
||||
//1)
|
||||
if (this.can_highlight && (this.getHighlight() || this.is_active)) {
|
||||
//keep if can be highlighted and either is highlighted or active
|
||||
this.state = ViewerObjState['Unlink']
|
||||
} else {
|
||||
this.state = ViewerObjState['Delete']
|
||||
}
|
||||
|
||||
if (this.autoDelete) {
|
||||
//remove if it's first automated layer
|
||||
this.state = ViewerObjState['Delete']
|
||||
}
|
||||
|
||||
// else {
|
||||
// //discard only if it's
|
||||
// if (this.autoDelete){
|
||||
// this.state = ViewerObjState['Delete']
|
||||
// }
|
||||
// }
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
|
||||
unlink() {
|
||||
//keep the layer but unlink it from the ui
|
||||
try {
|
||||
this.img_html.remove() //delete the img html element
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
|
||||
createThumbnailNew(img, _) {
|
||||
this.img_html = img
|
||||
this.thumbnail_container = thumbnail.Thumbnail.wrapImgInContainer(
|
||||
img,
|
||||
'viewer-image-container'
|
||||
)
|
||||
thumbnail.Thumbnail.addSPButtonToContainer(
|
||||
this.thumbnail_container,
|
||||
'svg_sp_btn',
|
||||
'Use this as an initial image',
|
||||
|
||||
this.useOutputImageAsInitImage,
|
||||
img
|
||||
)
|
||||
}
|
||||
useOutputImageAsInitImage = async () => {
|
||||
//set init image event listener, use when settion is active
|
||||
// const layer = await app.activeDocument.activeLayers[0]
|
||||
try {
|
||||
// console.log('this.img_html:', this.img_html)
|
||||
// await executeAsModal(() => {
|
||||
// this.visible(true)
|
||||
// })
|
||||
// await this.select(true) //select() does take arguments
|
||||
// this.active(true)
|
||||
await executeAsModal(async () => {
|
||||
await this.click(Enum.clickTypeEnum['Click'])
|
||||
})
|
||||
|
||||
const layer = layer_util.Layer.doesLayerExist(this.layer)
|
||||
? this.layer
|
||||
: await app.activeDocument.activeLayers[0]
|
||||
|
||||
// const layer = this.layer
|
||||
const image_info = await psapi.silentSetInitImage(
|
||||
layer,
|
||||
random_session_id
|
||||
)
|
||||
const image_name = image_info['name']
|
||||
const path = `./server/python_server/init_images/${image_name}`
|
||||
g_viewer_manager.addInitImageLayers(layer, path, false)
|
||||
await g_viewer_manager.loadInitImageViewerObject(path)
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
createThumbnail(img, b_button_visible = true) {
|
||||
this.img_html = img
|
||||
// Create new container element
|
||||
this.thumbnail_container = document.createElement('div')
|
||||
|
||||
this.thumbnail_container.className = 'viewer-image-container'
|
||||
|
||||
const elem = document.getElementById('svg_sp_btn')
|
||||
|
||||
// Create a copy of it
|
||||
const clone = elem.cloneNode(true)
|
||||
const button = clone
|
||||
button.style.display = null
|
||||
button.setAttribute(
|
||||
'title',
|
||||
'use this image to generate more variance like it'
|
||||
)
|
||||
|
||||
// Create button element
|
||||
// const button = document.createElement('sp-button');
|
||||
button.className = 'viewer-image-button'
|
||||
// button.innerHTML = "Button";
|
||||
if (!b_button_visible) {
|
||||
button.style.display = 'none'
|
||||
}
|
||||
button.addEventListener('click', async () => {
|
||||
await useOutputImageAsInitImage()
|
||||
})
|
||||
|
||||
// Append elements to container
|
||||
this.thumbnail_container.appendChild(this.img_html)
|
||||
this.thumbnail_container.appendChild(button)
|
||||
|
||||
// this.img_html = container
|
||||
}
|
||||
}
|
||||
|
||||
class OutputImage extends ViewerImage {
|
||||
constructor(layer, path, viewer_manager) {
|
||||
super()
|
||||
this.layer = layer
|
||||
this.path = path
|
||||
this.img_html = null
|
||||
this.viewerManager = viewer_manager
|
||||
this.viewerObjectType = Enum.ViewerObjectTypeEnum['OutputImage']
|
||||
this.objectId = path // the path is unique, so we will use it as an id
|
||||
}
|
||||
async click(click_type) {
|
||||
console.log('click_type: ', click_type)
|
||||
// if (this.isActive() && click_type === Enum.clickTypeEnum['Click']) {
|
||||
// //convert consecutive clicks to AltClick
|
||||
// click_type = Enum.clickTypeEnum['SecondClick']
|
||||
// console.log('converted click_type: ', click_type)
|
||||
// }
|
||||
|
||||
if (click_type === Enum.clickTypeEnum['Click']) {
|
||||
//select layer
|
||||
//turn the layer visible
|
||||
//set the layer to active
|
||||
this.visible(true)
|
||||
await this.select(true) //select() does take arguments
|
||||
this.active(true)
|
||||
} else if (click_type === Enum.clickTypeEnum['ShiftClick']) {
|
||||
this.visible(true)
|
||||
await this.select(true) //select() does take arguments
|
||||
this.setHighlight(true)
|
||||
this.active(true)
|
||||
// if (this.viewerManager.last_selected_viewer_obj) {
|
||||
// //if the last selected layer is valid then converted last selected layer into highlight layer
|
||||
// this.viewerManager.last_selected_viewer_obj.setHighlight(true)
|
||||
// }
|
||||
} else if (click_type === Enum.clickTypeEnum['AltClick']) {
|
||||
// this.viewerManager.last_selected_viewer_obj = null
|
||||
this.setHighlight(false)
|
||||
this.visible(false)
|
||||
this.active(false)
|
||||
|
||||
await psapi.unselectActiveLayersExe() //Note:can we move to ViewerManager.click()
|
||||
} else if (click_type === Enum.clickTypeEnum['SecondClick']) {
|
||||
//select layer
|
||||
//turn the layer visible
|
||||
//set the layer to active
|
||||
this.visible(false)
|
||||
await this.select(false) //select() does take arguments
|
||||
this.active(false)
|
||||
}
|
||||
this.viewerManager.replaceLastSelection(click_type, this) //pass the click_type and this object
|
||||
}
|
||||
visible(visibleOn) {
|
||||
//turn the visibility for the layer
|
||||
try {
|
||||
super.visible(visibleOn)
|
||||
if (layer_util.Layer.doesLayerExist(this.layer)) {
|
||||
this.layer.visible = visibleOn
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
async select() {
|
||||
//select the layer
|
||||
super.select()
|
||||
if (layer_util.Layer.doesLayerExist(this.layer)) {
|
||||
await psapi.selectLayersExe([this.layer])
|
||||
// console.log(`${this.layer.id} got selected`);
|
||||
}
|
||||
}
|
||||
|
||||
isSameLayer(layer_id) {
|
||||
super.isSameLayer(layer_id)
|
||||
const is_same = this.layer.id == layer_id
|
||||
return is_same
|
||||
}
|
||||
isSameObject(object) {
|
||||
if (
|
||||
layer_util.Layer.doesLayerExist(this.layer) &&
|
||||
layer_util.Layer.doesLayerExist(object.layer)
|
||||
) {
|
||||
return this.layer.id === object.layer.id
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
setImgHtml(img_html) {
|
||||
super.setImgHtml()
|
||||
this.img_html = img_html
|
||||
}
|
||||
async delete() {
|
||||
try {
|
||||
await super.delete()
|
||||
// this.img_html.remove()//delete the img html element
|
||||
if (this.state === ViewerObjState['Delete']) {
|
||||
await psapi.cleanLayers([this.layer])
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
info() {
|
||||
super.info()
|
||||
}
|
||||
// unlink(){
|
||||
// //keep the layer but unlink it from the ui
|
||||
// try{
|
||||
|
||||
// super.unlink()
|
||||
// this.img_html.remove()//delete the img html element
|
||||
|
||||
// }catch(e){
|
||||
// console.warn(e)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
class InitImage extends ViewerImage {
|
||||
constructor(init_group, init_snapshot, solid_layer, path, viewer_manager) {
|
||||
super()
|
||||
this.init_group = init_group
|
||||
this.init_snapshot = init_snapshot
|
||||
this.solid_layer = solid_layer
|
||||
|
||||
this.path = path
|
||||
this.can_highlight = false
|
||||
this.viewerManager = viewer_manager
|
||||
this.viewerObjectType = Enum.ViewerObjectTypeEnum['InitImage']
|
||||
this.objectId = path // the path is unique, so we will use it as an id
|
||||
// if (this.autoDelete === false){
|
||||
// this.state = ViewerObjState['Unlink']
|
||||
// }
|
||||
}
|
||||
async click(click_type) {
|
||||
if (click_type === Enum.clickTypeEnum['Click']) {
|
||||
//select layer
|
||||
//turn the layer visible
|
||||
//set the layer to active
|
||||
this.visible(true)
|
||||
await this.select(true) //select() does take arguments
|
||||
this.active(true)
|
||||
click_type = Enum.clickTypeEnum['Click'] // convert all click to Click
|
||||
this.viewerManager.replaceLastSelection(click_type, this) //pass the click_type and this object
|
||||
} else if (click_type === Enum.clickTypeEnum['ShiftClick']) {
|
||||
this.visible(true)
|
||||
await this.select(true) //select() does take arguments
|
||||
this.active(true)
|
||||
// if (this.viewerManager.last_selected_viewer_obj) {
|
||||
// //if the last selected layer is valid then converted last selected layer into highlight layer
|
||||
// this.viewerManager.last_selected_viewer_obj.setHighlight(true)
|
||||
// }
|
||||
click_type = Enum.clickTypeEnum['Click'] // convert all click to Click
|
||||
this.viewerManager.replaceLastSelection(click_type, this) //pass the click_type and this object
|
||||
}
|
||||
// else if (click_type === Enum.clickTypeEnum['AltClick']) {
|
||||
// // this.viewerManager.last_selected_viewer_obj = null
|
||||
// this.setHighlight(false)
|
||||
// this.visible(false)
|
||||
// this.active(false)
|
||||
|
||||
// await psapi.unselectActiveLayersExe() //Note:can we move to ViewerManager.click()
|
||||
// }
|
||||
// this.viewerManager.replaceLastSelection(click_type, this) //pass the click_type and this object
|
||||
}
|
||||
visible(visibleOn) {
|
||||
try {
|
||||
super.visible(visibleOn)
|
||||
|
||||
let visibleValues = []
|
||||
if (visibleOn) {
|
||||
visibleValues = [true, true, true]
|
||||
} else {
|
||||
visibleValues = [false, false, false]
|
||||
}
|
||||
|
||||
if (layer_util.Layer.doesLayerExist(this.init_group)) {
|
||||
this.init_group.visible = visibleValues[0]
|
||||
}
|
||||
if (layer_util.Layer.doesLayerExist(this.init_snapshot)) {
|
||||
this.init_snapshot.visible = visibleValues[1]
|
||||
}
|
||||
|
||||
if (layer_util.Layer.doesLayerExist(this.solid_layer)) {
|
||||
this.solid_layer.visible = visibleValues[2]
|
||||
}
|
||||
|
||||
if (!this.autoDelete) {
|
||||
//means it's not the first init image
|
||||
|
||||
if (layer_util.Layer.doesLayerExist(this.solid_layer)) {
|
||||
this.solid_layer.visible = false //turn it off sense the init group is above the output group, and the white solid will hide the init image reference located in the output group
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
|
||||
async select() {
|
||||
super.select()
|
||||
|
||||
const selectLayers = []
|
||||
if (layer_util.Layer.doesLayerExist(this.init_group)) {
|
||||
selectLayers.push(this.init_group)
|
||||
}
|
||||
|
||||
await psapi.selectLayersExe(selectLayers)
|
||||
// console.log(`${this.layer.id} got selected`);
|
||||
}
|
||||
|
||||
isSameLayer(layer_id) {
|
||||
super.isSameLayer(layer_id)
|
||||
let is_same = false
|
||||
if (layer_util.Layer.doesLayerExist(this.init_group)) {
|
||||
is_same = this.init_group.id == layer_id
|
||||
}
|
||||
return is_same
|
||||
}
|
||||
setImgHtml(img_html) {
|
||||
super.setImgHtml()
|
||||
this.img_html = img_html
|
||||
}
|
||||
async delete() {
|
||||
try {
|
||||
await super.delete()
|
||||
|
||||
// this.img_html.remove()//delete the img html element
|
||||
|
||||
if (!this.autoDelete && !this.can_highlight) {
|
||||
//don't delete since it's output layer that is been used as init image
|
||||
this.state = ViewerObjState['Unlink']
|
||||
}
|
||||
|
||||
if (this.state === ViewerObjState['Delete']) {
|
||||
await psapi.cleanLayers([
|
||||
this.init_group,
|
||||
this.init_snapshot,
|
||||
this.solid_layer,
|
||||
])
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class InitMaskImage extends ViewerImage {
|
||||
constructor(mask_group, white_mark, solid_black, path, viewer_manager) {
|
||||
super()
|
||||
this.mask_group = mask_group
|
||||
this.white_mark = white_mark
|
||||
this.solid_black = solid_black
|
||||
|
||||
this.path = path
|
||||
this.can_highlight = false
|
||||
this.viewerManager = viewer_manager
|
||||
this.viewerObjectType = Enum.ViewerObjectTypeEnum['MaskImage']
|
||||
this.objectId = path // the path is unique, so we will use it as an id
|
||||
}
|
||||
async click(click_type) {
|
||||
if (click_type === Enum.clickTypeEnum['Click']) {
|
||||
//select layer
|
||||
//turn the layer visible
|
||||
//set the layer to active
|
||||
this.visible(true)
|
||||
await this.select(true) //select() does take arguments
|
||||
this.active(true)
|
||||
click_type = Enum.clickTypeEnum['Click'] // convert all click to Click
|
||||
this.viewerManager.replaceLastSelection(click_type, this) //pass the click_type and this object
|
||||
} else if (click_type === Enum.clickTypeEnum['ShiftClick']) {
|
||||
this.visible(true)
|
||||
await this.select(true) //select() does take arguments
|
||||
this.active(true)
|
||||
// if (this.viewerManager.last_selected_viewer_obj) {
|
||||
// //if the last selected layer is valid then converted last selected layer into highlight layer
|
||||
// this.viewerManager.last_selected_viewer_obj.setHighlight(true)
|
||||
// }
|
||||
click_type = Enum.clickTypeEnum['Click'] // convert all click to Click
|
||||
this.viewerManager.replaceLastSelection(click_type, this) //pass the click_type and this object
|
||||
}
|
||||
}
|
||||
visible(visibleOn) {
|
||||
try {
|
||||
super.visible(visibleOn)
|
||||
|
||||
let visibleValues = []
|
||||
if (visibleOn) {
|
||||
visibleValues = [true, true, false]
|
||||
} else {
|
||||
visibleValues = [false, false, false]
|
||||
}
|
||||
|
||||
if (layer_util.Layer.doesLayerExist(this.mask_group)) {
|
||||
this.mask_group.visible = visibleValues[0]
|
||||
}
|
||||
if (layer_util.Layer.doesLayerExist(this.white_mark)) {
|
||||
this.white_mark.visible = visibleValues[1]
|
||||
}
|
||||
if (layer_util.Layer.doesLayerExist(this.solid_black)) {
|
||||
this.solid_black.visible = visibleValues[2]
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
|
||||
async select() {
|
||||
super.select()
|
||||
|
||||
const selectLayers = []
|
||||
|
||||
if (layer_util.Layer.doesLayerExist(this.white_mark)) {
|
||||
selectLayers.push(this.white_mark)
|
||||
}
|
||||
|
||||
await psapi.selectLayersExe(selectLayers)
|
||||
// console.log(`${this.layer.id} got selected`);
|
||||
}
|
||||
|
||||
isSameLayer(layer_id) {
|
||||
super.isSameLayer(layer_id)
|
||||
let is_same = false
|
||||
if (layer_util.Layer.doesLayerExist(this.mask_group)) {
|
||||
is_same = this.mask_group.id == layer_id
|
||||
}
|
||||
return is_same
|
||||
}
|
||||
setImgHtml(img_html) {
|
||||
super.setImgHtml()
|
||||
this.img_html = img_html
|
||||
}
|
||||
async delete() {
|
||||
try {
|
||||
await super.delete()
|
||||
// this.img_html.remove()//delete the img html element
|
||||
if (this.state === ViewerObjState['Delete']) {
|
||||
await psapi.cleanLayers([
|
||||
this.mask_group,
|
||||
this.white_mark,
|
||||
this.solid_black,
|
||||
])
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
createThumbnailNew(img, _) {
|
||||
this.img_html = img
|
||||
this.thumbnail_container = thumbnail.Thumbnail.wrapImgInContainer(
|
||||
img,
|
||||
'viewer-image-container'
|
||||
)
|
||||
thumbnail.Thumbnail.addSPButtonToContainer(
|
||||
this.thumbnail_container,
|
||||
'svg_sp_btn',
|
||||
'update the mask',
|
||||
setMaskViewer,
|
||||
img
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class initImageLayers {
|
||||
//store info about the init image related layers
|
||||
constructor(group, snapshot, solid_background, autoDelete) {
|
||||
this.group = group
|
||||
this.snapshot = snapshot
|
||||
this.solid_background = solid_background
|
||||
this.autoDelete = autoDelete
|
||||
}
|
||||
}
|
||||
class maskLayers {
|
||||
//store info about the init image related layers
|
||||
constructor(group, white_mark, solid_background, autoDelete) {
|
||||
this.group = group
|
||||
this.white_mark = white_mark
|
||||
this.solid_background = solid_background
|
||||
this.autoDelete = autoDelete
|
||||
}
|
||||
}
|
||||
class ViewerManager {
|
||||
//viewer manager will reset after the end of the session
|
||||
//it will store
|
||||
constructor() {
|
||||
this.outputImages = []
|
||||
this.initImages = []
|
||||
this.initMaskImage
|
||||
this.pathToViewerImage = {} // quick way to check if an link image path on disk to ViewerImage object.
|
||||
this.initImageLayersJson = {} //{path: initImageLayers}
|
||||
|
||||
this.selectedOutputImages = {} //store the selected output images {path: outputImage}
|
||||
|
||||
this.mask_layer
|
||||
this.maskLayersJson = {} //{path: MaskLayers}
|
||||
|
||||
//Note:move initGroup, to GenerationSession
|
||||
this.initGroup
|
||||
this.init_solid_background
|
||||
this.maskGroup
|
||||
this.mask_solid_background
|
||||
|
||||
//last_selected_obj
|
||||
this.last_selected_viewer_obj
|
||||
this.thumbnail_scaler = 1
|
||||
this.isSquareThumbnail = false
|
||||
this.init_image_container = document.getElementById(
|
||||
'divInitImageViewerContainer'
|
||||
)
|
||||
}
|
||||
|
||||
replaceLastSelection(click_type, clicked_object) {
|
||||
if (
|
||||
this.last_selected_viewer_obj && // is valid last selected object
|
||||
this.last_selected_viewer_obj.objectId !== clicked_object.objectId // not the same object
|
||||
|
||||
// clicked_object instanceof OutputImage &&
|
||||
// !clicked_object.isSameObject(this.last_selected_viewer_obj)
|
||||
) {
|
||||
//if the current selection and the last selection are different
|
||||
|
||||
this.last_selected_viewer_obj.visible(false)
|
||||
this.last_selected_viewer_obj.active(false)
|
||||
}
|
||||
if (click_type === Enum.clickTypeEnum['Click']) {
|
||||
this.last_selected_viewer_obj = clicked_object
|
||||
} else if (click_type === Enum.clickTypeEnum['ShiftClick']) {
|
||||
if (this.last_selected_viewer_obj) {
|
||||
//if the last selected layer is valid then converted last selected layer into highlight layer
|
||||
this.last_selected_viewer_obj.setHighlight(true)
|
||||
}
|
||||
this.last_selected_viewer_obj = clicked_object
|
||||
} else if (click_type === Enum.clickTypeEnum['AltClick']) {
|
||||
this.last_selected_viewer_obj = null
|
||||
} else if (click_type === Enum.clickTypeEnum['SecondClick']) {
|
||||
this.last_selected_viewer_obj = null
|
||||
}
|
||||
}
|
||||
initializeInitImage(group, snapshot, solid_background, path) {
|
||||
console.warn('this method is deprecated, use the session.js method ')
|
||||
this.initGroup = group
|
||||
this.init_solid_background = solid_background
|
||||
this.addInitImageLayers(snapshot, path, true)
|
||||
}
|
||||
initializeMask(group, white_mark, solid_background, path, base64) {
|
||||
this.maskGroup = group
|
||||
this.mask_solid_background = solid_background
|
||||
this.addMaskLayers(white_mark, path, true, base64)
|
||||
}
|
||||
addMaskLayers(white_mark, path, auto_delete, base64) {
|
||||
try {
|
||||
if (!this.maskLayersJson.hasOwnProperty(path)) {
|
||||
//it's a new mask, mostly for the first time storing the mask
|
||||
|
||||
const mask_layers = new maskLayers(
|
||||
this.maskGroup,
|
||||
white_mark,
|
||||
this.mask_solid_background,
|
||||
auto_delete
|
||||
)
|
||||
this.maskLayersJson[path] = mask_layers
|
||||
} else {
|
||||
//for updating the mask
|
||||
|
||||
//just update the html
|
||||
const new_path = `${path}?t=${new Date().getTime()}`
|
||||
console.log('new mask path: ', new_path)
|
||||
// this.maskLayersJson[path].img_html.src = new_path
|
||||
|
||||
// this.pathToViewerImage[path].img_html.src = new_path
|
||||
this.pathToViewerImage[path].img_html.src = base64ToSrc(base64)
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
updateMaskLayer() {}
|
||||
addInitImageLayers(snapshot, path, auto_delete) {
|
||||
try {
|
||||
if (!this.initImageLayersJson.hasOwnProperty(path)) {
|
||||
//if this is a new init image
|
||||
//store it all of layers in a container object
|
||||
const init_image_layers = new initImageLayers(
|
||||
this.initGroup,
|
||||
snapshot,
|
||||
this.init_solid_background,
|
||||
auto_delete
|
||||
)
|
||||
this.initImageLayersJson[path] = init_image_layers
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
|
||||
hasViewerImage(path) {
|
||||
if (this.pathToViewerImage.hasOwnProperty(path)) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
addOutputImage(layer, path) {
|
||||
const outputImage = new OutputImage(layer, path, this)
|
||||
|
||||
this.outputImages.push(outputImage)
|
||||
this.pathToViewerImage[path] = outputImage //
|
||||
return outputImage
|
||||
}
|
||||
addInitImage(group, snapshot, solid_background, path, auto_delete) {
|
||||
const initImage = new InitImage(
|
||||
group,
|
||||
snapshot,
|
||||
solid_background,
|
||||
path,
|
||||
this
|
||||
)
|
||||
initImage.setAutoDelete(auto_delete)
|
||||
this.initImages.push(initImage)
|
||||
this.pathToViewerImage[path] = initImage
|
||||
return initImage
|
||||
}
|
||||
addMask(group, white_mark, solid_background, path) {
|
||||
const mask = new InitMaskImage(
|
||||
group,
|
||||
white_mark,
|
||||
solid_background,
|
||||
path,
|
||||
this
|
||||
)
|
||||
|
||||
this.initMaskImage = mask
|
||||
this.pathToViewerImage[path] = mask
|
||||
return mask
|
||||
}
|
||||
|
||||
scaleThumbnails(
|
||||
original_width,
|
||||
original_height,
|
||||
min_width,
|
||||
min_height,
|
||||
scaler
|
||||
) {
|
||||
//calculate the new width and height
|
||||
|
||||
const image_width = this.isSquareThumbnail
|
||||
? 100
|
||||
: g_generation_session.last_settings.width
|
||||
const image_height = this.isSquareThumbnail
|
||||
? 100
|
||||
: g_generation_session.last_settings.height
|
||||
|
||||
const [new_width, new_height] = general.scaleToClosestKeepRatio(
|
||||
image_width,
|
||||
image_height,
|
||||
100,
|
||||
100
|
||||
)
|
||||
const [scaled_width, scaled_height] = [
|
||||
new_width * scaler,
|
||||
new_height * scaler,
|
||||
]
|
||||
|
||||
for (let outputImage of this.outputImages) {
|
||||
//get the image and it's container
|
||||
const img = outputImage.img_html
|
||||
const img_container = img.parentElement
|
||||
|
||||
img_container.style.width = scaled_width
|
||||
img_container.style.height = scaled_height
|
||||
img.style.width = scaled_width
|
||||
img.style.height = scaled_height
|
||||
//scale them to the new dimensions
|
||||
}
|
||||
}
|
||||
onSessionEnd() {
|
||||
this.outputImages = []
|
||||
this.initImages = []
|
||||
this.initMaskImage = null
|
||||
|
||||
this.pathToViewerImage = {} // quick way to check if an link image path on disk to ViewerImage object.
|
||||
this.initImageLayersJson = {} //{path: initImageLayers}
|
||||
|
||||
this.selectedOutputImages = {} //store the selected output images {path: outputImage}
|
||||
|
||||
this.mask_layer = null
|
||||
this.maskLayersJson = {} //{path: MaskLayers}
|
||||
|
||||
//Note:move initGroup, to GenerationSession
|
||||
this.initGroup = null
|
||||
this.init_solid_background = null
|
||||
this.maskGroup = null
|
||||
this.mask_solid_background = null
|
||||
|
||||
//last_selected_obj
|
||||
this.last_selected_viewer_obj = null
|
||||
// this.thumbnail_scaler = 1
|
||||
// this.isSquareThumbnail = false
|
||||
}
|
||||
|
||||
async loadInitImageViewerObject(path) {
|
||||
if (!g_viewer_manager.hasViewerImage(path)) {
|
||||
const group = this.initImageLayersJson[path].group
|
||||
const snapshot = this.initImageLayersJson[path].snapshot
|
||||
const solid_background =
|
||||
this.initImageLayersJson[path].solid_background
|
||||
const auto_delete = this.initImageLayersJson[path].autoDelete
|
||||
const base64_image = g_generation_session.base64initImages[path]
|
||||
await loadInitImageViewerObject(
|
||||
group,
|
||||
snapshot,
|
||||
solid_background,
|
||||
path,
|
||||
auto_delete,
|
||||
base64_image
|
||||
)
|
||||
}
|
||||
}
|
||||
deleteAll() {}
|
||||
keepAll() {}
|
||||
keepSelected() {}
|
||||
deleteSelected() {}
|
||||
deleteInitImages() {}
|
||||
deleteMask() {}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
OutputImage,
|
||||
InitImage,
|
||||
InitMaskImage,
|
||||
ViewerObjState,
|
||||
ViewerManager,
|
||||
}
|
||||
Loading…
Reference in New Issue