Files
ShammiG-ComfyUI-Simple_Read…/web/Simple_Readable_Metadata_SG.js
T
2025-11-15 13:02:53 +05:30

177 lines
7.2 KiB
JavaScript

import { app } from "../../scripts/app.js";
app.registerExtension({
name: "SimpleReadableMetadataSG.display",
async beforeRegisterNodeDef(nodeType, nodeData, app) {
if (nodeData.name === "SimpleReadableMetadataSG") {
const onNodeCreated = nodeType.prototype.onNodeCreated;
nodeType.prototype.onNodeCreated = function () {
const result = onNodeCreated ? onNodeCreated.apply(this, arguments) : undefined;
// Set minimum width only on initial creation
const minWidth = 400; // Adjust this value as needed
if (this.size[0] < minWidth) {
this.size[0] = minWidth;
}
const imageWidget = this.widgets?.find((w) => w.name === "image");
if (imageWidget) {
const self = this;
let lastValue = imageWidget.value;
// Create a timer to check for value changes
const checkInterval = setInterval(() => {
if (imageWidget.value !== lastValue) {
lastValue = imageWidget.value;
if (imageWidget.value && typeof imageWidget.value === 'string') {
// Load and analyze the image
const img = new Image();
const imageUrl = `/view?filename=${encodeURIComponent(imageWidget.value)}&type=input&subfolder=`;
img.onload = function() {
const width = img.naturalWidth;
const height = img.naturalHeight;
// Calculate parameters
const resolution_mp = (width * height / 1_000_000).toFixed(2);
// GCD calculation
function gcd(a, b) {
while (b) {
let temp = b;
b = a % b;
a = temp;
}
return a;
}
const divisor = gcd(width, height);
const width_ratio = width / divisor;
const height_ratio = height / divisor;
const aspect_decimal = (width / height).toFixed(2);
// Find closest standard ratio
const standardRatios = [
[1.0, '1:1'], [1.25, '5:4'], [1.33333, '4:3'],
[1.5, '3:2'], [1.6, '16:10'], [1.66667, '5:3'],
[1.77778, '16:9'], [1.88889, '17:9'], [2.0, '2:1'],
[2.33333, '21:9'], [2.35, '2.35:1'], [2.39, '2.39:1'],
[2.4, '12:5']
];
let closestRatio = null;
let closestDiff = Infinity;
const aspectRatio = width / height;
for (const [value, label] of standardRatios) {
const diff = Math.abs(value - aspectRatio);
if (diff < closestDiff) {
closestDiff = diff;
closestRatio = label;
}
}
if (closestDiff > 0.05) {
closestRatio = null;
}
// Calculate tensor size
const tensorSizeMB = (width * height * 3 * 4 / (1024 * 1024)).toFixed(2);
// Create display lines
const line1 = `${width}x${height} | ${resolution_mp}MP`;
let line2;
if (closestRatio && closestRatio !== `${width_ratio}:${height_ratio}`) {
line2 = `Ratio: ${width_ratio}:${height_ratio} or ${aspect_decimal}:1 or ~${closestRatio}`;
} else {
line2 = `Ratio: ${width_ratio}:${height_ratio} or ${aspect_decimal}:1`;
}
const line3 = `Tensor Size: ${tensorSizeMB}MB`;
const showTensorWidget = self.widgets?.find((w) => w.name === "show_tensor_size");
const showTensor = showTensorWidget ? showTensorWidget.value : true;
// Store and redraw
if (showTensor) {
self.imageParamsText = [line1, line2, line3];
} else {
self.imageParamsText = [line1, line2,];
}
// Force redraw
app.graph.setDirtyCanvas(true, true);
};
img.onerror = function() {
console.error("Failed to load image:", imageUrl);
};
img.src = imageUrl;
}
}
}, 500); // Check every 500ms
// Clean up interval when node is removed
const onRemoved = this.onRemoved;
this.onRemoved = function() {
clearInterval(checkInterval);
if (onRemoved) {
onRemoved.apply(this, arguments);
}
};
}
return result;
};
const onConfigure = nodeType.prototype.onConfigure;
nodeType.prototype.onConfigure = function(info) {
onConfigure?.apply(this, arguments);
if (info.imageParamsText) {
this.imageParamsText = info.imageParamsText;
}
};
const onSerialize = nodeType.prototype.onSerialize;
nodeType.prototype.onSerialize = function(info) {
const data = onSerialize ? onSerialize.apply(this, arguments) : info;
if (this.imageParamsText) {
data.imageParamsText = this.imageParamsText;
}
return data;
};
const onExecuted = nodeType.prototype.onExecuted;
nodeType.prototype.onExecuted = function (message) {
onExecuted?.apply(this, arguments);
if (message.text) {
this.imageParamsText = message.text;
}
};
const origDrawForeground = nodeType.prototype.onDrawForeground;
nodeType.prototype.onDrawForeground = function (ctx) {
origDrawForeground?.apply(this, arguments);
if (this.imageParamsText) {
ctx.save();
ctx.font = "12px monospace";
ctx.fillStyle = "#ccc";
const textX = 10;
const lineHeight = 18;
// Position text at top
const startY = 25;
// Draw each line
this.imageParamsText.forEach((line, index) => {
const yPos = startY + (index * lineHeight);
ctx.fillText(line, textX, yPos);
});
ctx.restore();
}
};
}
}
});