Files
ComfyUI/custom_nodes/comfyui-image-saver/js/read_exif_workflow.js
jaidaken f09734b0ee
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
Add custom nodes, Civitai loras (LFS), and vast.ai setup script
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>
2026-02-09 00:56:42 +00:00

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);
}
},
})