Functions/GenXdev.AI.ComfyUI/Set-ComfyUIBackgroundImage.cs
// ################################################################################
// Part of PowerShell module : GenXdev.AI.ComfyUI // Original cmdlet filename : Set-ComfyUIBackgroundImage.cs // Original author : René Vaessen / GenXdev // Version : 1.302.2025 // ################################################################################ // Copyright (c) René Vaessen / GenXdev // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ################################################################################ using System; using System.Collections; using System.IO; using System.Management.Automation; using System.Web; namespace GenXdev.AI.ComfyUI { /// <summary> /// <para type="synopsis"> /// Sets or clears the background image for ComfyUI's canvas interface /// </para> /// /// <para type="description"> /// Configures ComfyUI to display a custom background image in the canvas area by /// updating the comfy.settings.json file. The function handles copying the image /// to the appropriate ComfyUI directory and updating the configuration settings. /// /// The background image is displayed behind the workflow nodes in ComfyUI's main /// canvas area, providing visual customization of the interface. Images are /// automatically copied to ComfyUI's input/backgrounds/ directory structure. /// </para> /// /// <para type="description"> /// PARAMETERS /// </para> /// /// <para type="description"> /// -ImagePath <string><br/> /// Path to the image file to use as the background. Supported formats include /// PNG, JPG, JPEG, GIF, BMP, and WEBP. The image will be copied to ComfyUI's /// backgrounds directory and referenced in the settings.<br/> /// - <b>Position</b>: 0<br/> /// - <b>ParameterSet</b>: SetImage<br/> /// </para> /// /// <para type="description"> /// -Clear <SwitchParameter><br/> /// Removes the background image configuration from ComfyUI, returning the canvas /// to its default appearance without a background image.<br/> /// - <b>ParameterSet</b>: Clear<br/> /// </para> /// /// <example> /// <para>Sets the specified image as ComfyUI's canvas background. The image will be /// copied to the ComfyUI backgrounds directory and configured in settings.</para> /// <code> /// Set-ComfyUIBackgroundImage -ImagePath "C:\Pictures\my-background.png" /// </code> /// </example> /// /// <example> /// <para>Sets abstract-art.jpg as the background image for ComfyUI's canvas interface.</para> /// <code> /// Set-ComfyUIBackgroundImage "D:\Images\abstract-art.jpg" /// </code> /// </example> /// /// <example> /// <para>Removes the current background image configuration, restoring ComfyUI's /// default canvas appearance without a background image.</para> /// <code> /// Set-ComfyUIBackgroundImage -Clear /// </code> /// </example> /// </summary> [Cmdlet(VerbsCommon.Set, "ComfyUIBackgroundImage")] [OutputType(typeof(void))] public partial class SetComfyUIBackgroundImageCommand : PSGenXdevCmdlet { /// <summary> /// Path to the image file to set as background /// </summary> [Parameter( Mandatory = true, Position = 0, ParameterSetName = "SetImage", HelpMessage = "Path to the image file to set as background")] [ValidateNotNullOrEmpty] public string ImagePath { get; set; } /// <summary> /// Remove the background image configuration /// </summary> [Parameter( Mandatory = true, ParameterSetName = "Clear", HelpMessage = "Remove the background image configuration")] public SwitchParameter Clear { get; set; } /// <summary> /// Begin processing - initialization logic /// </summary> protected override void BeginProcessing() { // Get ComfyUI base path var scriptBlock = ScriptBlock.Create("GenXdev.AI\\Get-ComfyUIModelPath -Verbose:$false"); var result = scriptBlock.Invoke(); var comfyPath = result.Count > 0 ? result[0]?.ToString() : null; if (string.IsNullOrEmpty(comfyPath)) { var errorRecord = new ErrorRecord( new InvalidOperationException("Could not determine ComfyUI installation path. Please ensure ComfyUI is properly configured."), "ComfyUIPathNotFound", ErrorCategory.InvalidOperation, null); WriteError(errorRecord); return; } // Define paths var settingsPath = Path.Combine(comfyPath, "user", "default", "comfy.settings.json"); var backgroundsDir = Path.Combine(comfyPath, "input", "backgrounds"); WriteVerbose($"ComfyUI path: {comfyPath}"); WriteVerbose($"Settings file: {settingsPath}"); WriteVerbose($"Backgrounds directory: {backgroundsDir}"); // Store in private fields for ProcessRecord this.comfyPath = comfyPath; this.settingsPath = settingsPath; this.backgroundsDir = backgroundsDir; } /// <summary> /// Process record - main cmdlet logic /// </summary> protected override void ProcessRecord() { // Ensure settings file exists if (!File.Exists(this.settingsPath)) { var errorRecord = new ErrorRecord( new FileNotFoundException($"ComfyUI settings file not found at: {this.settingsPath}\nPlease ensure ComfyUI has been run at least once."), "SettingsFileNotFound", ErrorCategory.ObjectNotFound, this.settingsPath); WriteError(errorRecord); return; } // Read current settings PSObject settingsContent; try { var jsonContent = File.ReadAllText(this.settingsPath); var jsonResult = ConvertFromJson(jsonContent); settingsContent = jsonResult.Length > 0 ? (PSObject)jsonResult[0] : new PSObject(); } catch (Exception ex) { var errorRecord = new ErrorRecord( new InvalidOperationException($"Failed to read ComfyUI settings file: {ex.Message}"), "SettingsReadError", ErrorCategory.ReadError, this.settingsPath); WriteError(errorRecord); return; } if (Clear.ToBool()) { // Remove background image setting if (settingsContent.Properties["Comfy.Canvas.BackgroundImage"] != null) { settingsContent.Properties.Remove("Comfy.Canvas.BackgroundImage"); WriteVerbose("Removed background image setting from ComfyUI configuration"); } else { WriteVerbose("No background image was configured"); } } else { // Validate ImagePath if (!File.Exists(ImagePath)) { var errorRecord = new ErrorRecord( new FileNotFoundException($"Image file does not exist: {ImagePath}"), "ImageFileNotFound", ErrorCategory.ObjectNotFound, ImagePath); WriteError(errorRecord); return; } var extension = Path.GetExtension(ImagePath).ToLower(); var supportedFormats = new[] { ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".webp" }; if (Array.IndexOf(supportedFormats, extension) == -1) { var errorRecord = new ErrorRecord( new ArgumentException($"Unsupported image format. Supported formats: {string.Join(", ", supportedFormats)}"), "UnsupportedImageFormat", ErrorCategory.InvalidArgument, ImagePath); WriteError(errorRecord); return; } // Ensure backgrounds directory exists if (!Directory.Exists(this.backgroundsDir)) { Directory.CreateDirectory(this.backgroundsDir); WriteVerbose($"Created backgrounds directory: {this.backgroundsDir}"); } // Get image filename and copy to backgrounds directory var imageFileName = Path.GetFileName(ImagePath); var destinationPath = Path.Combine(this.backgroundsDir, imageFileName); try { File.Copy(ImagePath, destinationPath, true); WriteVerbose($"Copied background image to: {destinationPath}"); } catch (Exception ex) { var errorRecord = new ErrorRecord( new IOException($"Failed to copy image file: {ex.Message}"), "ImageCopyError", ErrorCategory.WriteError, ImagePath); WriteError(errorRecord); return; } // URL encode the filename for ComfyUI API var encodedFileName = HttpUtility.UrlEncode($"backgrounds/{imageFileName}"); var backgroundUrl = $"/api/view?filename={encodedFileName}&type=input&subfolder=backgrounds"; // Update settings with background image URL settingsContent.Properties.Add(new PSNoteProperty("Comfy.Canvas.BackgroundImage", backgroundUrl)); WriteVerbose($"Set background image URL: {backgroundUrl}"); } // Write updated settings back to file try { var jsonOutput = ConvertToJson(settingsContent, 10); File.WriteAllText(this.settingsPath, jsonOutput, System.Text.Encoding.UTF8); WriteVerbose("Updated ComfyUI settings file"); } catch (Exception ex) { var errorRecord = new ErrorRecord( new IOException($"Failed to update settings file: {ex.Message}"), "SettingsWriteError", ErrorCategory.WriteError, this.settingsPath); WriteError(errorRecord); return; } // Output result if (Clear.ToBool()) { var scriptBlock = ScriptBlock.Create("param($msg, $color) Write-Host $msg -ForegroundColor $color"); Console.WriteLine("Background image cleared from ComfyUI configuration", "Green"); Console.WriteLine("Restart ComfyUI for changes to take effect", "Yellow"); } else { var imageFileName = Path.GetFileName(ImagePath); var scriptBlock = ScriptBlock.Create("param($msg, $color) Write-Host $msg -ForegroundColor $color"); Console.WriteLine($"Background image set successfully: {imageFileName}", "Green"); Console.WriteLine($"Image location: {Path.Combine(this.backgroundsDir, imageFileName)}", "Cyan"); Console.WriteLine("Restart ComfyUI for changes to take effect", "Yellow"); } } /// <summary> /// End processing - cleanup logic /// </summary> protected override void EndProcessing() { // No cleanup needed } private string comfyPath; private string settingsPath; private string backgroundsDir; } } |