mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 01:04:32 +02:00
Merge pull request #4555 from CalamitousFelicitousness/feat/base-output-paths
Feat/base output paths
This commit is contained in:
+11
-4
@@ -239,9 +239,16 @@ class SimpleFunctionQueue {
|
||||
// HTML Elements
|
||||
|
||||
class GalleryFolder extends HTMLElement {
|
||||
constructor(name) {
|
||||
constructor(folder) {
|
||||
super();
|
||||
this.name = decodeURI(name);
|
||||
// Support both old format (string) and new format (object with path and label)
|
||||
if (typeof folder === 'object' && folder !== null) {
|
||||
this.name = decodeURI(folder.path || '');
|
||||
this.label = decodeURI(folder.label || folder.path || '');
|
||||
} else {
|
||||
this.name = decodeURI(folder);
|
||||
this.label = this.name;
|
||||
}
|
||||
this.style.overflowX = 'hidden';
|
||||
this.shadow = this.attachShadow({ mode: 'open' });
|
||||
this.shadow.adoptedStyleSheets = [folderStylesheet];
|
||||
@@ -250,8 +257,8 @@ class GalleryFolder extends HTMLElement {
|
||||
connectedCallback() {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'gallery-folder';
|
||||
div.innerHTML = `<span class="gallery-folder-icon">\uf03e</span> ${this.name}`;
|
||||
div.title = this.name;
|
||||
div.innerHTML = `<span class="gallery-folder-icon">\uf03e</span> ${this.label}`;
|
||||
div.title = this.name; // Show full path on hover
|
||||
div.addEventListener('click', () => {
|
||||
for (const folder of el.folders.children) {
|
||||
if (folder.name === this.name) folder.shadow.firstElementChild.classList.add('gallery-folder-selected');
|
||||
|
||||
+45
-13
@@ -10,6 +10,7 @@ from starlette.websockets import WebSocket, WebSocketState
|
||||
from pydantic import BaseModel, Field # pylint: disable=no-name-in-module
|
||||
from PIL import Image
|
||||
from modules import shared, images, files_cache, modelstats
|
||||
from modules.paths import resolve_output_path
|
||||
|
||||
|
||||
debug = shared.log.debug if os.environ.get('SD_BROWSER_DEBUG', None) is not None else lambda *args, **kwargs: None
|
||||
@@ -128,20 +129,51 @@ def register_api(app: FastAPI): # register api
|
||||
|
||||
# @app.get('/sdapi/v1/browser/folders', response_model=List[str])
|
||||
def get_folders():
|
||||
def make_folder(path, label=None):
|
||||
"""Create folder entry with path and display label."""
|
||||
if label is None:
|
||||
label = os.path.basename(path) or path
|
||||
return {"path": path, "label": label}
|
||||
|
||||
reference_dir = os.path.join('models', 'Reference')
|
||||
folders = [shared.opts.data.get(f, '') for f in OPTS_FOLDERS]
|
||||
folders += list(shared.opts.browser_folders.split(','))
|
||||
folders += [reference_dir]
|
||||
folders = [f.strip() for f in folders if f != '']
|
||||
folders = list(dict.fromkeys(folders)) # filter duplicates
|
||||
folders = [f for f in folders if os.path.isdir(f)]
|
||||
if shared.demo is not None:
|
||||
for f in folders:
|
||||
if f not in shared.demo.allowed_paths:
|
||||
debug(f'Browser folders allow: {f}')
|
||||
shared.demo.allowed_paths.append(quote(f))
|
||||
debug(f'Browser folders: {folders}')
|
||||
return JSONResponse(content=folders)
|
||||
base_samples = shared.opts.outdir_samples
|
||||
base_grids = shared.opts.outdir_grids
|
||||
# Build list of resolved output paths with labels
|
||||
folders = []
|
||||
if base_samples:
|
||||
folders.append(make_folder(base_samples, os.path.basename(base_samples.rstrip('/\\'))))
|
||||
if base_grids and base_grids != base_samples:
|
||||
folders.append(make_folder(base_grids, os.path.basename(base_grids.rstrip('/\\'))))
|
||||
# Use the specific folder setting values as labels (e.g., "outputs/text" -> "outputs/text")
|
||||
folders.append(make_folder(resolve_output_path(base_samples, shared.opts.outdir_txt2img_samples), shared.opts.outdir_txt2img_samples))
|
||||
folders.append(make_folder(resolve_output_path(base_samples, shared.opts.outdir_img2img_samples), shared.opts.outdir_img2img_samples))
|
||||
folders.append(make_folder(resolve_output_path(base_samples, shared.opts.outdir_control_samples), shared.opts.outdir_control_samples))
|
||||
folders.append(make_folder(resolve_output_path(base_samples, shared.opts.outdir_extras_samples), shared.opts.outdir_extras_samples))
|
||||
folders.append(make_folder(resolve_output_path(base_samples, shared.opts.outdir_save), shared.opts.outdir_save))
|
||||
folders.append(make_folder(resolve_output_path(base_samples, shared.opts.outdir_video), shared.opts.outdir_video))
|
||||
folders.append(make_folder(resolve_output_path(base_samples, shared.opts.outdir_init_images), shared.opts.outdir_init_images))
|
||||
folders.append(make_folder(resolve_output_path(base_grids, shared.opts.outdir_txt2img_grids), shared.opts.outdir_txt2img_grids))
|
||||
folders.append(make_folder(resolve_output_path(base_grids, shared.opts.outdir_img2img_grids), shared.opts.outdir_img2img_grids))
|
||||
folders.append(make_folder(resolve_output_path(base_grids, shared.opts.outdir_control_grids), shared.opts.outdir_control_grids))
|
||||
# Custom browser folders and reference dir
|
||||
for f in shared.opts.browser_folders.split(','):
|
||||
f = f.strip()
|
||||
if f:
|
||||
folders.append(make_folder(f))
|
||||
folders.append(make_folder(reference_dir, 'Reference'))
|
||||
# Filter empty and duplicates (by path)
|
||||
seen_paths = set()
|
||||
unique_folders = []
|
||||
for f in folders:
|
||||
path = f["path"].strip()
|
||||
if path and path not in seen_paths and os.path.isdir(path):
|
||||
seen_paths.add(path)
|
||||
unique_folders.append(f)
|
||||
if shared.demo is not None and path not in shared.demo.allowed_paths:
|
||||
debug(f'Browser folders allow: {path}')
|
||||
shared.demo.allowed_paths.append(quote(path))
|
||||
debug(f'Browser folders: {unique_folders}')
|
||||
return JSONResponse(content=unique_folders)
|
||||
|
||||
# @app.get("/sdapi/v1/browser/thumb", response_model=dict)
|
||||
async def get_thumb(file: str):
|
||||
|
||||
@@ -3,6 +3,7 @@ from fastapi.responses import JSONResponse
|
||||
from modules import errors, shared, scripts_manager, ui
|
||||
from modules.api import models, script, helpers
|
||||
from modules.processing import StableDiffusionProcessingTxt2Img, StableDiffusionProcessingImg2Img, process_images
|
||||
from modules.paths import resolve_output_path
|
||||
|
||||
|
||||
errors.install()
|
||||
@@ -105,8 +106,8 @@ class APIGenerate():
|
||||
p = StableDiffusionProcessingTxt2Img(sd_model=shared.sd_model, **args)
|
||||
self.prepare_ip_adapter(txt2imgreq, p)
|
||||
p.scripts = script_runner
|
||||
p.outpath_grids = shared.opts.outdir_grids or shared.opts.outdir_txt2img_grids
|
||||
p.outpath_samples = shared.opts.outdir_samples or shared.opts.outdir_txt2img_samples
|
||||
p.outpath_grids = resolve_output_path(shared.opts.outdir_grids, shared.opts.outdir_txt2img_grids)
|
||||
p.outpath_samples = resolve_output_path(shared.opts.outdir_samples, shared.opts.outdir_txt2img_samples)
|
||||
for key, value in getattr(txt2imgreq, "extra", {}).items():
|
||||
setattr(p, key, value)
|
||||
jobid = shared.state.begin('API-TXT', api=True)
|
||||
@@ -157,8 +158,8 @@ class APIGenerate():
|
||||
self.prepare_ip_adapter(img2imgreq, p)
|
||||
p.init_images = [helpers.decode_base64_to_image(x) for x in init_images]
|
||||
p.scripts = script_runner
|
||||
p.outpath_grids = shared.opts.outdir_img2img_grids
|
||||
p.outpath_samples = shared.opts.outdir_img2img_samples
|
||||
p.outpath_grids = resolve_output_path(shared.opts.outdir_grids, shared.opts.outdir_img2img_grids)
|
||||
p.outpath_samples = resolve_output_path(shared.opts.outdir_samples, shared.opts.outdir_img2img_samples)
|
||||
for key, value in getattr(img2imgreq, "extra", {}).items():
|
||||
setattr(p, key, value)
|
||||
jobid = shared.state.begin('API-IMG', api=True)
|
||||
|
||||
@@ -18,6 +18,7 @@ from modules.processing_class import StableDiffusionProcessingControl
|
||||
from modules.ui_common import infotext_to_html
|
||||
from modules.api import script
|
||||
from modules.generation_parameters_copypaste import create_override_settings_dict
|
||||
from modules.paths import resolve_output_path
|
||||
|
||||
|
||||
debug = os.environ.get('SD_CONTROL_DEBUG', None) is not None
|
||||
@@ -402,8 +403,8 @@ def control_run(state: str = '', # pylint: disable=keyword-arg-before-vararg
|
||||
hdr_mode=hdr_mode, hdr_brightness=hdr_brightness, hdr_color=hdr_color, hdr_sharpen=hdr_sharpen, hdr_clamp=hdr_clamp,
|
||||
hdr_boundary=hdr_boundary, hdr_threshold=hdr_threshold, hdr_maximize=hdr_maximize, hdr_max_center=hdr_max_center, hdr_max_boundary=hdr_max_boundary, hdr_color_picker=hdr_color_picker, hdr_tint_ratio=hdr_tint_ratio,
|
||||
# path
|
||||
outpath_samples=shared.opts.outdir_samples or shared.opts.outdir_control_samples,
|
||||
outpath_grids=shared.opts.outdir_grids or shared.opts.outdir_control_grids,
|
||||
outpath_samples=resolve_output_path(shared.opts.outdir_samples, shared.opts.outdir_control_samples),
|
||||
outpath_grids=resolve_output_path(shared.opts.outdir_grids, shared.opts.outdir_control_grids),
|
||||
# overrides
|
||||
override_settings=extra
|
||||
)
|
||||
@@ -572,13 +573,13 @@ def control_run(state: str = '', # pylint: disable=keyword-arg-before-vararg
|
||||
|
||||
# what are we doing?
|
||||
if 'control' in p.ops:
|
||||
p.outpath_samples = shared.opts.outdir_samples or shared.opts.outdir_control_samples
|
||||
p.outpath_samples = resolve_output_path(shared.opts.outdir_samples, shared.opts.outdir_control_samples)
|
||||
elif 'img2img' in p.ops:
|
||||
p.outpath_samples = shared.opts.outdir_samples or shared.opts.outdir_img2img_samples
|
||||
p.outpath_samples = resolve_output_path(shared.opts.outdir_samples, shared.opts.outdir_img2img_samples)
|
||||
elif 'txt2img' in p.ops:
|
||||
p.outpath_samples = shared.opts.outdir_samples or shared.opts.outdir_txt2img_samples
|
||||
p.outpath_samples = resolve_output_path(shared.opts.outdir_samples, shared.opts.outdir_txt2img_samples)
|
||||
else: # fallback to txt2img
|
||||
p.outpath_samples = shared.opts.outdir_samples or shared.opts.outdir_txt2img_samples
|
||||
p.outpath_samples = resolve_output_path(shared.opts.outdir_samples, shared.opts.outdir_txt2img_samples)
|
||||
|
||||
# pipeline
|
||||
output = None
|
||||
|
||||
+26
-13
@@ -19,19 +19,32 @@ def check_tmp_file(gradio, filename):
|
||||
ok = False
|
||||
if hasattr(gradio, 'temp_file_sets'):
|
||||
ok = ok or any(filename in fileset for fileset in gradio.temp_file_sets)
|
||||
if shared.opts.outdir_samples != '':
|
||||
ok = ok or Path(shared.opts.outdir_samples).resolve() in Path(filename).resolve().parents
|
||||
else:
|
||||
ok = ok or Path(shared.opts.outdir_txt2img_samples).resolve() in Path(filename).resolve().parents
|
||||
ok = ok or Path(shared.opts.outdir_img2img_samples).resolve() in Path(filename).resolve().parents
|
||||
ok = ok or Path(shared.opts.outdir_extras_samples).resolve() in Path(filename).resolve().parents
|
||||
if shared.opts.outdir_grids != '':
|
||||
ok = ok or Path(shared.opts.outdir_grids).resolve() in Path(filename).resolve().parents
|
||||
else:
|
||||
ok = ok or Path(shared.opts.outdir_txt2img_grids).resolve() in Path(filename).resolve().parents
|
||||
ok = ok or Path(shared.opts.outdir_img2img_grids).resolve() in Path(filename).resolve().parents
|
||||
ok = ok or Path(shared.opts.outdir_save).resolve() in Path(filename).resolve().parents
|
||||
ok = ok or Path(shared.opts.outdir_init_images).resolve() in Path(filename).resolve().parents
|
||||
# Check resolved output paths (base + specific)
|
||||
base_samples = shared.opts.outdir_samples
|
||||
base_grids = shared.opts.outdir_grids
|
||||
resolved_paths = [
|
||||
paths.resolve_output_path(base_samples, shared.opts.outdir_txt2img_samples),
|
||||
paths.resolve_output_path(base_samples, shared.opts.outdir_img2img_samples),
|
||||
paths.resolve_output_path(base_samples, shared.opts.outdir_extras_samples),
|
||||
paths.resolve_output_path(base_samples, shared.opts.outdir_control_samples),
|
||||
paths.resolve_output_path(base_samples, shared.opts.outdir_save),
|
||||
paths.resolve_output_path(base_samples, shared.opts.outdir_video),
|
||||
paths.resolve_output_path(base_samples, shared.opts.outdir_init_images),
|
||||
paths.resolve_output_path(base_grids, shared.opts.outdir_txt2img_grids),
|
||||
paths.resolve_output_path(base_grids, shared.opts.outdir_img2img_grids),
|
||||
paths.resolve_output_path(base_grids, shared.opts.outdir_control_grids),
|
||||
]
|
||||
# Also check base folders directly if set
|
||||
if base_samples:
|
||||
resolved_paths.append(base_samples)
|
||||
if base_grids:
|
||||
resolved_paths.append(base_grids)
|
||||
for path in resolved_paths:
|
||||
if path:
|
||||
try:
|
||||
ok = ok or Path(path).resolve() in Path(filename).resolve().parents
|
||||
except Exception:
|
||||
pass
|
||||
return ok
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -164,7 +164,7 @@ def save_image(image,
|
||||
if not check_grid_size([image]):
|
||||
return None, None, None
|
||||
if path is None or path == '': # set default path to avoid errors when functions are triggered manually or via api and param is not set
|
||||
path = shared.opts.outdir_save
|
||||
path = paths.resolve_output_path(shared.opts.outdir_samples, shared.opts.outdir_save)
|
||||
namegen = FilenameGenerator(p, seed, prompt, image, grid=grid)
|
||||
suffix = suffix if suffix is not None else ''
|
||||
basename = '' if basename is None else basename
|
||||
|
||||
+3
-2
@@ -7,6 +7,7 @@ from modules import scripts_manager, shared, processing, images, errors
|
||||
from modules.generation_parameters_copypaste import create_override_settings_dict
|
||||
from modules.ui_common import plaintext_to_html
|
||||
from modules.memstats import memory_stats
|
||||
from modules.paths import resolve_output_path
|
||||
|
||||
|
||||
debug = shared.log.trace if os.environ.get('SD_PROCESS_DEBUG', None) is not None else lambda *args, **kwargs: None
|
||||
@@ -239,8 +240,8 @@ def img2img(id_task: str, state: str, mode: int,
|
||||
|
||||
p = processing.StableDiffusionProcessingImg2Img(
|
||||
sd_model=shared.sd_model,
|
||||
outpath_samples=shared.opts.outdir_samples or shared.opts.outdir_img2img_samples,
|
||||
outpath_grids=shared.opts.outdir_grids or shared.opts.outdir_img2img_grids,
|
||||
outpath_samples=resolve_output_path(shared.opts.outdir_samples, shared.opts.outdir_img2img_samples),
|
||||
outpath_grids=resolve_output_path(shared.opts.outdir_grids, shared.opts.outdir_img2img_grids),
|
||||
prompt=prompt,
|
||||
negative_prompt=negative_prompt,
|
||||
styles=prompt_styles,
|
||||
|
||||
@@ -57,6 +57,23 @@ def create_path(folder):
|
||||
log.error(f'Create failed: folder="{folder}" {e}')
|
||||
|
||||
|
||||
def resolve_output_path(base_path: str, specific_path: str) -> str:
|
||||
"""
|
||||
Resolve output path by combining base and specific paths.
|
||||
|
||||
- If specific_path is absolute, return it directly (base is ignored)
|
||||
- If base_path is set and specific_path is relative, join them
|
||||
- If base_path is empty/None, return specific_path as-is
|
||||
"""
|
||||
if not specific_path:
|
||||
return base_path or ''
|
||||
if os.path.isabs(specific_path):
|
||||
return specific_path
|
||||
if base_path:
|
||||
return os.path.normpath(os.path.join(base_path, specific_path))
|
||||
return specific_path
|
||||
|
||||
|
||||
def create_paths(opts):
|
||||
def fix_path(folder):
|
||||
tgt = None
|
||||
@@ -111,6 +128,22 @@ def create_paths(opts):
|
||||
create_path(fix_path('yolo_dir'))
|
||||
create_path(fix_path('wildcards_dir'))
|
||||
|
||||
# Create resolved output paths (base + specific)
|
||||
base_samples = opts.data.get('outdir_samples', '')
|
||||
base_grids = opts.data.get('outdir_grids', '')
|
||||
if base_samples:
|
||||
create_path(resolve_output_path(base_samples, opts.data.get('outdir_txt2img_samples', '')))
|
||||
create_path(resolve_output_path(base_samples, opts.data.get('outdir_img2img_samples', '')))
|
||||
create_path(resolve_output_path(base_samples, opts.data.get('outdir_control_samples', '')))
|
||||
create_path(resolve_output_path(base_samples, opts.data.get('outdir_extras_samples', '')))
|
||||
create_path(resolve_output_path(base_samples, opts.data.get('outdir_save', '')))
|
||||
create_path(resolve_output_path(base_samples, opts.data.get('outdir_video', '')))
|
||||
create_path(resolve_output_path(base_samples, opts.data.get('outdir_init_images', '')))
|
||||
if base_grids:
|
||||
create_path(resolve_output_path(base_grids, opts.data.get('outdir_txt2img_grids', '')))
|
||||
create_path(resolve_output_path(base_grids, opts.data.get('outdir_img2img_grids', '')))
|
||||
create_path(resolve_output_path(base_grids, opts.data.get('outdir_control_grids', '')))
|
||||
|
||||
|
||||
class Prioritize:
|
||||
def __init__(self, name):
|
||||
|
||||
@@ -6,6 +6,7 @@ from PIL import Image
|
||||
|
||||
from modules import shared, images, devices, scripts_manager, scripts_postprocessing, infotext
|
||||
from modules.shared import opts
|
||||
from modules.paths import resolve_output_path
|
||||
|
||||
|
||||
def run_postprocessing(extras_mode, image, image_folder: List[tempfile.NamedTemporaryFile], input_dir, output_dir, show_extras_results, *args, save_output: bool = True):
|
||||
@@ -58,7 +59,7 @@ def run_postprocessing(extras_mode, image, image_folder: List[tempfile.NamedTemp
|
||||
if extras_mode == 2 and output_dir != '':
|
||||
outpath = output_dir
|
||||
else:
|
||||
outpath = opts.outdir_samples or opts.outdir_extras_samples
|
||||
outpath = resolve_output_path(opts.outdir_samples, opts.outdir_extras_samples)
|
||||
processed_images = []
|
||||
for image, name, ext in zip(image_data, image_names, image_ext): # pylint: disable=redefined-argument-from-local
|
||||
shared.log.debug(f'Process: image={image} {args}')
|
||||
|
||||
@@ -7,6 +7,7 @@ from dataclasses import dataclass, field
|
||||
import numpy as np
|
||||
from PIL import Image, ImageOps
|
||||
from modules import shared, images, scripts_manager, masking, sd_models, sd_vae, processing_helpers
|
||||
from modules.paths import resolve_output_path
|
||||
|
||||
|
||||
debug = shared.log.trace if os.environ.get('SD_PROCESS_DEBUG', None) is not None else lambda *args, **kwargs: None
|
||||
@@ -537,7 +538,7 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
|
||||
self.init_img_width = getattr(self, 'init_img_width', img.width) # pylint: disable=attribute-defined-outside-init
|
||||
self.init_img_height = getattr(self, 'init_img_height', img.height) # pylint: disable=attribute-defined-outside-init
|
||||
if shared.opts.save_init_img:
|
||||
images.save_image(img, path=shared.opts.outdir_init_images, basename=None, forced_filename=self.init_img_hash, suffix="-init-image")
|
||||
images.save_image(img, path=resolve_output_path(shared.opts.outdir_samples, shared.opts.outdir_init_images), basename=None, forced_filename=self.init_img_hash, suffix="-init-image")
|
||||
image = images.flatten(img, shared.opts.img2img_background_color)
|
||||
if crop_region is None and self.resize_mode > 0:
|
||||
image = images.resize_image(self.resize_mode, image, self.width, self.height, upscaler_name=self.resize_name, context=self.resize_context)
|
||||
|
||||
+2
-2
@@ -558,7 +558,7 @@ options_templates.update(options_section(('saving-paths', "Image Paths"), {
|
||||
"directories_max_prompt_words": OptionInfo(8, "Max words", gr.Slider, {"minimum": 1, "maximum": 99, "step": 1, **hide_dirs}),
|
||||
|
||||
"outdir_sep_dirs": OptionInfo("<h2>Folders</h2>", "", gr.HTML),
|
||||
"outdir_samples": OptionInfo("", "Images folder", component_args=hide_dirs, folder=True),
|
||||
"outdir_samples": OptionInfo("", "Base images folder", component_args=hide_dirs, folder=True),
|
||||
"outdir_txt2img_samples": OptionInfo("outputs/text", 'Folder for text generate', component_args=hide_dirs, folder=True),
|
||||
"outdir_img2img_samples": OptionInfo("outputs/image", 'Folder for image generate', component_args=hide_dirs, folder=True),
|
||||
"outdir_control_samples": OptionInfo("outputs/control", 'Folder for control generate', component_args=hide_dirs, folder=True),
|
||||
@@ -568,7 +568,7 @@ options_templates.update(options_section(('saving-paths', "Image Paths"), {
|
||||
"outdir_init_images": OptionInfo("outputs/inputs", "Folder for init images", component_args=hide_dirs, folder=True),
|
||||
|
||||
"outdir_sep_grids": OptionInfo("<h2>Grids</h2>", "", gr.HTML),
|
||||
"outdir_grids": OptionInfo("", "Grids folder", component_args=hide_dirs, folder=True),
|
||||
"outdir_grids": OptionInfo("", "Base grids folde", component_args=hide_dirs, folder=True),
|
||||
"outdir_txt2img_grids": OptionInfo("outputs/grids", 'Folder for txt2img grids', component_args=hide_dirs, folder=True),
|
||||
"outdir_img2img_grids": OptionInfo("outputs/grids", 'Folder for img2img grids', component_args=hide_dirs, folder=True),
|
||||
"outdir_control_grids": OptionInfo("outputs/grids", 'Folder for control grids', component_args=hide_dirs, folder=True),
|
||||
|
||||
+3
-2
@@ -2,6 +2,7 @@ import os
|
||||
from modules import shared, processing, scripts_manager
|
||||
from modules.generation_parameters_copypaste import create_override_settings_dict
|
||||
from modules.ui_common import plaintext_to_html
|
||||
from modules.paths import resolve_output_path
|
||||
|
||||
|
||||
debug = shared.log.trace if os.environ.get('SD_PROCESS_DEBUG', None) is not None else lambda *args, **kwargs: None
|
||||
@@ -41,8 +42,8 @@ def txt2img(id_task, state,
|
||||
|
||||
p = processing.StableDiffusionProcessingTxt2Img(
|
||||
sd_model=shared.sd_model,
|
||||
outpath_samples=shared.opts.outdir_samples or shared.opts.outdir_txt2img_samples,
|
||||
outpath_grids=shared.opts.outdir_grids or shared.opts.outdir_txt2img_grids,
|
||||
outpath_samples=resolve_output_path(shared.opts.outdir_samples, shared.opts.outdir_txt2img_samples),
|
||||
outpath_grids=resolve_output_path(shared.opts.outdir_grids, shared.opts.outdir_txt2img_grids),
|
||||
prompt=prompt,
|
||||
styles=prompt_styles,
|
||||
negative_prompt=negative_prompt,
|
||||
|
||||
@@ -6,6 +6,7 @@ import platform
|
||||
import subprocess
|
||||
import gradio as gr
|
||||
from modules import call_queue, shared, errors, ui_sections, ui_symbols, ui_components, generation_parameters_copypaste, images, scripts_manager, script_callbacks, infotext, processing
|
||||
from modules.paths import resolve_output_path
|
||||
|
||||
|
||||
folder_symbol = ui_symbols.folder
|
||||
@@ -105,7 +106,7 @@ def delete_files(js_data, files, all_files, index):
|
||||
|
||||
|
||||
def save_files(js_data, files, html_info, index):
|
||||
os.makedirs(shared.opts.outdir_save, exist_ok=True)
|
||||
os.makedirs(resolve_output_path(shared.opts.outdir_samples, shared.opts.outdir_save), exist_ok=True)
|
||||
|
||||
class PObject: # pylint: disable=too-few-public-methods
|
||||
def __init__(self, d=None):
|
||||
@@ -127,7 +128,7 @@ def save_files(js_data, files, html_info, index):
|
||||
self.styles = getattr(self, 'styles', None) or getattr(self, 'Styles', None) or []
|
||||
self.styles = [s.strip() for s in self.styles.split(',')] if isinstance(self.styles, str) else self.styles
|
||||
|
||||
self.outpath_grids = shared.opts.outdir_grids or shared.opts.outdir_txt2img_grids
|
||||
self.outpath_grids = resolve_output_path(shared.opts.outdir_grids, shared.opts.outdir_txt2img_grids)
|
||||
self.infotexts = getattr(self, 'infotexts', [html_info])
|
||||
self.infotext = self.infotexts[0] if len(self.infotexts) > 0 else html_info
|
||||
self.all_negative_prompt = getattr(self, 'all_negative_prompts', [self.negative_prompt])
|
||||
@@ -161,14 +162,14 @@ def save_files(js_data, files, html_info, index):
|
||||
if 'name' in filedata and ('tmp' not in filedata['name']) and os.path.isfile(filedata['name']):
|
||||
fullfn = filedata['name']
|
||||
fullfns.append(fullfn)
|
||||
destination = shared.opts.outdir_save
|
||||
destination = resolve_output_path(shared.opts.outdir_samples, shared.opts.outdir_save)
|
||||
namegen = images.FilenameGenerator(p, seed=p.all_seeds[i], prompt=p.all_prompts[i], image=None) # pylint: disable=no-member
|
||||
dirname = namegen.apply(shared.opts.directories_filename_pattern or "[prompt_words]").lstrip(' ').rstrip('\\ /')
|
||||
destination = os.path.join(destination, dirname)
|
||||
destination = namegen.sanitize(destination)
|
||||
os.makedirs(destination, exist_ok = True)
|
||||
tgt_filename = os.path.join(destination, os.path.basename(fullfn))
|
||||
relfn = os.path.relpath(tgt_filename, shared.opts.outdir_save)
|
||||
relfn = os.path.relpath(tgt_filename, resolve_output_path(shared.opts.outdir_samples, shared.opts.outdir_save))
|
||||
filenames.append(relfn)
|
||||
if not os.path.exists(tgt_filename):
|
||||
try:
|
||||
@@ -201,14 +202,14 @@ def save_files(js_data, files, html_info, index):
|
||||
try:
|
||||
seed = p.all_seeds[i] if i < len(p.all_seeds) else p.seed
|
||||
prompt = p.all_prompts[i] if i < len(p.all_prompts) else p.prompt
|
||||
fullfn, txt_fullfn, _exif = images.save_image(image, shared.opts.outdir_save, "", seed=seed, prompt=prompt, info=info, extension=shared.opts.samples_format, grid=is_grid, p=p)
|
||||
fullfn, txt_fullfn, _exif = images.save_image(image, resolve_output_path(shared.opts.outdir_samples, shared.opts.outdir_save), "", seed=seed, prompt=prompt, info=info, extension=shared.opts.samples_format, grid=is_grid, p=p)
|
||||
except Exception as e:
|
||||
fullfn, txt_fullfn = None, None
|
||||
shared.log.error(f'Save: image={image} i={i} seeds={p.all_seeds} prompts={p.all_prompts}')
|
||||
errors.display(e, 'save')
|
||||
if fullfn is None:
|
||||
continue
|
||||
filename = os.path.relpath(fullfn, shared.opts.outdir_save)
|
||||
filename = os.path.relpath(fullfn, resolve_output_path(shared.opts.outdir_samples, shared.opts.outdir_save))
|
||||
filenames.append(filename)
|
||||
fullfns.append(fullfn)
|
||||
if txt_fullfn:
|
||||
@@ -216,7 +217,7 @@ def save_files(js_data, files, html_info, index):
|
||||
# fullfns.append(txt_fullfn)
|
||||
script_callbacks.image_save_btn_callback(filename)
|
||||
if shared.opts.samples_save_zip and len(fullfns) > 1:
|
||||
zip_filepath = os.path.join(shared.opts.outdir_save, "images.zip")
|
||||
zip_filepath = os.path.join(resolve_output_path(shared.opts.outdir_samples, shared.opts.outdir_save), "images.zip")
|
||||
from zipfile import ZipFile
|
||||
with ZipFile(zip_filepath, "w") as zip_file:
|
||||
for i in range(len(fullfns)):
|
||||
|
||||
@@ -3,6 +3,7 @@ import copy
|
||||
import time
|
||||
from modules import shared, errors, sd_models, processing, devices, images, ui_common
|
||||
from modules.video_models import models_def, video_utils, video_load, video_vae, video_overrides, video_save, video_prompt
|
||||
from modules.paths import resolve_output_path
|
||||
|
||||
|
||||
debug = shared.log.trace if os.environ.get('SD_VIDEO_DEBUG', None) is not None else lambda *args, **kwargs: None
|
||||
@@ -56,7 +57,7 @@ def generate(*args, **kwargs):
|
||||
p.state = ui_state
|
||||
p.do_not_save_grid = True
|
||||
p.do_not_save_samples = not mp4_frames
|
||||
p.outpath_samples = shared.opts.outdir_samples or shared.opts.outdir_video
|
||||
p.outpath_samples = resolve_output_path(shared.opts.outdir_samples, shared.opts.outdir_video)
|
||||
if 'T2V' in model:
|
||||
if init_image is not None:
|
||||
shared.log.warning('Video: op=T2V init image not supported')
|
||||
|
||||
Reference in New Issue
Block a user