From 207bacc1f8917d46ae15542d6876c15eac5ace47 Mon Sep 17 00:00:00 2001 From: Dariusz L Date: Sun, 27 Jul 2025 18:47:41 +0200 Subject: [PATCH] Refactor image and mask utility functions Moved convertToImage, createMaskFromImageSrc, and canvasToMaskImage from MaskProcessingUtils and mask_utils to ImageUtils for better modularity and reuse. Updated imports in dependent modules to use the new locations. Removed duplicate implementations from mask_utils and MaskProcessingUtils. --- js/MaskEditorIntegration.js | 3 +- js/SAMDetectorIntegration.js | 3 +- js/utils/ImageUtils.js | 46 ++++++++++++++++++++++++++++ js/utils/MaskProcessingUtils.js | 17 ----------- js/utils/mask_utils.js | 29 ++---------------- src/MaskEditorIntegration.ts | 3 +- src/SAMDetectorIntegration.ts | 3 +- src/utils/ImageUtils.ts | 52 ++++++++++++++++++++++++++++++++ src/utils/MaskProcessingUtils.ts | 22 +------------- src/utils/mask_utils.ts | 30 ++---------------- 10 files changed, 113 insertions(+), 95 deletions(-) diff --git a/js/MaskEditorIntegration.js b/js/MaskEditorIntegration.js index 3637bcd..8daa8e1 100644 --- a/js/MaskEditorIntegration.js +++ b/js/MaskEditorIntegration.js @@ -4,7 +4,8 @@ import { app } from "../../scripts/app.js"; import { ComfyApp } from "../../scripts/app.js"; import { createModuleLogger } from "./utils/LoggerUtils.js"; import { uploadImageBlob } from "./utils/ImageUploadUtils.js"; -import { processImageToMask, processMaskForViewport, convertToImage } from "./utils/MaskProcessingUtils.js"; +import { processImageToMask, processMaskForViewport } from "./utils/MaskProcessingUtils.js"; +import { convertToImage } from "./utils/ImageUtils.js"; import { updateNodePreview } from "./utils/PreviewUtils.js"; import { mask_editor_showing, mask_editor_listen_for_cancel } from "./utils/mask_utils.js"; const log = createModuleLogger('MaskEditorIntegration'); diff --git a/js/SAMDetectorIntegration.js b/js/SAMDetectorIntegration.js index 05db148..af183e7 100644 --- a/js/SAMDetectorIntegration.js +++ b/js/SAMDetectorIntegration.js @@ -3,7 +3,8 @@ import { ComfyApp } from "../../scripts/app.js"; import { createModuleLogger } from "./utils/LoggerUtils.js"; import { showInfoNotification, showSuccessNotification, showErrorNotification } from "./utils/NotificationUtils.js"; import { uploadCanvasAsImage, uploadImageBlob } from "./utils/ImageUploadUtils.js"; -import { processImageToMask, convertToImage } from "./utils/MaskProcessingUtils.js"; +import { processImageToMask } from "./utils/MaskProcessingUtils.js"; +import { convertToImage } from "./utils/ImageUtils.js"; import { updateNodePreview } from "./utils/PreviewUtils.js"; const log = createModuleLogger('SAMDetectorIntegration'); /** diff --git a/js/utils/ImageUtils.js b/js/utils/ImageUtils.js index 86b33c7..0ec7c7f 100644 --- a/js/utils/ImageUtils.js +++ b/js/utils/ImageUtils.js @@ -268,3 +268,49 @@ export const createEmptyImage = withErrorHandling(function (width, height, color } throw new Error("Canvas context not available"); }, 'createEmptyImage'); +/** + * Converts a canvas or image to an Image element + * Consolidated from MaskProcessingUtils.convertToImage() + * @param source - Source canvas or image + * @returns Promise with Image element + */ +export async function convertToImage(source) { + if (source instanceof HTMLImageElement) { + return source; // Already an image + } + const image = new Image(); + image.src = source.toDataURL(); + await new Promise((resolve, reject) => { + image.onload = () => resolve(); + image.onerror = reject; + }); + return image; +} +/** + * Creates a mask from image source for use in mask editor + * Consolidated from mask_utils.create_mask_from_image_src() + * @param imageSrc - Image source (URL or data URL) + * @returns Promise returning Image object + */ +export function createMaskFromImageSrc(imageSrc) { + return new Promise((resolve, reject) => { + const img = new Image(); + img.onload = () => resolve(img); + img.onerror = (err) => reject(err); + img.src = imageSrc; + }); +} +/** + * Converts canvas to Image for use as mask + * Consolidated from mask_utils.canvas_to_mask_image() + * @param canvas - Canvas to convert + * @returns Promise returning Image object + */ +export function canvasToMaskImage(canvas) { + return new Promise((resolve, reject) => { + const img = new Image(); + img.onload = () => resolve(img); + img.onerror = (err) => reject(err); + img.src = canvas.toDataURL(); + }); +} diff --git a/js/utils/MaskProcessingUtils.js b/js/utils/MaskProcessingUtils.js index 5f4dcaf..ae36b68 100644 --- a/js/utils/MaskProcessingUtils.js +++ b/js/utils/MaskProcessingUtils.js @@ -71,23 +71,6 @@ export async function processImageWithTransform(sourceImage, pixelTransform, opt tempCtx.putImageData(imageData, 0, 0); return tempCanvas; } -/** - * Converts a canvas or image to an Image element - * @param source - Source canvas or image - * @returns Promise with Image element - */ -export async function convertToImage(source) { - if (source instanceof HTMLImageElement) { - return source; // Already an image - } - const image = new Image(); - image.src = source.toDataURL(); - await new Promise((resolve, reject) => { - image.onload = () => resolve(); - image.onerror = reject; - }); - return image; -} /** * Crops an image to a specific region * @param sourceImage - Source image or canvas diff --git a/js/utils/mask_utils.js b/js/utils/mask_utils.js index 4983607..671405b 100644 --- a/js/utils/mask_utils.js +++ b/js/utils/mask_utils.js @@ -143,29 +143,6 @@ export function start_mask_editor_auto(canvasInstance) { } canvasInstance.startMaskEditor(null, true); } -/** - * Tworzy maskę z obrazu dla użycia w mask editorze - * @param {string} imageSrc - Źródło obrazu (URL lub data URL) - * @returns {Promise} Promise zwracający obiekt Image - */ -export function create_mask_from_image_src(imageSrc) { - return new Promise((resolve, reject) => { - const img = new Image(); - img.onload = () => resolve(img); - img.onerror = (err) => reject(err); - img.src = imageSrc; - }); -} -/** - * Konwertuje canvas do Image dla użycia jako maska - * @param {HTMLCanvasElement} canvas - Canvas do konwersji - * @returns {Promise} Promise zwracający obiekt Image - */ -export function canvas_to_mask_image(canvas) { - return new Promise((resolve, reject) => { - const img = new Image(); - img.onload = () => resolve(img); - img.onerror = (err) => reject(err); - img.src = canvas.toDataURL(); - }); -} +// Duplikowane funkcje zostały przeniesione do ImageUtils.ts: +// - create_mask_from_image_src -> createMaskFromImageSrc +// - canvas_to_mask_image -> canvasToMaskImage diff --git a/src/MaskEditorIntegration.ts b/src/MaskEditorIntegration.ts index 157648e..e494309 100644 --- a/src/MaskEditorIntegration.ts +++ b/src/MaskEditorIntegration.ts @@ -6,7 +6,8 @@ import {ComfyApp} from "../../scripts/app.js"; import {api} from "../../scripts/api.js"; import { createModuleLogger } from "./utils/LoggerUtils.js"; import { uploadCanvasAsImage, uploadCanvasWithMaskAsImage, uploadImageBlob } from "./utils/ImageUploadUtils.js"; -import { processImageToMask, processMaskForViewport, convertToImage } from "./utils/MaskProcessingUtils.js"; +import { processImageToMask, processMaskForViewport } from "./utils/MaskProcessingUtils.js"; +import { convertToImage } from "./utils/ImageUtils.js"; import { updateNodePreview } from "./utils/PreviewUtils.js"; import { mask_editor_showing, mask_editor_listen_for_cancel } from "./utils/mask_utils.js"; diff --git a/src/SAMDetectorIntegration.ts b/src/SAMDetectorIntegration.ts index a5fbe73..72e1919 100644 --- a/src/SAMDetectorIntegration.ts +++ b/src/SAMDetectorIntegration.ts @@ -4,7 +4,8 @@ import { ComfyApp } from "../../scripts/app.js"; import { createModuleLogger } from "./utils/LoggerUtils.js"; import { showInfoNotification, showSuccessNotification, showErrorNotification } from "./utils/NotificationUtils.js"; import { uploadCanvasAsImage, uploadImageBlob } from "./utils/ImageUploadUtils.js"; -import { processImageToMask, convertToImage } from "./utils/MaskProcessingUtils.js"; +import { processImageToMask } from "./utils/MaskProcessingUtils.js"; +import { convertToImage } from "./utils/ImageUtils.js"; import { updateNodePreview } from "./utils/PreviewUtils.js"; import type { ComfyNode } from './types'; diff --git a/src/utils/ImageUtils.ts b/src/utils/ImageUtils.ts index a180cc8..b5f1bd5 100644 --- a/src/utils/ImageUtils.ts +++ b/src/utils/ImageUtils.ts @@ -334,3 +334,55 @@ export const createEmptyImage = withErrorHandling(function (width: number, heigh } throw new Error("Canvas context not available"); }, 'createEmptyImage'); + +/** + * Converts a canvas or image to an Image element + * Consolidated from MaskProcessingUtils.convertToImage() + * @param source - Source canvas or image + * @returns Promise with Image element + */ +export async function convertToImage(source: HTMLCanvasElement | HTMLImageElement): Promise { + if (source instanceof HTMLImageElement) { + return source; // Already an image + } + + const image = new Image(); + image.src = source.toDataURL(); + + await new Promise((resolve, reject) => { + image.onload = () => resolve(); + image.onerror = reject; + }); + + return image; +} + +/** + * Creates a mask from image source for use in mask editor + * Consolidated from mask_utils.create_mask_from_image_src() + * @param imageSrc - Image source (URL or data URL) + * @returns Promise returning Image object + */ +export function createMaskFromImageSrc(imageSrc: string): Promise { + return new Promise((resolve, reject) => { + const img = new Image(); + img.onload = () => resolve(img); + img.onerror = (err) => reject(err); + img.src = imageSrc; + }); +} + +/** + * Converts canvas to Image for use as mask + * Consolidated from mask_utils.canvas_to_mask_image() + * @param canvas - Canvas to convert + * @returns Promise returning Image object + */ +export function canvasToMaskImage(canvas: HTMLCanvasElement): Promise { + return new Promise((resolve, reject) => { + const img = new Image(); + img.onload = () => resolve(img); + img.onerror = (err) => reject(err); + img.src = canvas.toDataURL(); + }); +} diff --git a/src/utils/MaskProcessingUtils.ts b/src/utils/MaskProcessingUtils.ts index 47f9060..b11a44d 100644 --- a/src/utils/MaskProcessingUtils.ts +++ b/src/utils/MaskProcessingUtils.ts @@ -1,5 +1,6 @@ import { createModuleLogger } from "./LoggerUtils.js"; import { createCanvas } from "./CommonUtils.js"; +import { convertToImage } from "./ImageUtils.js"; const log = createModuleLogger('MaskProcessingUtils'); @@ -119,27 +120,6 @@ export async function processImageWithTransform( return tempCanvas; } -/** - * Converts a canvas or image to an Image element - * @param source - Source canvas or image - * @returns Promise with Image element - */ -export async function convertToImage(source: HTMLCanvasElement | HTMLImageElement): Promise { - if (source instanceof HTMLImageElement) { - return source; // Already an image - } - - const image = new Image(); - image.src = source.toDataURL(); - - await new Promise((resolve, reject) => { - image.onload = () => resolve(); - image.onerror = reject; - }); - - return image; -} - /** * Crops an image to a specific region * @param sourceImage - Source image or canvas diff --git a/src/utils/mask_utils.ts b/src/utils/mask_utils.ts index 5be6cc9..17d0918 100644 --- a/src/utils/mask_utils.ts +++ b/src/utils/mask_utils.ts @@ -167,30 +167,6 @@ export function start_mask_editor_auto(canvasInstance: Canvas): void { canvasInstance.startMaskEditor(null, true); } -/** - * Tworzy maskę z obrazu dla użycia w mask editorze - * @param {string} imageSrc - Źródło obrazu (URL lub data URL) - * @returns {Promise} Promise zwracający obiekt Image - */ -export function create_mask_from_image_src(imageSrc: string): Promise { - return new Promise((resolve, reject) => { - const img = new Image(); - img.onload = () => resolve(img); - img.onerror = (err) => reject(err); - img.src = imageSrc; - }); -} - -/** - * Konwertuje canvas do Image dla użycia jako maska - * @param {HTMLCanvasElement} canvas - Canvas do konwersji - * @returns {Promise} Promise zwracający obiekt Image - */ -export function canvas_to_mask_image(canvas: HTMLCanvasElement): Promise { - return new Promise((resolve, reject) => { - const img = new Image(); - img.onload = () => resolve(img); - img.onerror = (err) => reject(err); - img.src = canvas.toDataURL(); - }); -} +// Duplikowane funkcje zostały przeniesione do ImageUtils.ts: +// - create_mask_from_image_src -> createMaskFromImageSrc +// - canvas_to_mask_image -> canvasToMaskImage