...
 
Commits (5)
    https://gitcode.net/ranting8323/Auto-Photoshop-StableDiffusion-Plugin/-/commit/c1137537c301b7cd87088675f719058f5133ce65 Store `comfy_url` in Photoshop local storage 2023-11-19T02:57:37+03:00 Abdullah Alfaraj 7842232+AbdullahAlfaraj@users.noreply.github.com https://gitcode.net/ranting8323/Auto-Photoshop-StableDiffusion-Plugin/-/commit/3fd3a4fc9d2bc28394f3a2c62297fb8189ede4e7 Display error to the user if comfyui api failed to get object info 2023-11-19T03:02:51+03:00 Abdullah Alfaraj 7842232+AbdullahAlfaraj@users.noreply.github.com https://gitcode.net/ranting8323/Auto-Photoshop-StableDiffusion-Plugin/-/commit/8d73846cbf2abb9f686e77e4a58ba36706ddad19 enable hires fix in all comfyui modes 2023-11-19T03:03:43+03:00 Abdullah Alfaraj 7842232+AbdullahAlfaraj@users.noreply.github.com https://gitcode.net/ranting8323/Auto-Photoshop-StableDiffusion-Plugin/-/commit/32e775cf2b13aa7bd798ef4e9ddbf3757a07cf67 support batch size in inpaint mode 2023-11-19T03:05:52+03:00 Abdullah Alfaraj 7842232+AbdullahAlfaraj@users.noreply.github.com https://gitcode.net/ranting8323/Auto-Photoshop-StableDiffusion-Plugin/-/commit/b611e09bc30866ad8de654e5689c4a50d382ee0f reuse uploaded images and only upload if it's a new image 2023-11-19T03:09:31+03:00 Abdullah Alfaraj 7842232+AbdullahAlfaraj@users.noreply.github.com
