Allow setting custom image directory for preview images
This commit is contained in:
+46
-14
@@ -7,6 +7,7 @@ from aiohttp import web
|
||||
|
||||
from .src.config_reader import ConfigReader
|
||||
from .src.save_preview_image import SavePreviewImage
|
||||
from .src.util import get_preview_image_path
|
||||
|
||||
WEB_DIRECTORY = "./web"
|
||||
API_PREFIX = "/SyntaxHighlighting"
|
||||
@@ -19,47 +20,57 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
}
|
||||
|
||||
|
||||
image_index = {}
|
||||
|
||||
|
||||
def load_image_index():
|
||||
images_dir = Path(get_preview_image_path())
|
||||
json_path = images_dir.joinpath("images.json")
|
||||
if not json_path.exists():
|
||||
return {}
|
||||
with open(json_path, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
return {img["filename"]: img["path"] for img in data.get("images", [])}
|
||||
|
||||
|
||||
def reload_image_index():
|
||||
global image_index
|
||||
image_index.clear()
|
||||
image_index.update(load_image_index())
|
||||
|
||||
|
||||
def index_images():
|
||||
"""
|
||||
Create a JSON index of all images in the web/images directory and its subfolders.
|
||||
"""
|
||||
try:
|
||||
# Get the script's directory and construct path to images using Path
|
||||
script_dir = Path(os.path.dirname(os.path.realpath(__file__)))
|
||||
images_dir = script_dir.joinpath("web", "images")
|
||||
|
||||
# Ensure directory exists
|
||||
images_dir = Path(get_preview_image_path())
|
||||
if not images_dir.exists():
|
||||
print(f"Warning: Directory not found: {images_dir}")
|
||||
return {"success": False}
|
||||
|
||||
# Get all image files recursively
|
||||
image_files = []
|
||||
for ext in [".png", ".jpg", ".jpeg", ".webp"]:
|
||||
image_files.extend(images_dir.rglob(f"*{ext}"))
|
||||
print(f"Found {len(image_files)} images in {images_dir}")
|
||||
|
||||
# Create image entries
|
||||
images = []
|
||||
for img_path in image_files:
|
||||
images.append(
|
||||
{
|
||||
"filename": img_path.stem,
|
||||
"path": str(img_path.relative_to(script_dir)).replace(
|
||||
"web", "extensions\\ComfyUI-Syntax-Highlight"
|
||||
),
|
||||
"path": str(img_path),
|
||||
}
|
||||
)
|
||||
|
||||
# Create output data
|
||||
output = {"images": images, "count": len(images)}
|
||||
|
||||
# Write JSON file
|
||||
json_path = images_dir.joinpath("images.json")
|
||||
with open(json_path, "w", encoding="utf-8") as f:
|
||||
json.dump(output, f, indent=2)
|
||||
|
||||
print(f"Created index with {len(images)} images at {json_path}")
|
||||
return_data = {"success": True, "count": len(images)}
|
||||
reload_image_index()
|
||||
return return_data
|
||||
|
||||
except Exception as e:
|
||||
@@ -67,7 +78,6 @@ def index_images():
|
||||
return {"success": False}
|
||||
|
||||
|
||||
# Create image index
|
||||
index_images()
|
||||
|
||||
|
||||
@@ -91,6 +101,7 @@ async def get_enabled(request):
|
||||
@PromptServer.instance.routes.get(f"{API_PREFIX}/index")
|
||||
async def index_images_endpoint(request):
|
||||
data = index_images()
|
||||
reload_image_index()
|
||||
return web.json_response(data)
|
||||
|
||||
|
||||
@@ -98,3 +109,24 @@ async def index_images_endpoint(request):
|
||||
async def favorites_endpoint(request):
|
||||
favorites = ConfigReader.get_setting("SyntaxHighlighting.favorites", [])
|
||||
return web.json_response({"favorites": favorites})
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get(f"{API_PREFIX}/images_json")
|
||||
async def serve_images_json(request):
|
||||
images_dir = Path(get_preview_image_path())
|
||||
json_path = images_dir.joinpath("images.json")
|
||||
if json_path.exists():
|
||||
return web.FileResponse(path=json_path)
|
||||
return web.Response(status=404, text="images.json not found")
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get(f"{API_PREFIX}/images/{{filename}}")
|
||||
async def serve_image(request):
|
||||
filename = request.match_info["filename"]
|
||||
if not filename:
|
||||
return web.Response(status=400, text="Filename is required")
|
||||
|
||||
img_path = image_index.get(filename)
|
||||
if img_path and Path(img_path).exists():
|
||||
return web.FileResponse(path=img_path)
|
||||
return web.Response(status=404, text="Image not found")
|
||||
|
||||
@@ -6,26 +6,19 @@ import folder_paths
|
||||
from PIL import Image
|
||||
from PIL.PngImagePlugin import PngInfo
|
||||
from comfy.cli_args import args
|
||||
from .util import get_preview_image_path
|
||||
|
||||
|
||||
class SavePreviewImage:
|
||||
def __init__(self):
|
||||
self.type = "temp"
|
||||
self.compress_level = 4
|
||||
base_dir = self.get_base_dir()
|
||||
self.output_dir = os.path.join(base_dir, "web/images")
|
||||
self.output_dir = get_preview_image_path()
|
||||
os.makedirs(self.output_dir, exist_ok=True)
|
||||
|
||||
self.temp_output_dir = folder_paths.get_temp_directory()
|
||||
self.prefix_append = "_temp_" + "".join(random.choice("abcdefghijklmnopqrstupvxyz") for x in range(5))
|
||||
|
||||
@classmethod
|
||||
def get_base_dir(cls):
|
||||
dir_path = os.path.dirname(os.path.realpath(__file__))
|
||||
if os.path.basename(dir_path) == "src":
|
||||
dir_path = os.path.dirname(dir_path)
|
||||
return dir_path
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
import os
|
||||
from .config_reader import ConfigReader
|
||||
|
||||
|
||||
def get_preview_image_path():
|
||||
path: str = ConfigReader.get_setting("SyntaxHighlighting.preview-image-save-path", "./web/images")
|
||||
base_dir = get_base_dir()
|
||||
|
||||
if path.startswith("./"):
|
||||
path = os.path.join(base_dir, path[2:])
|
||||
else:
|
||||
path = os.path.abspath(path)
|
||||
|
||||
return path
|
||||
|
||||
|
||||
def get_base_dir():
|
||||
dir_path = os.path.dirname(os.path.realpath(__file__))
|
||||
if os.path.basename(dir_path) == "src":
|
||||
dir_path = os.path.dirname(dir_path)
|
||||
return dir_path
|
||||
+6
-7
@@ -1,9 +1,8 @@
|
||||
import { SettingsHelper } from "./settings/ComfyHelper.js";
|
||||
import { settingsHelper, API_PREFIX } from "./settings.js";
|
||||
import { hexToRgb, leadingEdgeDebounce } from "./util.js";
|
||||
import { app } from "../../../scripts/app.js";
|
||||
import { api } from "../../../scripts/api.js";
|
||||
|
||||
const settingsHelper = new SettingsHelper("SyntaxHighlighting");
|
||||
let contextMenuObserver = null;
|
||||
let favoritesCache = null;
|
||||
|
||||
@@ -428,9 +427,9 @@ async function observeContextMenu(existingList) {
|
||||
document.head.appendChild(style);
|
||||
let images;
|
||||
try {
|
||||
images = await fetch(
|
||||
"/extensions/ComfyUI-Syntax-Highlight/images/images.json"
|
||||
).then((response) => response.json());
|
||||
images = await fetch(`${API_PREFIX}/images_json`).then((response) =>
|
||||
response.json()
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("Error fetching images.json:", error);
|
||||
images = { images: [] };
|
||||
@@ -483,7 +482,7 @@ async function addPreviewImage(entry, path, settings) {
|
||||
|
||||
// Create temporary image to get dimensions
|
||||
const tempImg = new Image();
|
||||
tempImg.src = path;
|
||||
tempImg.src = `${API_PREFIX}/images/${path.split("/").pop().split(".")[0]}`;
|
||||
|
||||
// Wait for image to load to get actual dimensions
|
||||
await new Promise((resolve) => {
|
||||
@@ -717,7 +716,7 @@ async function addPreviewImage(entry, path, settings) {
|
||||
// Create and position the actual preview image
|
||||
const preview = document.createElement("img");
|
||||
preview.className = "preview-image";
|
||||
preview.src = path;
|
||||
preview.src = `${API_PREFIX}/images/${path.split("/").pop().split(".")[0]}`;
|
||||
preview.style.maxWidth = `${maxSize}px`;
|
||||
preview.style.maxHeight = `${maxSize}px`;
|
||||
preview.style.position = "fixed";
|
||||
|
||||
@@ -47,6 +47,17 @@ const settingsDefinitions = [
|
||||
type: SettingsHelper.ST.COLORPICKER,
|
||||
onChange: () => SettingsHelper.PresetOnChange.reloadSettings(),
|
||||
},
|
||||
{
|
||||
name: "Preview Image Save Path",
|
||||
category: [
|
||||
"Syntax Highlighting",
|
||||
"Preview Image",
|
||||
"PreviewImageSavePath",
|
||||
],
|
||||
defaultValue: "./web/images",
|
||||
type: SettingsHelper.ST.TEXT,
|
||||
onChange: () => SettingsHelper.PresetOnChange.reloadSettings(),
|
||||
},
|
||||
{
|
||||
name: "Preview Image Hover Delay",
|
||||
category: ["Syntax Highlighting", "Preview Image", "PreviewImageDelay"],
|
||||
|
||||
Reference in New Issue
Block a user