Merge pull request #267 from AbdullahAlfaraj/dev_v1.2.5

merge v1.2.5
pull/284/head
Abdullah Alfaraj 2023-05-23 19:03:06 +03:00 committed by GitHub
commit bb375f4839
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 7778 additions and 11 deletions

7
.gitignore vendored
View File

@ -6,6 +6,8 @@ env
/log
/.idea
/.vscode
/.git
/.github
test.bat
server/python_server/output/*
server/python_server/init_images/*
@ -25,3 +27,8 @@ original_mask.png
/jimp/browser/*.md
/jimp/browser/*.editorconfig
/jimp/browser/lib/jimp.js
# comments when packaging:
ultimate_sd_upscaler/dist/*LICENSE.txt
ultimate_sd_upscaler/dist/*.bundle.js

View File

@ -2293,6 +2293,70 @@ l32 44 -47 62 c-67 90 -253 281 -358 368 -248 208 -538 351 -802 397 -90 16
</svg>
</div>
</sp-action-button>
<sp-action-button
id="svg_sp_btn_expand"
style="
padding: 0;
max-width: 32px;
max-height: 32px;
display: none;
"
>
<div slot="icon" style="fill: currentColor">
<svg
version="1.0"
xmlns="http://www.w3.org/2000/svg"
width="200.000000pt"
height="200.000000pt"
viewBox="0 0 200.000000 200.000000"
preserveAspectRatio="xMidYMid meet"
style="
width: 28px;
height: 32px;
position: absolute;
top: -1px;
left: 1px;
"
>
<g
transform="translate(0.000000,200.000000) scale(0.100000,-0.100000)"
fill="#000000"
stroke="none"
>
<path
d="M246 1775 c-11 -6 -23 -21 -27 -35 -9 -31 -9 -275 0 -315 9 -41 50
-61 89 -43 26 13 27 17 30 97 l3 84 178 -176 c123 -123 184 -177 200 -177 12
0 33 11 46 25 14 13 25 34 25 46 0 16 -54 77 -177 200 l-176 178 84 3 c80 3
84 4 97 31 11 22 11 32 0 55 l-13 27 -170 5 c-104 3 -177 1 -189 -5z"
/>
<path
d="M1406 1775 c-32 -16 -43 -58 -22 -89 16 -26 18 -26 146 -26 l129 0 3
-132 3 -133 28 -13 c22 -11 32 -11 55 0 l27 13 3 179 c2 120 -1 183 -9 192
-14 17 -332 25 -363 9z"
/>
<path
d="M1515 1600 c-11 -4 -84 -73 -162 -152 -153 -155 -162 -170 -118 -213
43 -44 58 -36 219 124 132 131 149 153 149 181 0 22 -7 39 -22 52 -25 20 -36
21 -66 8z"
/>
<path
d="M700 783 c-8 -3 -93 -82 -187 -177 l-173 -171 0 82 c0 78 -2 84 -26
99 -32 22 -73 10 -92 -26 -18 -35 -13 -330 7 -354 12 -14 36 -16 195 -14 l181
3 13 28 c11 22 11 32 0 55 -13 26 -17 27 -98 30 l-84 3 174 174 c153 153 173
177 173 206 0 47 -40 77 -83 62z"
/>
<path
d="M1252 780 c-28 -12 -45 -52 -33 -82 5 -13 84 -97 175 -188 l166 -165
-82 -5 c-78 -5 -84 -6 -96 -33 -11 -22 -11 -32 0 -55 l13 -27 181 -3 c146 -2
183 0 193 12 8 9 11 67 9 192 l-3 178 -28 16 c-24 13 -30 13 -55 0 -26 -15
-27 -20 -30 -100 l-3 -84 -172 171 c-95 94 -181 173 -192 176 -11 3 -30 1 -43
-3z"
/>
</g>
</svg>
</div>
</sp-action-button>
</div>
<img
id="webp_container"
@ -2938,6 +3002,9 @@ l32 44 -47 62 c-67 90 -253 281 -358 368 -248 208 -538 351 -802 397 -90 16
>
</sp-radio-group>
</div>
<sp-divider class="line-divider" size="large"></sp-divider>
<sp-divider class="line-divider" size="large"></sp-divider>
<div id="scriptsContainer"></div>
</div>
</div>
</div>

View File

@ -36,7 +36,7 @@ if (should_log) {
// helloHelper2 = require('./helper.js')
// for organizational proposes
// let g_sdapi_path = 'sdapi'
let g_version = 'v1.2.4'
let g_version = 'v1.2.5'
let g_sd_url = 'http://127.0.0.1:7860'
let g_online_data_url =
'https://raw.githubusercontent.com/AbdullahAlfaraj/Auto-Photoshop-StableDiffusion-Plugin/master/utility/online_data.json'
@ -86,6 +86,17 @@ const history_tab = require('./utility/tab/history_tab')
const image_search_tab = require('./utility/tab/image_search_tab')
const lexica_tab = require('./utility/tab/lexica_tab')
const share_tab = require('./utility/tab/share_tab')
// const ultimate_sd_upscaler = require('./ultimate_sd_upscaler/dist/ultimate_sd_upscaler')
const ultimate_sd_upscaler_script = require('./ultimate_sd_upscaler/dist/ultimate_sd_upscaler.bundle')
const scripts = require('./ultimate_sd_upscaler/dist/scripts.bundle')
// const ultimate_sd_upscaler_script_test = require('./ultimate_sd_upscaler/dist/main')
// const {
// script_args,
// script_name,
// } = require('./ultimate_sd_upscaler/dist/ultimate_sd_upscaler')
let g_horde_generator = new horde_native.hordeGenerator()
let g_automatic_status = Enum.AutomaticStatusEnum['Offline']
let g_models_status = false
@ -778,6 +789,7 @@ for (let rbModeElement of rbModeElements) {
rbModeElement.addEventListener('click', async (evt) => {
try {
g_sd_mode = evt.target.value
scripts.script_store.setMode(g_sd_mode)
// console.log(`You clicked: ${g_sd_mode}`)
await displayUpdate()
await postModeSelection() // do things after selection
@ -1989,6 +2001,20 @@ async function getSettings() {
g_generation_session.activeBase64InitImage,
]
payload['image_cfg_scale'] = sd_tab.getImageCfgScaleSDValue() // we may need to check if model is pix2pix
if (
scripts.script_store.is_active &&
scripts.script_store.selected_script_name !== 'None' &&
scripts.script_store.is_selected_script_available
) {
payload['script_args'] = scripts.script_store.orderedValues()
payload['script_name'] =
scripts.script_store.selected_script_name //'Ultimate SD upscale'
}
} else {
delete payload['script_args']
delete payload['script_name']
}
if (hi_res_fix && width >= 512 && height >= 512) {
@ -2027,7 +2053,10 @@ async function getSettings() {
if (backend_type === backendTypeEnum['Auto1111HordeExtension']) {
payload['script_name'] = script_horde.script_name
payload['script_args'] = script_horde.getScriptArgs()
} else {
} else if (
payload['script_name'] === script_horde.script_name &&
backend_type !== backendTypeEnum['Auto1111HordeExtension']
) {
delete payload['script_name']
delete payload['script_args']
}

View File

@ -41,7 +41,7 @@ if auto_update:
# print("Auto-Photoshop-SD plugin is installing")
package_name = 'duckduckgo_search'
package_version= '2.9.5'
package_version= '3.0.2'
if not launch.is_installed(package_name):
launch.run_pip(f"install {package_name}=={package_version}", "requirements for Auto-Photoshop Image Search")
else:# it's installed but we need to check for update

6578
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -5,19 +5,43 @@
"author": "Adobe Inc",
"license": "Apache-2.0",
"dependencies": {
"@types/react": "^18.2.6",
"@types/react-dom": "^18.2.4",
"fastify": "^4.10.2",
"jimp": "^0.16.2",
"md5": "^2.3.0"
"md5": "^2.3.0",
"mobx": "^6.9.0",
"mobx-react": "^7.6.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"main": "index.js",
"directories": {
"test": "test"
},
"devDependencies": {
"prettier": "2.8.3"
"@babel/core": "^7.21.8",
"@babel/plugin-proposal-object-rest-spread": "^7.20.7",
"@babel/plugin-syntax-class-properties": "^7.12.13",
"@babel/plugin-transform-react-jsx": "^7.21.5",
"babel-loader": "^9.1.2",
"clean-webpack-plugin": "^4.0.0",
"copy-webpack-plugin": "^11.0.0",
"css-loader": "^6.7.3",
"file-loader": "^6.2.0",
"nodemon": "^2.0.22",
"prettier": "2.8.3",
"style-loader": "^3.3.2",
"terser-webpack-plugin": "^3.0.8",
"ts-loader": "^9.4.2",
"typescript": "^5.0.4",
"webpack": "^5.82.1",
"webpack-cli": "^5.1.1"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "echo \"Error: no test specified\" && exit 1",
"build": "cd ultimate_sd_upscaler && npx webpack --config webpack.config.js",
"watch": "cd ultimate_sd_upscaler && npx webpack --config webpack.config.js --watch"
},
"repository": {
"type": "git",

View File

@ -603,7 +603,12 @@ async function requestControlNetTxt2Img(plugin_settings) {
app.showAlert('you need to select a valid ControlNet Module')
throw 'you need to select a valid ControlNet Module'
}
if (!control_net_settings['controlnet_units'][index]['model']) {
if (
!control_net_settings['controlnet_units'][index]['model'] &&
!control_net.getModuleDetail()[
control_net_settings['controlnet_units'][index]['module']
].model_free
) {
app.showAlert('you need to select a valid ControlNet Model')
throw 'you need to select a valid ControlNet Model'
}
@ -684,7 +689,12 @@ async function requestControlNetImg2Img(plugin_settings) {
app.showAlert('you need to select a valid ControlNet Module')
throw 'you need to select a valid ControlNet Module'
}
if (!control_net_settings['controlnet_units'][index]['model']) {
if (
!control_net_settings['controlnet_units'][index]['model'] &&
!control_net.getModuleDetail()[
control_net_settings['controlnet_units'][index]['module']
].model_free
) {
app.showAlert('you need to select a valid ControlNet Model')
throw 'you need to select a valid ControlNet Model'
}
@ -709,6 +719,15 @@ async function requestControlNetImg2Img(plugin_settings) {
numOfImages - g_generation_session.last_settings.batch_size
if (numberOfAnnotations < 0) numberOfAnnotations = 0
// To fix a bug: when Ultimate SD Upscale is active and running, the detection maps wont be retrieved.
// So set its value to 0 to avoid the result images being loaded in the annotation map interface.
if (
scripts.script_store.is_active &&
scripts.script_store.selected_script_name !== 'None' &&
scripts.script_store.is_selected_script_available
) {
numberOfAnnotations = 0
}
const base64_mask = json['images'].slice(numOfImages - numberOfAnnotations)
let mask_index = 0

1
ultimate_sd_upscaler/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
# dist/*.bundle.js

View File

@ -0,0 +1,134 @@
export let ui_config = {
tile_width: {
minimum: 0,
maximum: 2048,
step: 64,
label: 'Tile width',
value: 512,
},
tile_height: {
minimum: 0,
maximum: 2048,
step: 64,
label: 'Tile height',
value: 0,
},
mask_blur: {
minimum: 0,
maximum: 64,
step: 1,
label: 'Mask blur',
value: 8,
},
padding: { minimum: 0, maximum: 128, step: 1, label: 'Padding', value: 32 },
seams_fix_denoise: {
label: 'Denoise',
minimum: 0,
maximum: 1,
step: 0.01,
value: 0.35,
visible: false,
interactive: true,
},
seams_fix_width: {
label: 'Width',
minimum: 0,
maximum: 128,
step: 1,
value: 64,
visible: false,
interactive: true,
},
seams_fix_mask_blur: {
label: 'Mask blur',
minimum: 0,
maximum: 64,
step: 1,
value: 4,
visible: false,
interactive: true,
},
seams_fix_padding: {
label: 'Padding',
minimum: 0,
maximum: 128,
step: 1,
value: 16,
visible: false,
interactive: true,
},
redraw_mode: {
label: 'Type',
choices: ['Linear', 'Chess', 'None'],
type: 'index',
value: 0,
},
save_upscaled_image: {
label: 'Upscaled',
value: true,
},
save_seams_fix_image: {
label: 'Seams fix',
value: false,
},
seams_fix_type: {
label: 'Type',
choices: [
'None',
'Band pass',
'Half tile offset pass',
'Half tile offset pass + intersections',
],
type: 'index',
value: 3,
},
target_size_type: {
label: 'Target size type',
choices: [
'From img2img2 settings',
'Custom size',
'Scale from image size',
],
type: 'index',
value: 2,
},
custom_width: {
label: 'Custom width',
minimum: 64,
maximum: 8192,
step: 64,
value: 2048,
visible: false,
interactive: true,
},
custom_height: {
label: 'Custom height',
minimum: 64,
maximum: 8192,
step: 64,
value: 2048,
visible: false,
interactive: true,
},
custom_scale: {
label: 'Scale',
minimum: 1,
maximum: 16,
step: 0.01,
value: 2,
visible: false,
interactive: true,
},
upscaler_index: {
label: 'Upscaler',
choices: [],
type: 'index',
value: 0,
},
}

View File

@ -0,0 +1,255 @@
import React, { ReactEventHandler, useState } from 'react'
// import ReactDOM from 'react-dom'
import ReactDOM from 'react-dom/client'
import { versions } from 'uxp'
declare global {
namespace JSX {
interface IntrinsicElements {
'sp-picker': any
'sp-menu': any
'sp-menu-item': any
'sp-label': any
'sp-checkbox': any
'sp-slider': any
'sp-radio-group': any
'sp-radio': any
'sp-divider': any
'sp-detail': any
}
}
}
function mapRange(
x: number,
in_min: number,
in_max: number,
out_min: number,
out_max: number
) {
const mappedValue =
((x - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min
return mappedValue
}
export enum SliderType {
Integer = 'integer',
Float = 'float',
}
export class SpSliderWithLabel extends React.Component<{
onSliderChange?: any
id?: string
'show-value'?: boolean
steps?: number
in_min?: number
in_max?: number
out_min: number
out_max: number
// value?: number
title?: string
label?: string
output_value?: number // can be use to represent sd value
// slider_value?: number // it's slider value can be from 1 to 100
slider_type?: SliderType
}> {
// const [sliderValue,setSliderValue] = useState<number>(0)
state = { output_value: this.props.output_value || 0, slider_value: 0 }
steps: number
in_min: number
in_max: number
out_min: number
out_max: number
slider_type: SliderType
constructor(props: any) {
super(props)
this.steps = this.props.steps || 1
// this.out_min = this.props.out_min || this.in_min
this.out_min = this.props.out_min
this.out_max = this.props.out_max
// const temp_out_max = this.props.out_max || this.props.in_max || 99
this.in_min = this.props.in_min || 0
this.in_max = Math.round((this.out_max - this.out_min) / this.steps)
this.slider_type = this.props.slider_type || SliderType.Integer
}
componentDidMount(): void {
const slider_value = this.outputValueToStep(this.state.output_value)
this.setState({ slider_value: slider_value })
}
stepToOutputValue(slider_step: number) {
let to_value = mapRange(
slider_step,
this.in_min,
this.in_max,
this.out_min,
this.out_max
)
if (this.slider_type === SliderType.Integer)
to_value = Math.round(to_value)
return to_value
}
outputValueToStep(output_value: number) {
let slider_step = mapRange(
output_value,
this.out_min,
this.out_max,
this.in_min,
this.in_max
)
// if (this.slider_type === SliderType.Integer)
slider_step = Math.round(slider_step)
return slider_step
}
setSliderValue(newValue: any) {
let to_value = mapRange(
newValue,
this.in_min,
this.in_max,
this.out_min,
this.out_max
)
if (this.slider_type === SliderType.Integer)
to_value = Math.round(to_value)
this.setState({ output_value: to_value })
}
onSliderValueChangeHandler(event: React.ChangeEvent<HTMLInputElement>) {
const newValue: string = event.target.value
console.log('onSliderValueChangeHandler value: ', newValue)
this.setState({ output_value: newValue })
console.log({
in_min: this.in_min,
in_max: this.in_max,
out_min: this.out_min,
out_max: this.out_max,
})
let output_value = this.stepToOutputValue(parseInt(newValue))
this.setState({ output_value: output_value })
if (this.props.onSliderChange && this.props.id) {
this.props.onSliderChange(this.props.id, output_value)
}
}
handleNum2Change = (event: React.ChangeEvent<HTMLInputElement>) => {}
render() {
return (
// <div>
// <
// <sp-detail>VERSIONS</sp-detail>
// <div>{versions.plugin}</div>
// </div>
<div>
<sp-slider
show-value="false"
// id="slControlNetWeight_0"
class="slControlNetWeight_"
min={this.in_min}
max={this.in_max}
value={this.state.slider_value}
title="2 will keep the composition; 0 will allow composition to change"
onInput={this.onSliderValueChangeHandler.bind(this)}
>
<sp-label slot="label">{this.props.label}:</sp-label>
<sp-label
slot="label"
// id="lControlNetWeight_0"
class="lControlNetWeight_"
>
{this.state.output_value}
</sp-label>
</sp-slider>
</div>
)
}
}
export class SpMenu extends React.Component<{
id?: string
title?: string
style?: string
items?: string[]
disabled?: boolean[]
label_item?: string
onChange?: any
selected_index?: number
}> {
state = {
selectedItem: this.props.items ? this.props.items[0] : undefined,
}
componentDidUpdate(prevProps: any) {
// console.log('prevProps.items: ', prevProps.items)
// console.log('this.props.items: ', this.props.items)
// if (prevProps.items !== this.props.items) {
// const spMenu = this.spMenuRef.current
// if (spMenu) {
// spMenu.innerHTML = ''
// }
// }
}
handleItemClick = (item: string, index: number) => {
console.log('clicked item: ', item)
console.log('clicked index: ', index)
this.setState({ selectedItem: item })
if (this.props.onChange && this.props.id) {
this.props.onChange(this.props.id, { index: index, item: item })
}
}
handleMakeSelection = (item: string) => {
console.log('handleMakeSelection: item ', item)
this.setState({ selectedItem: item })
}
render() {
return (
<div>
<sp-picker
title={this.props.title}
size="m"
style={{ width: '199px', marginRight: '5px' }}
>
<sp-menu id={this.props.id} slot="options">
{this.props.label_item && (
<sp-menu-item
disabled="disabled"
key={-1}
data-index={-1}
selected
>
{this.props.label_item}
</sp-menu-item>
)}
{this.props.items?.map((item, index: number) => (
<sp-menu-item
key={item}
data-index={index}
selected={
this.props.selected_index !== undefined &&
this.props.selected_index !== null &&
this.props.selected_index === index
? 'selected'
: undefined
}
disabled={
this.props.disabled?.[index]
? 'disabled'
: undefined
}
onClick={() => {
this.handleItemClick(item, index)
}}
>
{item}
</sp-menu-item>
))}
</sp-menu>
</sp-picker>
</div>
)
}
}

View File

@ -0,0 +1,165 @@
import React, { ReactEventHandler, useState } from 'react'
import ReactDOM from 'react-dom/client'
import { action, makeAutoObservable, reaction, toJS } from 'mobx'
import { Provider, inject, observer } from 'mobx-react'
import { SpMenu } from './elements'
import * as ultimate_sd_upscale_script from './ultimate_sd_upscaler'
import { ScriptMode } from './ultimate_sd_upscaler'
export function toJsFunc(store: any) {
return toJS(store)
}
class ScriptStore {
scripts_list
disabled: boolean[]
selected_script_name
is_selected_script_available: boolean
selected_store: any
is_active: boolean
selected_args_name: string[]
mode: ScriptMode
scripts: any = {
None: { store: null, args_names: [], mode: [] },
'Ultimate SD upscale': {
store: ultimate_sd_upscale_script.ultimate_sd_upscaler_store,
args_names: ultimate_sd_upscale_script.script_args_ordered,
mode: ultimate_sd_upscale_script.script_mode,
},
}
constructor() {
this.scripts_list = ['None', ultimate_sd_upscale_script.script_name]
this.disabled = [false, true]
this.selected_script_name = 'None'
this.is_selected_script_available = true
this.selected_store = null
this.is_active = true
this.selected_args_name = []
this.mode = ScriptMode.Txt2Img
makeAutoObservable(this)
}
setSelectedScript(name: string) {
this.selected_script_name = name
this.selected_store = this.scripts[name].store
this.selected_args_name = this.scripts[name].args_names
this.is_selected_script_available = true
}
setIsActive(new_value: boolean) {
this.is_active = new_value
}
updateProperty(id: any, value: any) {}
orderedValues() {
const values: any = []
if (!this.selected_store) return values
for (const key of this.selected_args_name) {
// console.log(key, this.data[key])
values.push((this.selected_store.data as any)[key])
}
return values
}
setDisabled(newDisabled: boolean[]) {
console.log('this.disabled:', this.disabled)
console.log('newDisabled:', newDisabled)
this.disabled = newDisabled
}
setMode(newMode: ScriptMode) {
this.mode = newMode
// let index = 0
// Object.keys(this.scripts).forEach((key, index) => {
// const script = this.scripts[key]
// this.disabled[index] = script.mode.includes(newMode) ? false : true
// // console.log(key, script)
// })
const names = Object.keys(this.scripts)
let index = 0
for (let name of names) {
const script = this.scripts[name]
this.disabled[index] = script.mode.includes(newMode) ? false : true
index += 1
}
this.disabled[0] = false // None is always enabled
const selected_index = this.scripts_list.indexOf(
this.selected_script_name
)
this.is_selected_script_available = !this.disabled?.[selected_index]
this.setDisabled([...this.disabled])
}
}
export const script_store = new ScriptStore()
@observer
class ScriptComponent extends React.Component<{}> {
render(): React.ReactNode {
// const script_message = index !== -1 ? script_store.disabled[index] : undefined;
const script_message =
script_store.is_selected_script_available ? undefined : (
<span style={{ color: '#ff595e' }}>
{'the script is not available in the current Mode'}
</span>
)
return (
<>
<SpMenu
title="Scripts"
items={script_store.scripts_list}
disabled={script_store.disabled}
// style="width: 199px; margin-right: 5px"
label_item="Select A Script"
id={'script_list'}
onChange={(id: any, value: any) => {
script_store.setSelectedScript(value.item)
}}
/>
<div>
{script_message}
{/* {script_store.disabled.map((value, index) => (
<li key={index}> {value ? 'true' : 'false'}</li>
))} */}
</div>
<sp-checkbox
checked={script_store.is_active ? true : undefined}
onClick={(event: React.ChangeEvent<HTMLInputElement>) => {
script_store.setIsActive(event.target.checked)
}}
>
{'Activate'}
</sp-checkbox>
<>
{script_store.selected_script_name === 'None' && <></>}
{script_store.selected_script_name ===
ultimate_sd_upscale_script.script_name && (
<ultimate_sd_upscale_script.UltimateSDUpscalerForm
store={
// ultimate_sd_upscale_script.ultimate_sd_upscaler_store
script_store.scripts[
script_store.selected_script_name
].store
}
/>
)}
{/* ... other conditions for other components */}
</>
</>
)
}
}
const domNode = document.getElementById('scriptsContainer')!
const root = ReactDOM.createRoot(domNode)
root.render(
<React.StrictMode>
<ScriptComponent></ScriptComponent>
{/* <SliderValuesDisplay /> */}
</React.StrictMode>
)

