mirror of
https://github.com/Azornes/Comfyui-LayerForge.git
synced 2026-03-22 05:02:11 -03:00
171 lines
4.7 KiB
JavaScript
171 lines
4.7 KiB
JavaScript
import {logger, LogLevel} from "./logger.js";
|
|
|
|
// Inicjalizacja loggera dla modułu ImageUtils
|
|
const log = {
|
|
debug: (...args) => logger.debug('ImageUtils', ...args),
|
|
info: (...args) => logger.info('ImageUtils', ...args),
|
|
warn: (...args) => logger.warn('ImageUtils', ...args),
|
|
error: (...args) => logger.error('ImageUtils', ...args)
|
|
};
|
|
|
|
// Konfiguracja loggera dla modułu ImageUtils
|
|
logger.setModuleLevel('ImageUtils', LogLevel.INFO);
|
|
|
|
export function validateImageData(data) {
|
|
log.debug("Validating data structure:", {
|
|
hasData: !!data,
|
|
type: typeof data,
|
|
isArray: Array.isArray(data),
|
|
keys: data ? Object.keys(data) : null,
|
|
shape: data?.shape,
|
|
dataType: data?.data ? data.data.constructor.name : null,
|
|
fullData: data
|
|
});
|
|
|
|
if (!data) {
|
|
log.info("Data is null or undefined");
|
|
return false;
|
|
}
|
|
|
|
if (Array.isArray(data)) {
|
|
log.debug("Data is array, getting first element");
|
|
data = data[0];
|
|
}
|
|
|
|
if (!data || typeof data !== 'object') {
|
|
log.info("Invalid data type");
|
|
return false;
|
|
}
|
|
|
|
if (!data.data) {
|
|
log.info("Missing data property");
|
|
return false;
|
|
}
|
|
|
|
if (!(data.data instanceof Float32Array)) {
|
|
try {
|
|
data.data = new Float32Array(data.data);
|
|
} catch (e) {
|
|
log.error("Failed to convert data to Float32Array:", e);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
export function convertImageData(data) {
|
|
log.info("Converting image data:", data);
|
|
|
|
if (Array.isArray(data)) {
|
|
data = data[0];
|
|
}
|
|
|
|
const shape = data.shape;
|
|
const height = shape[1];
|
|
const width = shape[2];
|
|
const channels = shape[3];
|
|
const floatData = new Float32Array(data.data);
|
|
|
|
log.debug("Processing dimensions:", {height, width, channels});
|
|
|
|
const rgbaData = new Uint8ClampedArray(width * height * 4);
|
|
|
|
for (let h = 0; h < height; h++) {
|
|
for (let w = 0; w < width; w++) {
|
|
const pixelIndex = (h * width + w) * 4;
|
|
const tensorIndex = (h * width + w) * channels;
|
|
|
|
for (let c = 0; c < channels; c++) {
|
|
const value = floatData[tensorIndex + c];
|
|
rgbaData[pixelIndex + c] = Math.max(0, Math.min(255, Math.round(value * 255)));
|
|
}
|
|
|
|
rgbaData[pixelIndex + 3] = 255;
|
|
}
|
|
}
|
|
|
|
return {
|
|
data: rgbaData,
|
|
width: width,
|
|
height: height
|
|
};
|
|
}
|
|
|
|
export function applyMaskToImageData(imageData, maskData) {
|
|
log.info("Applying mask to image data");
|
|
|
|
const rgbaData = new Uint8ClampedArray(imageData.data);
|
|
const width = imageData.width;
|
|
const height = imageData.height;
|
|
|
|
const maskShape = maskData.shape;
|
|
const maskFloatData = new Float32Array(maskData.data);
|
|
|
|
log.debug(`Applying mask of shape: ${maskShape}`);
|
|
|
|
for (let h = 0; h < height; h++) {
|
|
for (let w = 0; w < width; w++) {
|
|
const pixelIndex = (h * width + w) * 4;
|
|
const maskIndex = h * width + w;
|
|
|
|
const alpha = maskFloatData[maskIndex];
|
|
rgbaData[pixelIndex + 3] = Math.max(0, Math.min(255, Math.round(alpha * 255)));
|
|
}
|
|
}
|
|
|
|
log.info("Mask application completed");
|
|
|
|
return {
|
|
data: rgbaData,
|
|
width: width,
|
|
height: height
|
|
};
|
|
}
|
|
|
|
export function prepareImageForCanvas(inputImage) {
|
|
log.info("Preparing image for canvas:", inputImage);
|
|
|
|
try {
|
|
if (Array.isArray(inputImage)) {
|
|
inputImage = inputImage[0];
|
|
}
|
|
|
|
if (!inputImage || !inputImage.shape || !inputImage.data) {
|
|
throw new Error("Invalid input image format");
|
|
}
|
|
|
|
const shape = inputImage.shape;
|
|
const height = shape[1];
|
|
const width = shape[2];
|
|
const channels = shape[3];
|
|
const floatData = new Float32Array(inputImage.data);
|
|
|
|
log.debug("Image dimensions:", {height, width, channels});
|
|
|
|
const rgbaData = new Uint8ClampedArray(width * height * 4);
|
|
|
|
for (let h = 0; h < height; h++) {
|
|
for (let w = 0; w < width; w++) {
|
|
const pixelIndex = (h * width + w) * 4;
|
|
const tensorIndex = (h * width + w) * channels;
|
|
|
|
for (let c = 0; c < channels; c++) {
|
|
const value = floatData[tensorIndex + c];
|
|
rgbaData[pixelIndex + c] = Math.max(0, Math.min(255, Math.round(value * 255)));
|
|
}
|
|
|
|
rgbaData[pixelIndex + 3] = 255;
|
|
}
|
|
}
|
|
|
|
return {
|
|
data: rgbaData,
|
|
width: width,
|
|
height: height
|
|
};
|
|
} catch (error) {
|
|
log.error("Error preparing image:", error);
|
|
throw new Error(`Failed to prepare image: ${error.message}`);
|
|
}
|
|
} |