import { app } from 'photoshop'
import settings_tab from '../settings/settings'
import { requestGet, requestPost } from '../util/ts/api'
import { base64UrlToBase64 } from '../util/ts/general'
......@@ -20,12 +21,21 @@ export interface ComfyResult {
class ComfyAPI {
private object_info: Record<string, any> = {}
comfy_url: string
status: boolean = false
constructor(comfy_url: string) {
this.comfy_url = comfy_url
}
async init() {
this.object_info = await this.getObjectInfo(this.comfy_url)
return this.object_info
try {
this.object_info = await this.getObjectInfo(this.comfy_url)
this.status = true
return this.object_info
} catch (e) {
console.error(e)
app.showAlert(`${e}`)
this.status = false
}
}
setUrl(comfy_url: string) {
this.comfy_url = comfy_url
......@@ -74,10 +84,14 @@ class ComfyAPI {
async getObjectInfo(comfy_url: string) {
try {
const object_info = await requestGet(`${comfy_url}/object_info`)
const full_url = `${comfy_url}/object_info`
const object_info = await requestGet(full_url)
if (!object_info)
throw `can not request from comfyui url: ${comfy_url}`
return object_info
} catch (e) {
console.error(e)
throw e
}
}
getReadableError(result: ComfyResult): string {
......
......@@ -9,7 +9,7 @@
"cfg": 7,
"sampler_name": "euler_ancestral",
"scheduler": "karras",
"denoise": 1,
"denoise": 0.71,
"model": [
"76",
0
......@@ -23,7 +23,7 @@
4
],
"latent_image": [
"135",
"160",
0
]
},
......@@ -130,7 +130,7 @@
},
"16": {
"inputs": {
"ckpt_name": "dreamshaper_8Inpainting.safetensors"
"ckpt_name": "aniverse_v15Pruned.safetensors"
},
"class_type": "CheckpointLoaderSimple"
},
......@@ -153,7 +153,7 @@
},
"58": {
"inputs": {
"image": "pasted/image (13).png",
"image": "04b380cb676f37e52d5963a0982edd5e.jpg",
"choose file to upload": "image"
},
"class_type": "LoadImage"
......@@ -188,7 +188,7 @@
},
"83": {
"inputs": {
"image": "pasted/image (14).png",
"image": "pasted/image (4).png",
"choose file to upload": "image"
},
"class_type": "LoadImage"
......@@ -207,7 +207,7 @@
},
"135": {
"inputs": {
"content_mask": "latent_nothing",
"content_mask": "original",
"width": [
"126",
0
......@@ -237,7 +237,7 @@
},
"141": {
"inputs": {
"seed": 370804183246305
"seed": 519416762507340
},
"class_type": "APS_Seed"
},
......@@ -325,5 +325,15 @@
]
},
"class_type": "ControlNetScript"
},
"160": {
"inputs": {
"amount": 1,
"samples": [
"135",
0
]
},
"class_type": "RepeatLatentBatch"
}
}
\ No newline at end of file
{
"last_node_id": 159,
"last_link_id": 304,
"last_node_id": 160,
"last_link_id": 306,
"nodes": [
{
"id": 13,
......@@ -14,7 +14,7 @@
"1": 46
},
"flags": {},
"order": 35,
"order": 36,
"mode": 0,
"inputs": [
{
......@@ -200,7 +200,7 @@
"1": 46
},
"flags": {},
"order": 32,
"order": 33,
"mode": 0,
"inputs": [
{
......@@ -277,7 +277,7 @@
"1": 82
},
"flags": {},
"order": 31,
"order": 32,
"mode": 0,
"inputs": [
{
......@@ -318,7 +318,7 @@
"1": 474
},
"flags": {},
"order": 33,
"order": 34,
"mode": 0,
"inputs": [
{
......@@ -553,79 +553,6 @@
"Node name for S&R": "PreviewImage"
}
},
{
"id": 141,
"type": "APS_Seed",
"pos": [
359,
532
],
"size": {
"0": 361.20001220703125,
"1": 82
},
"flags": {},
"order": 1,
"mode": 0,
"outputs": [
{
"name": "s",
"type": "INT",
"links": [
259,
260
],
"shape": 3,
"slot_index": 0
}
],
"title": "Auto-Photoshop-SD Seed | id:first_pass_seed",
"properties": {
"Node name for S&R": "APS_Seed"
},
"widgets_values": [
248827423249163,
"randomize"
]
},
{
"id": 121,
"type": "Reroute",
"pos": [
2069,
410
],
"size": [
90.4,
26
],
"flags": {},
"order": 21,
"mode": 0,
"inputs": [
{
"name": "",
"type": "*",
"link": 290
}
],
"outputs": [
{
"name": "LATENT",
"type": "LATENT",
"links": [
217
],
"slot_index": 0
}
],
"properties": {
"showOutputText": true,
"horizontal": false
},
"color": "#223",
"bgcolor": "#335"
},
{
"id": 148,
"type": "PreviewImage",
......@@ -663,7 +590,7 @@
"1": 106
},
"flags": {},
"order": 2,
"order": 1,
"mode": 0,
"outputs": [
{
......@@ -854,7 +781,7 @@
"1": 282.4336242675781
},
"flags": {},
"order": 34,
"order": 35,
"mode": 0,
"inputs": [
{
......@@ -869,33 +796,6 @@
"ComfyUI"
]
},
{
"id": 12,
"type": "SaveImage",
"pos": [
3162,
1131
],
"size": {
"0": 407.53717041015625,
"1": 468.13226318359375
},
"flags": {},
"order": 36,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 17
}
],
"title": "Save Image | id:hires_output",
"properties": {},
"widgets_values": [
"ComfyUI"
]
},
{
"id": 126,
"type": "Integer",
......@@ -908,7 +808,7 @@
"1": 58
},
"flags": {},
"order": 3,
"order": 2,
"mode": 0,
"outputs": [
{
......@@ -941,7 +841,7 @@
"1": 58
},
"flags": {},
"order": 4,
"order": 3,
"mode": 0,
"outputs": [
{
......@@ -974,7 +874,7 @@
"1": 98
},
"flags": {},
"order": 5,
"order": 4,
"mode": 0,
"outputs": [
{
......@@ -1021,7 +921,7 @@
"1": 678
},
"flags": {},
"order": 26,
"order": 27,
"mode": 0,
"inputs": [
{
......@@ -1278,7 +1178,7 @@
"1": 314
},
"flags": {},
"order": 6,
"order": 5,
"mode": 0,
"outputs": [
{
......@@ -1319,7 +1219,7 @@
"1": 314
},
"flags": {},
"order": 7,
"order": 6,
"mode": 0,
"outputs": [
{
......@@ -1350,82 +1250,174 @@
]
},
{
"id": 157,
"type": "PreviewImage",
"id": 3,
"type": "KSampler",
"pos": [
-610,
-240
757,
831
],
"size": {
"0": 336,
"1": 246
"0": 315,
"1": 446
},
"flags": {},
"order": 28,
"mode": 2,
"order": 31,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 292
"name": "model",
"type": "MODEL",
"link": 263
},
{
"name": "positive",
"type": "CONDITIONING",
"link": 298,
"slot_index": 1
},
{
"name": "negative",
"type": "CONDITIONING",
"link": 299
},
{
"name": "latent_image",
"type": "LATENT",
"link": 306
},
{
"name": "seed",
"type": "INT",
"link": 260,
"widget": {
"name": "seed"
}
}
],
"title": "Preview Image | id:preprocessor_output_2",
"outputs": [
{
"name": "LATENT",
"type": "LATENT",
"links": [
78,
278
],
"slot_index": 0
}
],
"title": "KSampler | id:sampler",
"properties": {
"Node name for S&R": "PreviewImage"
}
"Node name for S&R": "KSampler"
},
"widgets_values": [
109789101278740,
"randomize",
20,
7,
"euler_ancestral",
"karras",
0.71
]
},
{
"id": 156,
"type": "PreviewImage",
"id": 12,
"type": "SaveImage",
"pos": [
-860,
-240
3162,
1131
],
"size": {
"0": 336,
"1": 246
"0": 407.53717041015625,
"1": 468.13226318359375
},
"flags": {},
"order": 27,
"mode": 2,
"order": 37,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 291
"link": 17
}
],
"title": "Preview Image | id:preprocessor_output_1",
"properties": {
"Node name for S&R": "PreviewImage"
}
"title": "Save Image | id:hires_output",
"properties": {},
"widgets_values": [
"ComfyUI"
]
},
{
"id": 158,
"type": "PreviewImage",
"id": 141,
"type": "APS_Seed",
"pos": [
-370,
-240
359,
532
],
"size": {
"0": 336,
"1": 246
"0": 361.20001220703125,
"1": 82
},
"flags": {},
"order": 29,
"mode": 2,
"order": 7,
"mode": 0,
"outputs": [
{
"name": "s",
"type": "INT",
"links": [
259,
260
],
"shape": 3,
"slot_index": 0
}
],
"title": "Auto-Photoshop-SD Seed | id:first_pass_seed",
"properties": {
"Node name for S&R": "APS_Seed"
},
"widgets_values": [
519416762507340,
"fixed"
]
},
{
"id": 121,
"type": "Reroute",
"pos": [
2069,
410
],
"size": [
90.4,
26
],
"flags": {},
"order": 21,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 293
"name": "",
"type": "*",
"link": 290
}
],
"outputs": [
{
"name": "LATENT",
"type": "LATENT",
"links": [
305
],
"slot_index": 0
}
],
"title": "Preview Image | id:preprocessor_output_3",
"properties": {
"Node name for S&R": "PreviewImage"
}
"showOutputText": true,
"horizontal": false
},
"color": "#223",
"bgcolor": "#335"
},
{
"id": 135,
......@@ -1530,53 +1522,29 @@
"original",
512,
768,
771262702963796,
933689295201272,
"randomize"
]
},
{
"id": 3,
"type": "KSampler",
"id": 160,
"type": "RepeatLatentBatch",
"pos": [
757,
831
1752,
517
],
"size": {
"0": 315,
"1": 446
"1": 58
},
"flags": {},
"order": 30,
"order": 26,
"mode": 0,
"inputs": [
{
"name": "model",
"type": "MODEL",
"link": 263
},
{
"name": "positive",
"type": "CONDITIONING",
"link": 298,
"slot_index": 1
},
{
"name": "negative",
"type": "CONDITIONING",
"link": 299
},
{
"name": "latent_image",
"name": "samples",
"type": "LATENT",
"link": 217
},
{
"name": "seed",
"type": "INT",
"link": 260,
"widget": {
"name": "seed"
}
"link": 305
}
],
"outputs": [
......@@ -1584,25 +1552,97 @@
"name": "LATENT",
"type": "LATENT",
"links": [
78,
278
306
],
"shape": 3,
"slot_index": 0
}
],
"title": "KSampler | id:sampler",
"title": "Repeat Latent Batch | id:latent_batch",
"properties": {
"Node name for S&R": "KSampler"
"Node name for S&R": "RepeatLatentBatch"
},
"widgets_values": [
574883933962509,
"randomize",
20,
7,
"euler_ancestral",
"karras",
0.71
1
]
},
{
"id": 157,
"type": "PreviewImage",
"pos": [
-610,
-240
],
"size": {
"0": 336,
"1": 246
},
"flags": {},
"order": 29,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 292
}
],
"title": "Preview Image | id:preprocessor_output_2",
"properties": {
"Node name for S&R": "PreviewImage"
}
},
{
"id": 158,
"type": "PreviewImage",
"pos": [
-370,
-240
],
"size": {
"0": 336,
"1": 246
},
"flags": {},
"order": 30,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 293
}
],
"title": "Preview Image | id:preprocessor_output_3",
"properties": {
"Node name for S&R": "PreviewImage"
}
},
{
"id": 156,
"type": "PreviewImage",
"pos": [
-860,
-240
],
"size": {
"0": 336,
"1": 246
},
"flags": {},
"order": 28,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 291
}
],
"title": "Preview Image | id:preprocessor_output_1",
"properties": {
"Node name for S&R": "PreviewImage"
}
}
],
"links": [
......@@ -1798,14 +1838,6 @@
0,
"*"
],
[
217,
121,
0,
3,
3,
"LATENT"
],
[
247,
115,
......@@ -2021,6 +2053,22 @@
159,
3,
"IMAGE"
],
[
305,
121,
0,
160,
0,
"LATENT"
],
[
306,
160,
0,
3,
3,
"LATENT"
]
],
"groups": [
......
......@@ -4,8 +4,8 @@ import txt2img_api from './txt2img_api_v0.0.6.json'
import img2img from './img2img_workflow_v0.0.6.json'
import img2img_api from './img2img_api_v0.0.6.json'
import inpaint from './inpaint_workflow_v0.0.10.json'
import inpaint_api from './inpaint_api_v0.0.10.json'
import inpaint from './inpaint_workflow.json'
import inpaint_api from './inpaint_api.json'
import vae_settings from '../settings/vae'
import sd_tab_util from '../sd_tab/util'
......@@ -15,6 +15,7 @@ import { store } from './util'
import { base64UrlToBase64, copyJson } from '../util/ts/general'
import { session_store } from '../stores'
import ControlNetStore from '../controlnet/store'
// Function to parse metadata from a title string
function parseMetadata(title: string) {
......@@ -196,7 +197,7 @@ const inpaint_map: Record<string, any> = {
vae: 'vae.vae_name',
width: 'width.Value',
height: 'height.Value',
// batch_size: 'latent_batch.amount',
batch_size: 'latent_batch.amount',
// prompt: 'positive_prompt.text',
prompt: 'multi_loras_positive_prompt.prompt',
negative_prompt: 'multi_loras_negative_prompt.prompt',
......@@ -223,15 +224,14 @@ const inpaint_map: Record<string, any> = {
// hr_scheduler: 'normal',
hr_denoising_strength: 'hires_sampler.denoise',
}
async function addMissingSettings(plugin_settings: Record<string, any>) {
plugin_settings['vae'] = vae_settings.store.data.current_vae
plugin_settings['model'] = sd_tab_util.store.data.selected_model
plugin_settings['hr_denoising_strength'] =
sd_tab_util.store.data.hr_denoising_strength
plugin_settings['hr_sampler_name'] = sd_tab_util.store.data.sampler_name // use the same sampler for the first and second pass (hires) upscale sampling steps
if ('init_images' in plugin_settings) {
const base64 = plugin_settings['init_images'][0]
async function reuseOrUploadComfyImage(
base64: string,
all_uploaded_images: Record<string, any>
) {
let image_name: string = ''
if (all_uploaded_images[base64]) {
image_name = all_uploaded_images[base64]
} else {
const new_loaded_image = await util.uploadImage(false, base64)
console.log('new_loaded_image: ', new_loaded_image)
if (new_loaded_image) {
......@@ -239,20 +239,33 @@ async function addMissingSettings(plugin_settings: Record<string, any>) {
...store.data.uploaded_images_list,
new_loaded_image.name,
]
plugin_settings['init_image'] = new_loaded_image.name
image_name = new_loaded_image.name
all_uploaded_images[base64] = new_loaded_image.name
}
}
return image_name
}
async function addMissingSettings(plugin_settings: Record<string, any>) {
plugin_settings['vae'] = vae_settings.store.data.current_vae
plugin_settings['model'] = sd_tab_util.store.data.selected_model
plugin_settings['hr_denoising_strength'] =
sd_tab_util.store.data.hr_denoising_strength
plugin_settings['hr_sampler_name'] = sd_tab_util.store.data.sampler_name // use the same sampler for the first and second pass (hires) upscale sampling steps
if ('init_images' in plugin_settings) {
const base64 = plugin_settings['init_images'][0]
plugin_settings['init_image'] = await reuseOrUploadComfyImage(
base64,
store.data.base64_to_uploaded_images_names
)
}
if ('mask' in plugin_settings) {
const base64 = plugin_settings['mask']
const new_loaded_image = await util.uploadImage(false, base64)
console.log('new_loaded_image: ', new_loaded_image)
if (new_loaded_image) {
store.data.uploaded_images_list = [
...store.data.uploaded_images_list,
new_loaded_image.name,
]
plugin_settings['comfy_mask'] = new_loaded_image.name
}
plugin_settings['comfy_mask'] = await reuseOrUploadComfyImage(
base64,
store.data.base64_to_uploaded_images_names
)
}
//calculate positive random seed if seed is -1
......@@ -275,35 +288,31 @@ async function addMissingSettings(plugin_settings: Record<string, any>) {
async function addMissingControlnetSettings(
plugin_settings: Record<string, any>
) {
plugin_settings['disableControlNetTab'] =
ControlNetStore.disableControlNetTab
for (const unit of plugin_settings['controlnet_units']) {
unit['comfy_enabled'] = unit.enabled ? 'enable' : 'disable'
unit['comfy_enabled'] =
!plugin_settings['disableControlNetTab'] && unit.enabled
? 'enable'
: 'disable'
unit['comfy_input_image'] = ''
unit['comfy_mask'] = ''
if ('input_image' in unit && unit['input_image'] !== '') {
const base64 = unit['input_image']
const new_loaded_image = await util.uploadImage(false, base64)
console.log('new_loaded_image: ', new_loaded_image)
if (new_loaded_image) {
store.data.uploaded_images_list = [
...store.data.uploaded_images_list,
new_loaded_image.name,
]
unit['comfy_input_image'] = new_loaded_image.name
}
unit['comfy_input_image'] = await reuseOrUploadComfyImage(
base64,
store.data.base64_to_uploaded_images_names
)
}
if ('mask' in unit && unit['mask'] !== '') {
//if mask have been set manually
const base64 = unit['mask']
const new_loaded_image = await util.uploadImage(false, base64)
console.log('new_loaded_image: ', new_loaded_image)
if (new_loaded_image) {
store.data.uploaded_images_list = [
...store.data.uploaded_images_list,
new_loaded_image.name,
]
unit['comfy_mask'] = new_loaded_image.name
}
unit['comfy_mask'] = await reuseOrUploadComfyImage(
base64,
store.data.base64_to_uploaded_images_names
)
} else if ('comfy_mask' in plugin_settings) {
// use the mask from the main ui (inpaint and outpaint mode)
......
......@@ -84,6 +84,8 @@ export const store = new AStore({
progress_value: 0,
is_random_seed: {} as Record<string, boolean>,
last_moved: undefined as string | undefined, // the last node that has been moved in the edit mode
base64_to_uploaded_images_names: {} as Record<string, any>,
})
interface Workflow {}
......
......@@ -38,6 +38,8 @@ import {
onHeightSliderInput,
heightSliderOnChangeEventHandler,
loadPresetSettings,
isHiResMode,
} from './util'
import { general } from '../util/oldSystem'
import { requestSwapModel, setInpaintMaskWeight } from '../util/ts/sdapi'
......@@ -1103,11 +1105,7 @@ class SDTab extends React.Component<{}> {
class="checkbox"
id="chHiResFixs"
style={{
display: [ScriptMode.Txt2Img].includes(
store.data.rb_mode
)
? 'flex'
: 'none',
display: isHiResMode() ? 'flex' : 'none',
}}
checked={store.data.enable_hr}
onClick={(evt: any) => {
......@@ -1131,9 +1129,7 @@ class SDTab extends React.Component<{}> {
id="HiResDiv"
style={{
display:
[ScriptMode.Txt2Img].includes(
store.data.rb_mode
) && store.data.enable_hr
isHiResMode() && store.data.enable_hr
? void 0
: 'none',
}}
......
......@@ -714,6 +714,20 @@ export function loadPresetSettings(preset: any) {
// io_ts.presetToStore(preset?.controlnet_tab_preset, store)
}
}
export function isHiResMode() {
let is_hi_res_mode = false
if (settings_tab_ts.store.data.selected_backend === 'Automatic1111') {
is_hi_res_mode = [ScriptMode.Txt2Img].includes(store.data.rb_mode)
} else if (settings_tab_ts.store.data.selected_backend === 'ComfyUI') {
is_hi_res_mode = [
ScriptMode.Txt2Img,
ScriptMode.Img2Img,
ScriptMode.Inpaint,
ScriptMode.Outpaint,
].includes(store.data.rb_mode)
}
return is_hi_res_mode
}
export default {
store: store,
......
......@@ -102,7 +102,8 @@ export const store = new AStore<AStoreData>({
use_smart_object: true, // true to keep layer as smart objects, false to rasterize them
// selected_backend: 'Automatic1111' as 'Automatic1111' | 'ComfyUI',
selected_backend: 'ComfyUI' as 'Automatic1111' | 'ComfyUI',
comfy_url: 'http://127.0.0.1:8188',
comfy_url:
storage.localStorage.getItem('comfy_url') || 'http://127.0.0.1:8188',
})
function onShouldLogToFileChange(event: any) {
......@@ -189,11 +190,16 @@ export class Settings extends React.Component<{}> {
value={store.data.comfy_url}
onChange={(event: any) => {
// store.data.search_query = event.target.value
let url = event.target.value
let url = event.target.value.trim() // remove leading and trailing white spaces
url = url.replace(/[/\\]$/, '')
console.log(url)
store.data.comfy_url = url
comfyapi.comfy_api.setUrl(store.data.comfy_url)
storage.localStorage.setItem(
'comfy_url',
store.data.comfy_url
)
}}
></SpTextfield>
<sp-radio-group>
......