View File

@ -0,0 +1,292 @@
import React, { ReactEventHandler } from 'react'
import ReactDOM from 'react-dom/client'
import { action, makeAutoObservable, reaction, toJS } from 'mobx'
import { Provider, inject, observer } from 'mobx-react'
import { SliderType, SpMenu, SpSliderWithLabel } from './elements'
import * as sdapi from '../../sdapi_py_re'
import { ui_config } from './config'
export let script_name: string = 'Ultimate SD upscale'
export enum ScriptMode {
Txt2Img = 'txt2img',
Img2Img = 'img2img',
Inpaint = 'inpaint',
Outpaint = 'outpaint',
}
export let script_mode = [
ScriptMode.Img2Img,
ScriptMode.Inpaint,
ScriptMode.Outpaint,
]
interface UltimateSDUpscalerData {
_: string
tile_width: number
tile_height: number
mask_blur: number
padding: number
seams_fix_width: number
seams_fix_denoise: number
seams_fix_padding: number
upscaler_index: number
save_upscaled_image: boolean
redraw_mode: number
save_seams_fix_image: boolean
seams_fix_mask_blur: number
seams_fix_type: number
target_size_type: number
custom_width: number
custom_height: number
custom_scale: number
}
export const script_args_ordered = [
'_',
'tile_width',
'tile_height',
'mask_blur',
'padding',
'seams_fix_width',
'seams_fix_denoise',
'seams_fix_padding',
'upscaler_index',
'save_upscaled_image',
'redraw_mode',
'save_seams_fix_image',
'seams_fix_mask_blur',
'seams_fix_type',
'target_size_type',
'custom_width',
'custom_height',
'custom_scale',
]
class UltimateSDUpscalerStore {
data: UltimateSDUpscalerData
// test_value: number = 10
// test_value_2: number = 2
test_value: number
test_value_2: number
is_active: boolean
constructor(data: UltimateSDUpscalerData) {
this.data = data
this.test_value = 10
this.test_value_2 = 2
this.is_active = false
makeAutoObservable(this)
// reaction(
// () => [this.test_value],
// () => {
// this.test_value_2 = this.test_value * 2
// console.log('reaction to test_value change:', this.test_value)
// console.log('this.test_value_2:', this.test_value_2)
// }
// )
}
setIsActive(b_value: boolean) {
this.is_active = b_value
}
setTestValue(new_value: number) {
this.test_value = new_value
console.log('setTestValue: new_value ', new_value)
console.log('setTestValue: this.test_value: ', this.test_value)
}
updateProperty(key: keyof UltimateSDUpscalerData, value: any) {
;(this.data as any)[key] = value
}
toJsFunc() {
return toJS(this)
}
}
const configValues = Object.entries(ui_config).reduce(
(acc, [key, value]) => ({ ...acc, [key]: value.value }),
{}
)
const default_values: any = {
_: '',
...configValues,
}
export const ultimate_sd_upscaler_store = new UltimateSDUpscalerStore(
default_values
)
@observer
export class UltimateSDUpscalerForm extends React.Component<{
store: UltimateSDUpscalerStore
}> {
// slider1Ref = React.createRef<SpSliderWithLabel>()
// slider2Ref = React.createRef<SpSliderWithLabel>()
state = {
items: ['Item 1', 'Item 2', 'Item 3'],
sd_upscalers: [],
}
componentDidMount(): void {
this.getUpscalers()
}
handleUpdateItems = () => {
this.setState({
items: ['New Item 1', 'New Item 2', 'New Item 3'],
})
}
handleSlider1ValueChange = (newValue: any) => {
// this.props.store.setTestValue(newValue)
this.props.store.test_value = newValue
// this.props.store.
console.log('store.test_value: ', this.props.store.test_value)
console.log('newValue: ', newValue)
}
handleSlider2ValueChange = (newValue: any) => {
// scriptFormStore.setSlider2Value(newValue)
}
handleSliderChange = (key: any, newValue: any) => {
this.props.store.updateProperty(key, newValue)
}
handleMenuChange = (key: any, new_index_value_pair: any) => {
let config = ui_config[key as keyof typeof ui_config] as any
if ('type' in config) {
let value =
config.type === 'index'
? new_index_value_pair['index']
: new_index_value_pair['item']
this.props.store.updateProperty(key, value)
}
}
async getUpscalers() {
const sd_upscalers_json = await sdapi.requestGetUpscalers()
const sd_upscalers = sd_upscalers_json.map(
(upscaler: any) => upscaler.name
)
this.setState({ sd_upscalers: sd_upscalers })
return sd_upscalers
}
render() {
const ids = [
'tile_width',
'tile_height',
'mask_blur',
'padding',
] as const
// let config = ui_config[ids as keyof typeof ui_config] as any
const group_1_sliders = ids.map((id) => (
<SpSliderWithLabel
key={id}
id={id}
show-value={false}
steps={ui_config[id].step}
out_min={ui_config[id].minimum}
out_max={ui_config[id].maximum}
output_value={this.props.store.data[id]}
title={ui_config[id].label}
label={ui_config[id].label}
onSliderChange={this.handleSliderChange}
/>
))
const seamfix_ids = [
'seams_fix_denoise',
'seams_fix_width',
'seams_fix_mask_blur',
'seams_fix_padding',
] as const
const seamfix_sliders = seamfix_ids.map((id) => (
<SpSliderWithLabel
key={id}
id={id}
show-value={false}
steps={ui_config[id].step}
out_min={ui_config[id].minimum}
out_max={ui_config[id].maximum}
output_value={this.props.store.data[id]}
title={ui_config[id].label}
label={ui_config[id].label}
onSliderChange={this.handleSliderChange}
slider_type={
Number.isInteger(ui_config[id].step)
? SliderType.Integer
: SliderType.Float
}
/>
))
return (
<div>
<SpMenu
title="Stable Diffusion Upscalers"
items={this.state.sd_upscalers}
label_item="Select Upscaler"
id={'upscaler_index'}
onChange={this.handleMenuChange}
selected_index={this.props.store.data.upscaler_index}
/>
<SpMenu
title={ui_config.target_size_type.label}
id={'target_size_type'}
items={ui_config.target_size_type.choices}
label_item={'Select ' + ui_config.target_size_type.label}
onChange={this.handleMenuChange}
selected_index={this.props.store.data.target_size_type}
/>
<SpSliderWithLabel
label={ui_config.custom_scale.label}
output_value={this.props.store.data.custom_scale}
id={'custom_scale'}
out_min={ui_config.custom_scale.minimum}
out_max={ui_config.custom_scale.maximum}
onSliderChange={this.handleSliderChange}
steps={0.01}
slider_type={SliderType.Float}
/>
<sp-checkbox
checked={
this.props.store.data.save_upscaled_image
? true
: undefined
}
onClick={(event: React.ChangeEvent<HTMLInputElement>) => {
this.props.store.updateProperty(
'save_upscaled_image',
event.target.checked
)
}}
>
{ui_config.save_upscaled_image.label}
</sp-checkbox>
<sp-checkbox
checked={
this.props.store.data.save_seams_fix_image
? true
: undefined
}
onClick={(event: React.ChangeEvent<HTMLInputElement>) => {
this.props.store.updateProperty(
'save_seams_fix_image',
event.target.checked
)
}}
>
{ui_config.save_seams_fix_image.label}
</sp-checkbox>
{group_1_sliders}
<SpMenu
title={'Seams Fix Type'}
id={'seams_fix_type'}
items={ui_config.seams_fix_type.choices}
label_item="Select Seams Fix Type"
onChange={this.handleMenuChange}
selected_index={this.props.store.data.seams_fix_type}
/>
{seamfix_sliders}
</div>
)
}
}

