177 lines
7.2 KiB
JavaScript
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();
|
|
}
|
|
};
|
|
}
|
|
}
|
|
});
|