mirror of
https://github.com/sd-webui/stable-diffusion-webui.git
synced 2024-12-13 18:02:31 +03:00
Fixed LDSR, now it should work both txt2img and img2img
This commit is contained in:
parent
8239c328fd
commit
393a695aef
@ -91,9 +91,12 @@ txt2img:
|
|||||||
|
|
||||||
sampling_steps:
|
sampling_steps:
|
||||||
value: 30
|
value: 30
|
||||||
min_value: 10
|
|
||||||
max_value: 250
|
LDSR_config:
|
||||||
step: 10
|
sampling_steps: 50
|
||||||
|
preDownScale: 1
|
||||||
|
postDownScale: 1
|
||||||
|
downsample_method: "Lanczos"
|
||||||
|
|
||||||
default_sampler: "k_euler"
|
default_sampler: "k_euler"
|
||||||
separate_prompts: False
|
separate_prompts: False
|
||||||
@ -108,6 +111,7 @@ txt2img:
|
|||||||
use_RealESRGAN: False
|
use_RealESRGAN: False
|
||||||
use_LDSR: False
|
use_LDSR: False
|
||||||
RealESRGAN_model: "RealESRGAN_x4plus"
|
RealESRGAN_model: "RealESRGAN_x4plus"
|
||||||
|
use_upscaling: False
|
||||||
|
|
||||||
variant_amount:
|
variant_amount:
|
||||||
value: 0.0
|
value: 0.0
|
||||||
@ -175,6 +179,7 @@ txt2vid:
|
|||||||
use_GFPGAN: False
|
use_GFPGAN: False
|
||||||
use_RealESRGAN: False
|
use_RealESRGAN: False
|
||||||
RealESRGAN_model: "RealESRGAN_x4plus"
|
RealESRGAN_model: "RealESRGAN_x4plus"
|
||||||
|
use_upscaling: False
|
||||||
variant_amount:
|
variant_amount:
|
||||||
value: 0.0
|
value: 0.0
|
||||||
min_value: 0.0
|
min_value: 0.0
|
||||||
@ -200,6 +205,12 @@ txt2vid:
|
|||||||
beta_scheduler_type: "linear"
|
beta_scheduler_type: "linear"
|
||||||
max_frames: 100
|
max_frames: 100
|
||||||
|
|
||||||
|
LDSR_config:
|
||||||
|
sampling_steps: 50
|
||||||
|
preDownScale: 1
|
||||||
|
postDownScale: 1
|
||||||
|
downsample_method: "Lanczos"
|
||||||
|
|
||||||
img2img:
|
img2img:
|
||||||
prompt:
|
prompt:
|
||||||
sampler_name: "k_euler"
|
sampler_name: "k_euler"
|
||||||
@ -261,6 +272,12 @@ img2img:
|
|||||||
max_value: 500
|
max_value: 500
|
||||||
step: 10
|
step: 10
|
||||||
|
|
||||||
|
LDSR_config:
|
||||||
|
sampling_steps: 50
|
||||||
|
preDownScale: 1
|
||||||
|
postDownScale: 1
|
||||||
|
downsample_method: "Lanczos"
|
||||||
|
|
||||||
loopback: True
|
loopback: True
|
||||||
random_seed_loopback: True
|
random_seed_loopback: True
|
||||||
separate_prompts: False
|
separate_prompts: False
|
||||||
@ -274,6 +291,7 @@ img2img:
|
|||||||
use_GFPGAN: False
|
use_GFPGAN: False
|
||||||
use_RealESRGAN: False
|
use_RealESRGAN: False
|
||||||
RealESRGAN_model: "RealESRGAN_x4plus"
|
RealESRGAN_model: "RealESRGAN_x4plus"
|
||||||
|
use_upscaling: False
|
||||||
variant_amount: 0.0
|
variant_amount: 0.0
|
||||||
variant_seed: ""
|
variant_seed: ""
|
||||||
write_info_files: True
|
write_info_files: True
|
||||||
@ -295,4 +313,6 @@ textual_inversion:
|
|||||||
|
|
||||||
daisi_app:
|
daisi_app:
|
||||||
running_on_daisi_io: False
|
running_on_daisi_io: False
|
||||||
|
|
||||||
|
model_manager:
|
||||||
|
value: 0
|
@ -437,10 +437,10 @@ def layout():
|
|||||||
step=st.session_state['defaults'].img2img.find_noise_steps.step)
|
step=st.session_state['defaults'].img2img.find_noise_steps.step)
|
||||||
|
|
||||||
with st.expander("Batch Options"):
|
with st.expander("Batch Options"):
|
||||||
st.session_state["batch_count"] = int(st.text_input("Batch count.", value=st.session_state['defaults'].txt2img.batch_count.value,
|
st.session_state["batch_count"] = int(st.text_input("Batch count.", value=st.session_state['defaults'].img2img.batch_count.value,
|
||||||
help="How many iterations or batches of images to generate in total."))
|
help="How many iterations or batches of images to generate in total."))
|
||||||
|
|
||||||
st.session_state["batch_size"] = int(st.text_input("Batch size", value=st.session_state.defaults.txt2img.batch_size.value,
|
st.session_state["batch_size"] = int(st.text_input("Batch size", value=st.session_state.defaults.img2img.batch_size.value,
|
||||||
help="How many images are at once in a batch.\
|
help="How many images are at once in a batch.\
|
||||||
It increases the VRAM usage a lot but if you have enough VRAM it can reduce the time it takes to finish generation as more images are generated at once.\
|
It increases the VRAM usage a lot but if you have enough VRAM it can reduce the time it takes to finish generation as more images are generated at once.\
|
||||||
Default: 1"))
|
Default: 1"))
|
||||||
@ -492,7 +492,7 @@ def layout():
|
|||||||
#with st.expander("Face Restoration"):
|
#with st.expander("Face Restoration"):
|
||||||
#if st.session_state["GFPGAN_available"]:
|
#if st.session_state["GFPGAN_available"]:
|
||||||
#with st.expander("GFPGAN"):
|
#with st.expander("GFPGAN"):
|
||||||
st.session_state["use_GFPGAN"] = st.checkbox("Use GFPGAN", value=st.session_state['defaults'].txt2img.use_GFPGAN,
|
st.session_state["use_GFPGAN"] = st.checkbox("Use GFPGAN", value=st.session_state['defaults'].img2img.use_GFPGAN,
|
||||||
help="Uses the GFPGAN model to improve faces after the generation.\
|
help="Uses the GFPGAN model to improve faces after the generation.\
|
||||||
This greatly improve the quality and consistency of faces but uses\
|
This greatly improve the quality and consistency of faces but uses\
|
||||||
extra VRAM. Disable if you need the extra VRAM.")
|
extra VRAM. Disable if you need the extra VRAM.")
|
||||||
@ -506,7 +506,8 @@ def layout():
|
|||||||
st.session_state["use_GFPGAN"] = False
|
st.session_state["use_GFPGAN"] = False
|
||||||
|
|
||||||
with upscaling_tab:
|
with upscaling_tab:
|
||||||
#with st.expander("Upscaling"):
|
st.session_state['us_upscaling'] = st.checkbox("Use Upscaling", value=st.session_state['defaults'].img2img.use_upscaling)
|
||||||
|
|
||||||
# RealESRGAN and LDSR used for upscaling.
|
# RealESRGAN and LDSR used for upscaling.
|
||||||
if st.session_state["RealESRGAN_available"] or st.session_state["LDSR_available"]:
|
if st.session_state["RealESRGAN_available"] or st.session_state["LDSR_available"]:
|
||||||
|
|
||||||
@ -520,14 +521,14 @@ def layout():
|
|||||||
index=upscaling_method_list.index(st.session_state['defaults'].general.upscaling_method))
|
index=upscaling_method_list.index(st.session_state['defaults'].general.upscaling_method))
|
||||||
|
|
||||||
if st.session_state["RealESRGAN_available"]:
|
if st.session_state["RealESRGAN_available"]:
|
||||||
# with st.expander("RealESRGAN"):
|
with st.expander("RealESRGAN"):
|
||||||
st.session_state["use_RealESRGAN"] = st.checkbox("Use RealESRGAN", value=st.session_state['defaults'].txt2img.use_RealESRGAN,
|
if st.session_state["upscaling_method"] == "RealESRGAN" and st.session_state['us_upscaling']:
|
||||||
help="Uses the RealESRGAN model to upscale the images after the generation.\
|
st.session_state["use_RealESRGAN"] = True
|
||||||
This greatly improve the quality and lets you have high resolution images but \
|
else:
|
||||||
uses extra VRAM. Disable if you need the extra VRAM.")
|
st.session_state["use_RealESRGAN"] = False
|
||||||
|
|
||||||
st.session_state["RealESRGAN_model"] = st.selectbox("RealESRGAN model", st.session_state["RealESRGAN_models"],
|
st.session_state["RealESRGAN_model"] = st.selectbox("RealESRGAN model", st.session_state["RealESRGAN_models"],
|
||||||
index=st.session_state["RealESRGAN_models"].index(st.session_state['defaults'].general.RealESRGAN_model))
|
index=st.session_state["RealESRGAN_models"].index(st.session_state['defaults'].general.RealESRGAN_model))
|
||||||
else:
|
else:
|
||||||
st.session_state["use_RealESRGAN"] = False
|
st.session_state["use_RealESRGAN"] = False
|
||||||
st.session_state["RealESRGAN_model"] = "RealESRGAN_x4plus"
|
st.session_state["RealESRGAN_model"] = "RealESRGAN_x4plus"
|
||||||
@ -535,17 +536,31 @@ def layout():
|
|||||||
|
|
||||||
#
|
#
|
||||||
if st.session_state["LDSR_available"]:
|
if st.session_state["LDSR_available"]:
|
||||||
#with st.expander("LDSR"):
|
with st.expander("LDSR"):
|
||||||
st.session_state["use_LDSR"] = st.checkbox("Use LDSR", value=st.session_state['defaults'].txt2img.use_LDSR,
|
if st.session_state["upscaling_method"] == "LDSR" and st.session_state['us_upscaling']:
|
||||||
help="Uses the LDSR model to upscale the images after the generation.\
|
st.session_state["use_LDSR"] = True
|
||||||
This greatly improve the quality and lets you have high resolution images but \
|
else:
|
||||||
uses extra VRAM. Disable if you need the extra VRAM.")
|
st.session_state["use_LDSR"] = False
|
||||||
|
|
||||||
|
st.session_state["LDSR_model"] = st.selectbox("LDSR model", st.session_state["LDSR_models"],
|
||||||
|
index=st.session_state["LDSR_models"].index(st.session_state['defaults'].general.LDSR_model))
|
||||||
|
|
||||||
|
st.session_state["ldsr_sampling_steps"] = int(st.text_input("Sampling Steps", value=st.session_state['defaults'].img2img.LDSR_config.sampling_steps,
|
||||||
|
help=""))
|
||||||
|
|
||||||
|
st.session_state["preDownScale"] = int(st.text_input("PreDownScale", value=st.session_state['defaults'].img2img.LDSR_config.preDownScale,
|
||||||
|
help=""))
|
||||||
|
|
||||||
|
st.session_state["postDownScale"] = int(st.text_input("postDownScale", value=st.session_state['defaults'].img2img.LDSR_config.postDownScale,
|
||||||
|
help=""))
|
||||||
|
|
||||||
|
downsample_method_list = ['Nearest', 'Lanczos']
|
||||||
|
st.session_state["downsample_method"] = st.selectbox("Downsample Method", downsample_method_list,
|
||||||
|
index=downsample_method_list.index(st.session_state['defaults'].img2img.LDSR_config.downsample_method))
|
||||||
|
|
||||||
st.session_state["LDSR_model"] = st.selectbox("LDSR model", st.session_state["LDSR_models"],
|
|
||||||
index=st.session_state["LDSR_models"].index(st.session_state['defaults'].general.LDSR_model))
|
|
||||||
else:
|
else:
|
||||||
st.session_state["use_LDSR"] = False
|
st.session_state["use_LDSR"] = False
|
||||||
st.session_state["LDSR_model"] = "model"
|
st.session_state["LDSR_model"] = "model"
|
||||||
|
|
||||||
with st.expander("Variant"):
|
with st.expander("Variant"):
|
||||||
variant_amount = st.slider("Variant Amount:", value=st.session_state['defaults'].img2img.variant_amount, min_value=0.0, max_value=1.0, step=0.01)
|
variant_amount = st.slider("Variant Amount:", value=st.session_state['defaults'].img2img.variant_amount, min_value=0.0, max_value=1.0, step=0.01)
|
||||||
@ -559,11 +574,11 @@ def layout():
|
|||||||
editor_image = st.empty()
|
editor_image = st.empty()
|
||||||
st.session_state["editor_image"] = editor_image
|
st.session_state["editor_image"] = editor_image
|
||||||
|
|
||||||
st.form_submit_button("Refresh")
|
|
||||||
|
|
||||||
masked_image_holder = st.empty()
|
masked_image_holder = st.empty()
|
||||||
image_holder = st.empty()
|
image_holder = st.empty()
|
||||||
|
|
||||||
|
st.form_submit_button("Refresh")
|
||||||
|
|
||||||
uploaded_images = st.file_uploader(
|
uploaded_images = st.file_uploader(
|
||||||
"Upload Image", accept_multiple_files=False, type=["png", "jpg", "jpeg", "webp"],
|
"Upload Image", accept_multiple_files=False, type=["png", "jpg", "jpeg", "webp"],
|
||||||
help="Upload an image which will be used for the image to image generation.",
|
help="Upload an image which will be used for the image to image generation.",
|
||||||
@ -636,9 +651,10 @@ def layout():
|
|||||||
# load the models when we hit the generate button for the first time, it wont be loaded after that so dont worry.
|
# load the models when we hit the generate button for the first time, it wont be loaded after that so dont worry.
|
||||||
with col3_img2img_layout:
|
with col3_img2img_layout:
|
||||||
with hc.HyLoader('Loading Models...', hc.Loaders.standard_loaders,index=[0]):
|
with hc.HyLoader('Loading Models...', hc.Loaders.standard_loaders,index=[0]):
|
||||||
load_models(st.session_state["use_LDSR"], st.session_state["LDSR_model"], st.session_state["use_GFPGAN"],
|
load_models(use_LDSR=st.session_state["use_LDSR"], LDSR_model=st.session_state["LDSR_model"],
|
||||||
st.session_state["GFPGAN_model"] , st.session_state["use_RealESRGAN"],
|
use_GFPGAN=st.session_state["use_GFPGAN"], GFPGAN_model=st.session_state["GFPGAN_model"] ,
|
||||||
st.session_state["RealESRGAN_model"], server_state["CustomModel_available"], st.session_state["custom_model"])
|
use_RealESRGAN=st.session_state["use_RealESRGAN"], RealESRGAN_model=st.session_state["RealESRGAN_model"],
|
||||||
|
CustomModel_available=server_state["CustomModel_available"], custom_model=st.session_state["custom_model"])
|
||||||
|
|
||||||
if uploaded_images:
|
if uploaded_images:
|
||||||
image = Image.open(uploaded_images).convert('RGBA')
|
image = Image.open(uploaded_images).convert('RGBA')
|
||||||
|
@ -1036,34 +1036,8 @@ class LDSR():
|
|||||||
|
|
||||||
@torch.no_grad()
|
@torch.no_grad()
|
||||||
|
|
||||||
def superResolution(self,image,ddimSteps=100,preDownScale='None',postDownScale='None'):
|
def superResolution(self, image, ddimSteps = 100, preDownScale = 1, postDownScale = 1, downsample_method= "Lanczos"):
|
||||||
diffMode = 'superresolution'
|
"""
|
||||||
model = self.load_model_from_config()
|
|
||||||
#@title Import location
|
|
||||||
#@markdown ***File height and width should be multiples of 64, or image will be padded.***
|
|
||||||
|
|
||||||
#@markdown *To change upload settings without adding more, run and cancel upload*
|
|
||||||
#import_method = 'Directory' #@param ['Google Drive', 'Upload']
|
|
||||||
#output_subfolder_name = 'processed' #@param {type: 'string'}
|
|
||||||
|
|
||||||
#@markdown Drive method options:
|
|
||||||
#drive_directory = '/content/drive/MyDrive/upscaleTest' #@param {type: 'string'}
|
|
||||||
|
|
||||||
#@markdown Upload method options:
|
|
||||||
#remove_previous_uploads = False #@param {type: 'boolean'}
|
|
||||||
#save_output_to_drive = False #@param {type: 'boolean'}
|
|
||||||
#zip_if_not_drive = False #@param {type: 'boolean'}
|
|
||||||
'''
|
|
||||||
os.makedirs(pathInput+'/content/input'.replace('\\',os.sep).replace('/',os.sep), exist_ok=True)
|
|
||||||
output_directory = os.getcwd()+f'/content/output/{output_subfolder_name}'.replace('\\',os.sep).replace('/',os.sep)
|
|
||||||
os.makedirs(output_directory, exist_ok=True)
|
|
||||||
uploaded_img = pathInput+'/content/input/'.replace('\\',os.sep).replace('/',os.sep)
|
|
||||||
pathInput, dirsInput, filesInput = next(os.walk(pathInput+'/content/input').replace('\\',os.sep).replace('/',os.sep))
|
|
||||||
file_count = len(filesInput)
|
|
||||||
print(f'Found {file_count} files total')
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
||||||
#Run settings
|
#Run settings
|
||||||
|
|
||||||
diffusion_steps = int(ddimSteps) #@param [25, 50, 100, 250, 500, 1000]
|
diffusion_steps = int(ddimSteps) #@param [25, 50, 100, 250, 500, 1000]
|
||||||
@ -1074,47 +1048,53 @@ class LDSR():
|
|||||||
# Downsampling to 256px first will often improve the final image and runs faster.
|
# Downsampling to 256px first will often improve the final image and runs faster.
|
||||||
|
|
||||||
# You can improve sharpness without upscaling by upscaling and then downsampling to the original size (i.e. Super Resolution)
|
# You can improve sharpness without upscaling by upscaling and then downsampling to the original size (i.e. Super Resolution)
|
||||||
pre_downsample = preDownScale #@param ['None', '1/2', '1/4']
|
preDownScale: Values ['None', '2', '4']
|
||||||
|
|
||||||
post_downsample = postDownScale #@param ['None', 'Original Size', '1/2', '1/4']
|
postDownScale: Values ['None', 'Original Size', '2', '4']
|
||||||
|
|
||||||
# Nearest gives sharper results, but may look more pixellated. Lancoz is much higher quality, but result may be less crisp.
|
# Nearest gives sharper results, but may look more pixellated. Lancoz is much higher quality, but result may be less crisp.
|
||||||
downsample_method = 'Lanczos' #@param ['Nearest', 'Lanczos']
|
downsample_method = 'Lanczos' #@param ['Nearest', 'Lanczos']
|
||||||
|
"""
|
||||||
|
|
||||||
|
diffMode = 'superresolution'
|
||||||
|
model = self.load_model_from_config()
|
||||||
|
|
||||||
|
#Run settings
|
||||||
|
|
||||||
|
diffusion_steps = int(ddimSteps) #@param [25, 50, 100, 250, 500, 1000]
|
||||||
|
eta = 1.0 #@param {type: 'raw'}
|
||||||
|
stride = 0 #not working atm
|
||||||
|
|
||||||
|
# ####Scaling options:
|
||||||
|
# Downsampling to 256px first will often improve the final image and runs faster.
|
||||||
|
|
||||||
|
# You can improve sharpness without upscaling by upscaling and then downsampling to the original size (i.e. Super Resolution)
|
||||||
|
pre_downsample = preDownScale #@param ['None', '2', '4']
|
||||||
|
|
||||||
|
post_downsample = postDownScale #@param ['None', 'Original Size', '2', '4']
|
||||||
|
|
||||||
|
# Nearest gives sharper results, but may look more pixellated. Lancoz is much higher quality, but result may be less crisp.
|
||||||
|
#downsample_method = 'Lanczos' #@param ['Nearest', 'Lanczos']
|
||||||
|
|
||||||
|
|
||||||
overwrite_prior_runs = True #@param {type: 'boolean'}
|
overwrite_prior_runs = True #@param {type: 'boolean'}
|
||||||
|
|
||||||
#pathProcessed, dirsProcessed, filesProcessed = next(os.walk(output_directory))
|
|
||||||
|
|
||||||
#for img in filesInput:
|
|
||||||
# if img in filesProcessed and overwrite_prior_runs is False:
|
|
||||||
# print(f'Skipping {img}: Already processed')
|
|
||||||
# continue
|
|
||||||
gc.collect()
|
gc.collect()
|
||||||
torch.cuda.empty_cache()
|
torch.cuda.empty_cache()
|
||||||
#dir = pathInput
|
|
||||||
#filepath = os.path.join(dir, img).replace('\\',os.sep).replace('/',os.sep)
|
|
||||||
|
|
||||||
im_og = image
|
im_og = image
|
||||||
width_og, height_og = im_og.size
|
width_og, height_og = im_og.size
|
||||||
|
|
||||||
#Downsample Pre
|
#Downsample Pre
|
||||||
if pre_downsample == '1/2':
|
|
||||||
downsample_rate = 2
|
downsample_rate = preDownScale
|
||||||
elif pre_downsample == '1/4':
|
|
||||||
downsample_rate = 4
|
|
||||||
else:
|
|
||||||
downsample_rate = 1
|
|
||||||
# get system temp directory
|
# get system temp directory
|
||||||
#dir = tempfile.gettempdir()
|
|
||||||
width_downsampled_pre = width_og//downsample_rate
|
width_downsampled_pre = width_og//downsample_rate
|
||||||
height_downsampled_pre = height_og//downsample_rate
|
height_downsampled_pre = height_og//downsample_rate
|
||||||
if downsample_rate != 1:
|
if downsample_rate != 1:
|
||||||
print(f'Downsampling from [{width_og}, {height_og}] to [{width_downsampled_pre}, {height_downsampled_pre}]')
|
print(f'Downsampling from [{width_og}, {height_og}] to [{width_downsampled_pre}, {height_downsampled_pre}]')
|
||||||
im_og = im_og.resize((width_downsampled_pre, height_downsampled_pre), Image.LANCZOS)
|
im_og = im_og.resize((width_downsampled_pre, height_downsampled_pre), Image.LANCZOS)
|
||||||
#os.makedirs(dir, exist_ok=True)
|
|
||||||
#im_og.save(dir + '/ldsr/temp.png'.replace('\\',os.sep).replace('/',os.sep))
|
|
||||||
#filepath = dir + '/ldsr/temp.png'.replace('\\',os.sep).replace('/',os.sep)
|
|
||||||
|
|
||||||
logs = self.run(model["model"], im_og, diffMode, diffusion_steps, eta)
|
logs = self.run(model["model"], im_og, diffMode, diffusion_steps, eta)
|
||||||
|
|
||||||
@ -1124,16 +1104,11 @@ class LDSR():
|
|||||||
sample = (sample + 1.) / 2. * 255
|
sample = (sample + 1.) / 2. * 255
|
||||||
sample = sample.numpy().astype(np.uint8)
|
sample = sample.numpy().astype(np.uint8)
|
||||||
sample = np.transpose(sample, (0, 2, 3, 1))
|
sample = np.transpose(sample, (0, 2, 3, 1))
|
||||||
#print(sample.shape)
|
|
||||||
a = Image.fromarray(sample[0])
|
a = Image.fromarray(sample[0])
|
||||||
|
|
||||||
#Downsample Post
|
#Downsample Post
|
||||||
if post_downsample == '1/2':
|
downsample_rate = postDownScale
|
||||||
downsample_rate = 2
|
|
||||||
elif post_downsample == '1/4':
|
|
||||||
downsample_rate = 4
|
|
||||||
else:
|
|
||||||
downsample_rate = 1
|
|
||||||
|
|
||||||
width, height = a.size
|
width, height = a.size
|
||||||
width_downsampled_post = width//downsample_rate
|
width_downsampled_post = width//downsample_rate
|
||||||
@ -1150,20 +1125,11 @@ class LDSR():
|
|||||||
elif post_downsample == 'Original Size':
|
elif post_downsample == 'Original Size':
|
||||||
print(f'Downsampling from [{width}, {height}] to Original Size [{width_og}, {height_og}]')
|
print(f'Downsampling from [{width}, {height}] to Original Size [{width_og}, {height_og}]')
|
||||||
a = a.resize((width_og, height_og), aliasing)
|
a = a.resize((width_og, height_og), aliasing)
|
||||||
|
|
||||||
#display.display(a)
|
|
||||||
#a.save(f'{output_directory}/{img}')
|
|
||||||
del model
|
del model
|
||||||
gc.collect()
|
gc.collect()
|
||||||
torch.cuda.empty_cache()
|
torch.cuda.empty_cache()
|
||||||
'''
|
|
||||||
if import_method != 'Google Drive' and zip_if_not_drive is True:
|
|
||||||
print('Zipping files')
|
|
||||||
current_time = datetime.now().strftime('%y%m%d-%H%M%S_%f')
|
|
||||||
output_zip_name = 'output'+str(current_time)+'.zip'
|
|
||||||
#!zip -r {output_zip_name} {output_directory}
|
|
||||||
print(f'Zipped outputs in {output_zip_name}')
|
|
||||||
'''
|
|
||||||
print(f'Processing finished!')
|
print(f'Processing finished!')
|
||||||
return a
|
return a
|
||||||
|
|
||||||
@ -1211,13 +1177,13 @@ def torch_gc():
|
|||||||
|
|
||||||
@retry(tries=5)
|
@retry(tries=5)
|
||||||
#@st.experimental_memo(persist="disk", show_spinner=False, suppress_st_warning=True)
|
#@st.experimental_memo(persist="disk", show_spinner=False, suppress_st_warning=True)
|
||||||
def load_GFPGAN(model_name='GFPGANv1.3'):
|
def load_GFPGAN(model_name='GFPGANv1.4'):
|
||||||
#model_name = 'GFPGANv1.3'
|
#model_name = 'GFPGANv1.3'
|
||||||
|
|
||||||
model_path = os.path.join(st.session_state['defaults'].general.GFPGAN_dir, 'experiments/pretrained_models', model_name + '.pth')
|
model_path = os.path.join(st.session_state['defaults'].general.GFPGAN_dir, model_name + '.pth')
|
||||||
|
|
||||||
if not os.path.isfile(model_path):
|
#if not os.path.isfile(model_path):
|
||||||
model_path = os.path.join(st.session_state['defaults'].general.GFPGAN_dir, model_name + '.pth')
|
#model_path = os.path.join(st.session_state['defaults'].general.GFPGAN_dir, model_name + '.pth')
|
||||||
|
|
||||||
if not os.path.isfile(model_path):
|
if not os.path.isfile(model_path):
|
||||||
raise Exception("GFPGAN model not found at path "+model_path)
|
raise Exception("GFPGAN model not found at path "+model_path)
|
||||||
@ -2020,7 +1986,7 @@ def oxlamon_matrix(prompt, seed, n_iter, batch_size):
|
|||||||
#
|
#
|
||||||
def process_images(
|
def process_images(
|
||||||
outpath, func_init, func_sample, prompt, seed, sampler_name, save_grid, batch_size,
|
outpath, func_init, func_sample, prompt, seed, sampler_name, save_grid, batch_size,
|
||||||
n_iter, steps, cfg_scale, width, height, prompt_matrix, use_GFPGAN: bool = True, GFPGAN_model: str = 'GFPGANv1.3',
|
n_iter, steps, cfg_scale, width, height, prompt_matrix, use_GFPGAN: bool = True, GFPGAN_model: str = 'GFPGANv1.4',
|
||||||
use_RealESRGAN: bool = False, realesrgan_model_name:str = 'RealESRGAN_x4plus',
|
use_RealESRGAN: bool = False, realesrgan_model_name:str = 'RealESRGAN_x4plus',
|
||||||
use_LDSR:bool = False, LDSR_model_name:str = 'model', ddim_eta=0.0, normalize_prompt_weights=True, init_img=None, init_mask=None,
|
use_LDSR:bool = False, LDSR_model_name:str = 'model', ddim_eta=0.0, normalize_prompt_weights=True, init_img=None, init_mask=None,
|
||||||
mask_blur_strength=3, mask_restore=False, denoising_strength=0.75, noise_mode=0, find_noise_steps=1, resize_mode=None, uses_loopback=False,
|
mask_blur_strength=3, mask_restore=False, denoising_strength=0.75, noise_mode=0, find_noise_steps=1, resize_mode=None, uses_loopback=False,
|
||||||
@ -2248,10 +2214,14 @@ def process_images(
|
|||||||
original_filename = filename
|
original_filename = filename
|
||||||
|
|
||||||
st.session_state["preview_image"].image(image)
|
st.session_state["preview_image"].image(image)
|
||||||
|
|
||||||
|
#
|
||||||
if use_GFPGAN and server_state["GFPGAN"] is not None and not use_RealESRGAN and not use_LDSR:
|
if use_GFPGAN and server_state["GFPGAN"] is not None and not use_RealESRGAN and not use_LDSR:
|
||||||
st.session_state["progress_bar_text"].text("Running GFPGAN on image %d of %d..." % (i+1, len(x_samples_ddim)))
|
st.session_state["progress_bar_text"].text("Running GFPGAN on image %d of %d..." % (i+1, len(x_samples_ddim)))
|
||||||
|
|
||||||
|
if server_state["GFPGAN"].name != GFPGAN_model:
|
||||||
|
load_models(use_LDSR=use_LDSR, LDSR_model=LDSR_model_name, use_GFPGAN=use_GFPGAN, use_RealESRGAN=use_RealESRGAN, RealESRGAN_model=realesrgan_model_name)
|
||||||
|
|
||||||
torch_gc()
|
torch_gc()
|
||||||
cropped_faces, restored_faces, restored_img = server_state["GFPGAN"].enhance(x_sample[:,:,::-1], has_aligned=False, only_center_face=False, paste_back=True)
|
cropped_faces, restored_faces, restored_img = server_state["GFPGAN"].enhance(x_sample[:,:,::-1], has_aligned=False, only_center_face=False, paste_back=True)
|
||||||
|
|
||||||
@ -2314,7 +2284,10 @@ def process_images(
|
|||||||
#try_loading_RealESRGAN(realesrgan_model_name)
|
#try_loading_RealESRGAN(realesrgan_model_name)
|
||||||
load_models(use_LDSR=use_LDSR, LDSR_model=LDSR_model_name, use_GFPGAN=use_GFPGAN, use_RealESRGAN=use_RealESRGAN, RealESRGAN_model=realesrgan_model_name)
|
load_models(use_LDSR=use_LDSR, LDSR_model=LDSR_model_name, use_GFPGAN=use_GFPGAN, use_RealESRGAN=use_RealESRGAN, RealESRGAN_model=realesrgan_model_name)
|
||||||
|
|
||||||
result = server_state["LDSR"].superResolution(image, 2, 2, 2)
|
result = server_state["LDSR"].superResolution(gfpgan_image, ddimSteps = st.session_state["ldsr_sampling_steps"],
|
||||||
|
preDownScale = st.session_state["preDownScale"], postDownScale = st.session_state["postDownScale"],
|
||||||
|
downsample_method=st.session_state["downsample_method"])
|
||||||
|
|
||||||
ldsr_filename = original_filename + '-ldsr4x'
|
ldsr_filename = original_filename + '-ldsr4x'
|
||||||
#ldsr_sample = result[:,:,::-1]
|
#ldsr_sample = result[:,:,::-1]
|
||||||
#ldsr_image = Image.fromarray(ldsr_sample)
|
#ldsr_image = Image.fromarray(ldsr_sample)
|
||||||
@ -2327,24 +2300,35 @@ def process_images(
|
|||||||
normalize_prompt_weights, use_GFPGAN, write_info_files, prompt_matrix, init_img, uses_loopback, uses_random_seed_loopback,
|
normalize_prompt_weights, use_GFPGAN, write_info_files, prompt_matrix, init_img, uses_loopback, uses_random_seed_loopback,
|
||||||
save_grid, sort_samples, sampler_name, ddim_eta, n_iter, batch_size, i, denoising_strength, resize_mode, False, server_state["loaded_model"])
|
save_grid, sort_samples, sampler_name, ddim_eta, n_iter, batch_size, i, denoising_strength, resize_mode, False, server_state["loaded_model"])
|
||||||
|
|
||||||
output_images.append(ldsr_image) #287
|
output_images.append(result) #287
|
||||||
run_images.append(ldsr_image)
|
run_images.append(result)
|
||||||
|
|
||||||
if simple_templating:
|
if simple_templating:
|
||||||
grid_captions.append( captions[i] + "\nldsr" )
|
grid_captions.append( captions[i] + "\nldsr" )
|
||||||
|
|
||||||
#
|
#
|
||||||
elif use_LDSR and server_state["LDSR"] is not None and use_GFPGAN:
|
elif use_LDSR and server_state["LDSR"] is not None and use_GFPGAN and server_state["GFPGAN"] is not None:
|
||||||
print ("Running GFPGAN+LDSR on image %d of %d..." % (i+1, len(x_samples_ddim)))
|
print ("Running GFPGAN+LDSR on image %d of %d..." % (i+1, len(x_samples_ddim)))
|
||||||
st.session_state["progress_bar_text"].text("Running GFPGAN+LDSR on image %d of %d..." % (i+1, len(x_samples_ddim)))
|
st.session_state["progress_bar_text"].text("Running GFPGAN+LDSR on image %d of %d..." % (i+1, len(x_samples_ddim)))
|
||||||
#skip_save = True # #287 >_>
|
|
||||||
|
if server_state["GFPGAN"].name != GFPGAN_model:
|
||||||
|
load_models(use_LDSR=use_LDSR, LDSR_model=LDSR_model_name, use_GFPGAN=use_GFPGAN, use_RealESRGAN=use_RealESRGAN, RealESRGAN_model=realesrgan_model_name)
|
||||||
|
|
||||||
torch_gc()
|
torch_gc()
|
||||||
|
cropped_faces, restored_faces, restored_img = server_state["GFPGAN"].enhance(x_sample[:,:,::-1], has_aligned=False, only_center_face=False, paste_back=True)
|
||||||
|
|
||||||
|
gfpgan_sample = restored_img[:,:,::-1]
|
||||||
|
gfpgan_image = Image.fromarray(gfpgan_sample)
|
||||||
|
|
||||||
if server_state["LDSR"].name != LDSR_model_name:
|
if server_state["LDSR"].name != LDSR_model_name:
|
||||||
#try_loading_RealESRGAN(realesrgan_model_name)
|
#try_loading_RealESRGAN(realesrgan_model_name)
|
||||||
load_models(use_LDSR=use_LDSR, LDSR_model=LDSR_model_name, use_GFPGAN=use_GFPGAN, use_RealESRGAN=use_RealESRGAN, RealESRGAN_model=realesrgan_model_name)
|
load_models(use_LDSR=use_LDSR, LDSR_model=LDSR_model_name, use_GFPGAN=use_GFPGAN, use_RealESRGAN=use_RealESRGAN, RealESRGAN_model=realesrgan_model_name)
|
||||||
|
|
||||||
result = server_state["LDSR"].superResolution(image, 2, 2, 2)
|
#LDSR.superResolution(gfpgan_image, ddimSteps=100, preDownScale='None', postDownScale='None', downsample_method="Lanczos")
|
||||||
|
result = server_state["LDSR"].superResolution(gfpgan_image, ddimSteps = st.session_state["ldsr_sampling_steps"],
|
||||||
|
preDownScale = st.session_state["preDownScale"], postDownScale = st.session_state["postDownScale"],
|
||||||
|
downsample_method=st.session_state["downsample_method"])
|
||||||
|
|
||||||
ldsr_filename = original_filename + '-gfpgan-ldsr2x'
|
ldsr_filename = original_filename + '-gfpgan-ldsr2x'
|
||||||
#ldsr_sample = result[:,:,::-1]
|
#ldsr_sample = result[:,:,::-1]
|
||||||
#ldsr_image = Image.fromarray(result)
|
#ldsr_image = Image.fromarray(result)
|
||||||
|
@ -325,7 +325,8 @@ def layout():
|
|||||||
st.session_state["use_GFPGAN"] = False
|
st.session_state["use_GFPGAN"] = False
|
||||||
|
|
||||||
with upscaling_tab:
|
with upscaling_tab:
|
||||||
#with st.expander("Upscaling"):
|
st.session_state['us_upscaling'] = st.checkbox("Use Upscaling", value=st.session_state['defaults'].txt2img.use_upscaling)
|
||||||
|
|
||||||
# RealESRGAN and LDSR used for upscaling.
|
# RealESRGAN and LDSR used for upscaling.
|
||||||
if st.session_state["RealESRGAN_available"] or st.session_state["LDSR_available"]:
|
if st.session_state["RealESRGAN_available"] or st.session_state["LDSR_available"]:
|
||||||
|
|
||||||
@ -339,14 +340,14 @@ def layout():
|
|||||||
index=upscaling_method_list.index(st.session_state['defaults'].general.upscaling_method))
|
index=upscaling_method_list.index(st.session_state['defaults'].general.upscaling_method))
|
||||||
|
|
||||||
if st.session_state["RealESRGAN_available"]:
|
if st.session_state["RealESRGAN_available"]:
|
||||||
# with st.expander("RealESRGAN"):
|
with st.expander("RealESRGAN"):
|
||||||
st.session_state["use_RealESRGAN"] = st.checkbox("Use RealESRGAN", value=st.session_state['defaults'].txt2img.use_RealESRGAN,
|
if st.session_state["upscaling_method"] == "RealESRGAN" and st.session_state['us_upscaling']:
|
||||||
help="Uses the RealESRGAN model to upscale the images after the generation.\
|
st.session_state["use_RealESRGAN"] = True
|
||||||
This greatly improve the quality and lets you have high resolution images but \
|
else:
|
||||||
uses extra VRAM. Disable if you need the extra VRAM.")
|
st.session_state["use_RealESRGAN"] = False
|
||||||
|
|
||||||
st.session_state["RealESRGAN_model"] = st.selectbox("RealESRGAN model", st.session_state["RealESRGAN_models"],
|
st.session_state["RealESRGAN_model"] = st.selectbox("RealESRGAN model", st.session_state["RealESRGAN_models"],
|
||||||
index=st.session_state["RealESRGAN_models"].index(st.session_state['defaults'].general.RealESRGAN_model))
|
index=st.session_state["RealESRGAN_models"].index(st.session_state['defaults'].general.RealESRGAN_model))
|
||||||
else:
|
else:
|
||||||
st.session_state["use_RealESRGAN"] = False
|
st.session_state["use_RealESRGAN"] = False
|
||||||
st.session_state["RealESRGAN_model"] = "RealESRGAN_x4plus"
|
st.session_state["RealESRGAN_model"] = "RealESRGAN_x4plus"
|
||||||
@ -354,14 +355,28 @@ def layout():
|
|||||||
|
|
||||||
#
|
#
|
||||||
if st.session_state["LDSR_available"]:
|
if st.session_state["LDSR_available"]:
|
||||||
#with st.expander("LDSR"):
|
with st.expander("LDSR"):
|
||||||
st.session_state["use_LDSR"] = st.checkbox("Use LDSR", value=st.session_state['defaults'].txt2img.use_LDSR,
|
if st.session_state["upscaling_method"] == "LDSR" and st.session_state['us_upscaling']:
|
||||||
help="Uses the LDSR model to upscale the images after the generation.\
|
st.session_state["use_LDSR"] = True
|
||||||
This greatly improve the quality and lets you have high resolution images but \
|
else:
|
||||||
uses extra VRAM. Disable if you need the extra VRAM.")
|
st.session_state["use_LDSR"] = False
|
||||||
|
|
||||||
st.session_state["LDSR_model"] = st.selectbox("LDSR model", st.session_state["LDSR_models"],
|
st.session_state["LDSR_model"] = st.selectbox("LDSR model", st.session_state["LDSR_models"],
|
||||||
index=st.session_state["LDSR_models"].index(st.session_state['defaults'].general.LDSR_model))
|
index=st.session_state["LDSR_models"].index(st.session_state['defaults'].general.LDSR_model))
|
||||||
|
|
||||||
|
st.session_state["ldsr_sampling_steps"] = int(st.text_input("Sampling Steps", value=st.session_state['defaults'].txt2img.LDSR_config.sampling_steps,
|
||||||
|
help=""))
|
||||||
|
|
||||||
|
st.session_state["preDownScale"] = int(st.text_input("PreDownScale", value=st.session_state['defaults'].txt2img.LDSR_config.preDownScale,
|
||||||
|
help=""))
|
||||||
|
|
||||||
|
st.session_state["postDownScale"] = int(st.text_input("postDownScale", value=st.session_state['defaults'].txt2img.LDSR_config.postDownScale,
|
||||||
|
help=""))
|
||||||
|
|
||||||
|
downsample_method_list = ['Nearest', 'Lanczos']
|
||||||
|
st.session_state["downsample_method"] = st.selectbox("Downsample Method", downsample_method_list,
|
||||||
|
index=downsample_method_list.index(st.session_state['defaults'].txt2img.LDSR_config.downsample_method))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
st.session_state["use_LDSR"] = False
|
st.session_state["use_LDSR"] = False
|
||||||
st.session_state["LDSR_model"] = "model"
|
st.session_state["LDSR_model"] = "model"
|
||||||
|
@ -54,7 +54,7 @@ except:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
class plugin_info():
|
class plugin_info():
|
||||||
plugname = "txt2img"
|
plugname = "txt2vid"
|
||||||
description = "Text to Image"
|
description = "Text to Image"
|
||||||
isTab = True
|
isTab = True
|
||||||
displayPriority = 1
|
displayPriority = 1
|
||||||
@ -734,22 +734,93 @@ def layout():
|
|||||||
help="Do loop")
|
help="Do loop")
|
||||||
st.session_state["save_as_jpg"] = st.checkbox("Save samples as jpg", value=st.session_state['defaults'].txt2vid.save_as_jpg, help="Saves the images as jpg instead of png.")
|
st.session_state["save_as_jpg"] = st.checkbox("Save samples as jpg", value=st.session_state['defaults'].txt2vid.save_as_jpg, help="Saves the images as jpg instead of png.")
|
||||||
|
|
||||||
if server_state["GFPGAN_available"]:
|
#
|
||||||
st.session_state["use_GFPGAN"] = st.checkbox("Use GFPGAN", value=st.session_state['defaults'].txt2vid.use_GFPGAN,
|
if "GFPGAN_available" not in st.session_state:
|
||||||
help="Uses the GFPGAN model to improve faces after the generation. This greatly improve the quality and consistency \
|
GFPGAN_available()
|
||||||
of faces but uses extra VRAM. Disable if you need the extra VRAM.")
|
|
||||||
else:
|
if "RealESRGAN_available" not in st.session_state:
|
||||||
st.session_state["use_GFPGAN"] = False
|
RealESRGAN_available()
|
||||||
|
|
||||||
if server_state["RealESRGAN_available"]:
|
if "LDSR_available" not in st.session_state:
|
||||||
st.session_state["use_RealESRGAN"] = st.checkbox("Use RealESRGAN", value=st.session_state['defaults'].txt2vid.use_RealESRGAN,
|
LDSR_available()
|
||||||
help="Uses the RealESRGAN model to upscale the images after the generation. \
|
|
||||||
This greatly improve the quality and lets you have high resolution images but \
|
if st.session_state["GFPGAN_available"] or st.session_state["RealESRGAN_available"] or st.session_state["LDSR_available"]:
|
||||||
uses extra VRAM. Disable if you need the extra VRAM.")
|
with st.expander("Post-Processing"):
|
||||||
st.session_state["RealESRGAN_model"] = st.selectbox("RealESRGAN model", ["RealESRGAN_x4plus", "RealESRGAN_x4plus_anime_6B"], index=0)
|
face_restoration_tab, upscaling_tab = st.tabs(["Face Restoration", "Upscaling"])
|
||||||
else:
|
with face_restoration_tab:
|
||||||
st.session_state["use_RealESRGAN"] = False
|
# GFPGAN used for face restoration
|
||||||
st.session_state["RealESRGAN_model"] = "RealESRGAN_x4plus"
|
if st.session_state["GFPGAN_available"]:
|
||||||
|
#with st.expander("Face Restoration"):
|
||||||
|
#if st.session_state["GFPGAN_available"]:
|
||||||
|
#with st.expander("GFPGAN"):
|
||||||
|
st.session_state["use_GFPGAN"] = st.checkbox("Use GFPGAN", value=st.session_state['defaults'].txt2vid.use_GFPGAN,
|
||||||
|
help="Uses the GFPGAN model to improve faces after the generation.\
|
||||||
|
This greatly improve the quality and consistency of faces but uses\
|
||||||
|
extra VRAM. Disable if you need the extra VRAM.")
|
||||||
|
|
||||||
|
st.session_state["GFPGAN_model"] = st.selectbox("GFPGAN model", st.session_state["GFPGAN_models"],
|
||||||
|
index=st.session_state["GFPGAN_models"].index(st.session_state['defaults'].general.GFPGAN_model))
|
||||||
|
|
||||||
|
#st.session_state["GFPGAN_strenght"] = st.slider("Effect Strenght", min_value=1, max_value=100, value=1, step=1, help='')
|
||||||
|
|
||||||
|
else:
|
||||||
|
st.session_state["use_GFPGAN"] = False
|
||||||
|
|
||||||
|
with upscaling_tab:
|
||||||
|
st.session_state['us_upscaling'] = st.checkbox("Use Upscaling", value=st.session_state['defaults'].txt2vid.use_upscaling)
|
||||||
|
# RealESRGAN and LDSR used for upscaling.
|
||||||
|
if st.session_state["RealESRGAN_available"] or st.session_state["LDSR_available"]:
|
||||||
|
|
||||||
|
upscaling_method_list = []
|
||||||
|
if st.session_state["RealESRGAN_available"]:
|
||||||
|
upscaling_method_list.append("RealESRGAN")
|
||||||
|
if st.session_state["LDSR_available"]:
|
||||||
|
upscaling_method_list.append("LDSR")
|
||||||
|
|
||||||
|
st.session_state["upscaling_method"] = st.selectbox("Upscaling Method", upscaling_method_list,
|
||||||
|
index=upscaling_method_list.index(st.session_state['defaults'].general.upscaling_method))
|
||||||
|
|
||||||
|
if st.session_state["RealESRGAN_available"]:
|
||||||
|
with st.expander("RealESRGAN"):
|
||||||
|
if st.session_state["upscaling_method"] == "RealESRGAN" and st.session_state['us_upscaling']:
|
||||||
|
st.session_state["use_RealESRGAN"] = True
|
||||||
|
else:
|
||||||
|
st.session_state["use_RealESRGAN"] = False
|
||||||
|
|
||||||
|
st.session_state["RealESRGAN_model"] = st.selectbox("RealESRGAN model", st.session_state["RealESRGAN_models"],
|
||||||
|
index=st.session_state["RealESRGAN_models"].index(st.session_state['defaults'].general.RealESRGAN_model))
|
||||||
|
else:
|
||||||
|
st.session_state["use_RealESRGAN"] = False
|
||||||
|
st.session_state["RealESRGAN_model"] = "RealESRGAN_x4plus"
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
if st.session_state["LDSR_available"]:
|
||||||
|
with st.expander("LDSR"):
|
||||||
|
if st.session_state["upscaling_method"] == "LDSR" and st.session_state['us_upscaling']:
|
||||||
|
st.session_state["use_LDSR"] = True
|
||||||
|
else:
|
||||||
|
st.session_state["use_LDSR"] = False
|
||||||
|
|
||||||
|
st.session_state["LDSR_model"] = st.selectbox("LDSR model", st.session_state["LDSR_models"],
|
||||||
|
index=st.session_state["LDSR_models"].index(st.session_state['defaults'].general.LDSR_model))
|
||||||
|
|
||||||
|
st.session_state["ldsr_sampling_steps"] = int(st.text_input("Sampling Steps", value=st.session_state['defaults'].txt2vid.LDSR_config.sampling_steps,
|
||||||
|
help=""))
|
||||||
|
|
||||||
|
st.session_state["preDownScale"] = int(st.text_input("PreDownScale", value=st.session_state['defaults'].txt2vid.LDSR_config.preDownScale,
|
||||||
|
help=""))
|
||||||
|
|
||||||
|
st.session_state["postDownScale"] = int(st.text_input("postDownScale", value=st.session_state['defaults'].txt2vid.LDSR_config.postDownScale,
|
||||||
|
help=""))
|
||||||
|
|
||||||
|
downsample_method_list = ['Nearest', 'Lanczos']
|
||||||
|
st.session_state["downsample_method"] = st.selectbox("Downsample Method", downsample_method_list,
|
||||||
|
index=downsample_method_list.index(st.session_state['defaults'].txt2vid.LDSR_config.downsample_method))
|
||||||
|
|
||||||
|
else:
|
||||||
|
st.session_state["use_LDSR"] = False
|
||||||
|
st.session_state["LDSR_model"] = "model"
|
||||||
|
|
||||||
with st.expander("Variant"):
|
with st.expander("Variant"):
|
||||||
st.session_state["variant_amount"] = st.slider("Variant Amount:", value=st.session_state['defaults'].txt2vid.variant_amount.value,
|
st.session_state["variant_amount"] = st.slider("Variant Amount:", value=st.session_state['defaults'].txt2vid.variant_amount.value,
|
||||||
|
Loading…
Reference in New Issue
Block a user