View File

@ -0,0 +1,109 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */
/* Projects */
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
"jsx": "react", /* Specify what JSX code is generated. */
"experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
/* Modules */
"module": "commonjs", /* Specify what module code is generated. */
// "rootDir": "./", /* Specify the root folder within your source files. */
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
"typeRoots": ["./types", "../node_modules/@types"], /* Specify multiple folders that act like './node_modules/@types'. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
"allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
/* Emit */
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
"outDir": "./dist", /* Specify an output folder for all emitted files. */
// "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
/* Type Checking */
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}

View File

@ -0,0 +1,5 @@
declare module 'sdapi_py_re' {
const exports: any;
export = exports;
}

5
ultimate_sd_upscaler/types/uxp.d.ts vendored Normal file
View File

@ -0,0 +1,5 @@
declare module 'uxp' {
// Add type declarations for the uxp module here
export const storage: any;
export const versions: any;
}

View File

@ -0,0 +1,65 @@
const path = require('path')
// const CleanWebpackPlugin = require('clean-webpack-plugin')
const CopyPlugin = require('copy-webpack-plugin')
module.exports = {
entry: {
ultimate_sd_upscaler: './src/ultimate_sd_upscaler.tsx',
scripts: './src/scripts.tsx',
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].bundle.js',
libraryTarget: 'commonjs2',
},
// mode: 'development',
mode: 'production',
devtool: 'inline-source-map', // won't work on XD due to lack of eval
externals: {
uxp: 'commonjs2 uxp',
photoshop: 'commonjs2 photoshop',
os: 'commonjs2 os',
},
resolve: {
extensions: ['.tsx', '.ts', '.js', '.jsx'],
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/,
options: {
configFile: 'tsconfig.json',
},
},
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
plugins: [
'@babel/transform-react-jsx',
'@babel/proposal-object-rest-spread',
'@babel/plugin-syntax-class-properties',
],
},
},
{
test: /\.png$/,
exclude: /node_modules/,
loader: 'file-loader',
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
],
},
plugins: [
//new CleanWebpackPlugin(),
// new CopyPlugin(['plugin'], {
// copyUnmodified: true,
// }),
],
}

View File

@ -349,10 +349,23 @@ function changeModule(_module, index) {
return obj
}
const params = remapArray(detail['sliders'])
const model_free = detail.model_free
// threshold_a_element.min = prams.
// threshold_a_element.max =
// debugger
if (model_free)
controlnetElement(
index,
'.mModelsMenuControlNet_'
).parentElement.style.display = 'none'
else
controlnetElement(
index,
'.mModelsMenuControlNet_'
).parentElement.style.display = 'block'
if (params?.preprocessor_res) {
const preprocessor_res_label_element = controlnetElement(
@ -1125,4 +1138,7 @@ module.exports = {
ControlNetUnit,
populateControlNetPresetMenu,
isControlNetModeEnable,
getModuleDetail() {
return g_module_detail
}
}

View File

@ -221,7 +221,7 @@ function initInitMaskElement() {
)
thumbnail.Thumbnail.addSPButtonToContainer(
this.thumbnail_container,
'svg_sp_btn',
'svg_sp_btn_expand',
'view modified mask',
viewMaskExpansion,