Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
Python Linting / Run Pylint (push) Has been cancelled
Full Comfy CI Workflow Runs / test-stable (12.1, , linux, 3.10, [self-hosted Linux], stable) (push) Has been cancelled
Full Comfy CI Workflow Runs / test-stable (12.1, , linux, 3.11, [self-hosted Linux], stable) (push) Has been cancelled
Full Comfy CI Workflow Runs / test-stable (12.1, , linux, 3.12, [self-hosted Linux], stable) (push) Has been cancelled
Full Comfy CI Workflow Runs / test-unix-nightly (12.1, , linux, 3.11, [self-hosted Linux], nightly) (push) Has been cancelled
Execution Tests / test (macos-latest) (push) Has been cancelled
Execution Tests / test (ubuntu-latest) (push) Has been cancelled
Execution Tests / test (windows-latest) (push) Has been cancelled
Test server launches without errors / test (push) Has been cancelled
Unit Tests / test (macos-latest) (push) Has been cancelled
Unit Tests / test (ubuntu-latest) (push) Has been cancelled
Unit Tests / test (windows-2022) (push) Has been cancelled
Includes 30 custom nodes committed directly, 7 Civitai-exclusive loras stored via Git LFS, and a setup script that installs all dependencies and downloads HuggingFace-hosted models on vast.ai. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
75 lines
3.5 KiB
JavaScript
75 lines
3.5 KiB
JavaScript
import { app } from '../../scripts/app.js'
|
|
import { ExifReader } from './lib/exif-reader.js' // https://github.com/mattiasw/ExifReader v4.26.2
|
|
|
|
const SETTING_CATEGORY_NAME = "Image Saver";
|
|
const SETTING_SECTION_FILE_HANDLING = "File Handling";
|
|
|
|
app.registerExtension({
|
|
name: "ComfyUI-Image-Saver",
|
|
settings: [
|
|
{
|
|
id: "ImageSaver.HandleImageWorkflowDrop",
|
|
name: "Use a custom file drop handler to load workflows from JPEG and WEBP files",
|
|
type: "boolean",
|
|
defaultValue: true,
|
|
category: [SETTING_CATEGORY_NAME, SETTING_SECTION_FILE_HANDLING, "Custom File Drop Handler"],
|
|
tooltip:
|
|
"Use a custom file handler for dropped JPEG and WEBP files.\n" +
|
|
"This is needed to load embedded workflows.\n" +
|
|
"Only disable this if it interferes with another extension's file drop handler.",
|
|
},
|
|
],
|
|
async setup() {
|
|
// Save original function, reassign to our own handler
|
|
const handleFileOriginal = app.handleFile;
|
|
app.handleFile = async function (file) {
|
|
if (app.ui.settings.getSettingValue("ImageSaver.HandleImageWorkflowDrop") && (file.type === "image/jpeg" || file.type === "image/webp")) {
|
|
try {
|
|
const exifTags = await ExifReader.load(file);
|
|
|
|
const workflowString = "workflow:";
|
|
const promptString = "prompt:";
|
|
let workflow;
|
|
let prompt;
|
|
// Search Exif tag data for workflow and prompt
|
|
Object.values(exifTags).some(value => {
|
|
try {
|
|
const description = `${value.description}`;
|
|
if (workflow === undefined && description.slice(0, workflowString.length).toLowerCase() === workflowString) {
|
|
workflow = JSON.parse(description.slice(workflowString.length));
|
|
} else if (prompt === undefined && description.slice(0, promptString.length).toLowerCase() === promptString) {
|
|
prompt = JSON.parse(description.slice(promptString.length));
|
|
}
|
|
} catch (error) {
|
|
if (!(error instanceof SyntaxError)) {
|
|
console.error(`ComfyUI-Image-Saver: Error reading Exif value: ${error}`);
|
|
}
|
|
}
|
|
|
|
return workflow !== undefined;
|
|
});
|
|
|
|
if (workflow !== undefined) {
|
|
// Remove file extension
|
|
let filename = file.name;
|
|
let dot = filename.lastIndexOf('.');
|
|
if (dot !== -1) {
|
|
filename = filename.slice(0, dot);
|
|
}
|
|
|
|
app.loadGraphData(workflow, true, true, filename);
|
|
return;
|
|
} else if (prompt !== undefined) {
|
|
app.loadApiJson(prompt);
|
|
return;
|
|
}
|
|
} catch (error) {
|
|
console.error(`ComfyUI-Image-Saver: Error parsing Exif: ${error}`);
|
|
}
|
|
}
|
|
|
|
// Fallback to original function
|
|
handleFileOriginal.call(this, file);
|
|
}
|
|
},
|
|
}) |