Files
marcoc2-ComfyUI-AnotherUtils/__init__.py
T
Marco e1adac9396 Add GIF frame loading and deduplication nodes
- LoadGifFrames: loads GIF via Pillow (no OpenCV/FFmpeg), deduplicates
  identical frames using MD5 hash, outputs unique_frames batch + frame_map
  JSON for reconstruction. Alpha channel composited over white background.
- RemapGifFrames: decompressor node that expands deduplicated processed
  frames back to full sequence using frame_map.
- BatchToImageList: splits IMAGE batch [N,H,W,C] into list of N individual
  frames so ComfyUI iterates the pipeline per-frame, avoiding RAM spikes
  on VAE encode/decode with large GIF batches.
- js/load_gif_frames.js: upload widget for LoadGifFrames accepting .gif only.
2026-03-10 23:09:44 -03:00

132 lines
5.5 KiB
Python

"""
ComfyUI Animation Nodes
A collection of custom nodes for animation and character generation in ComfyUI
"""
__version__ = "1.0.0"
__author__ = "marcoags"
__package_name__ = "AnotherUtils"
from .custom_crop import CustomCropNode
from .smart_resize import SmartResizeNode
from .nearest_upscale import NearestUpscaleNode
from .load_images import LoadImagesOriginalSize
from .pixel_normalizer import PixelArtNormalizerNode
from .fighting_game_character import FightingGameCharacter
from .walking_pose import WalkingPoseGenerator
from .load_remove_alpha import LoadImageRemoveAlpha
from .pixel_art_converter import PixelArtConverterNode
from .pixel_art_converter_parallel import PixelArtConverterNodeParallel
from .last_image import LastImage
from .character_constructor import CharacterConstructor
from .character_generator import CharacterRandomizer
from .remove_alpha import RemoveAlphaNode
from .gimp_nodes.adaptive_noise import AdaptiveNoise
from .gimp_nodes.cie_lch_noise_gegl_like import CIELChNoiseGEGLLike
from .gimp_nodes.image_type_detector import ImageTypeDetector
from .gimp_nodes.mean_curvature_blur_gegl_like import MeanCurvatureBlurGEGLLike
from .gimp_nodes.rgb_noise_gegl_like import RGBNoiseGEGLLike
from .csv_prompt_loader import CSVPromptLoader
from .comparison_swipe import ComparisonSwipeNode
from .folder_video_concatenator import FolderVideoConcatenator
from .interactive_crop import InteractiveCropNode
from .caption_image_loader import CaptionImageLoader
from .video_audio_combiner import (
VideoAudioCombiner,
VideoAudioCombinerSimple,
HAS_NEW_VIDEO_API,
)
if HAS_NEW_VIDEO_API:
from .video_audio_combiner import VideoAudioCombinerV3
from .acestep_loader import AceStepLoKrLoader
from .audio_waveform_slicer import AudioWaveformSlicer
from .audio_slice_selector import AudioSliceSelector
from .audio_concatenate import AudioConcatenate
from .load_gif_frames import LoadGifFrames, RemapGifFrames
from .batch_image_list import BatchToImageList
from . import server_routes # Register Custom API Routes
NODE_CLASS_MAPPINGS = {
"CustomCrop": CustomCropNode,
"SmartResize": SmartResizeNode,
"NearestUpscale": NearestUpscaleNode,
"LoadImagesOriginal": LoadImagesOriginalSize,
"PixelArtNormalizer": PixelArtNormalizerNode,
"FightingGameCharacter": FightingGameCharacter,
"WalkingPoseGenerator": WalkingPoseGenerator,
"LoadImageRemoveAlpha": LoadImageRemoveAlpha,
"PixelArtConverter": PixelArtConverterNode,
"PixelArtConverterParallel": PixelArtConverterNodeParallel,
"LastImage": LastImage,
"CharacterConstructor": CharacterConstructor,
"CharacterRandomizer": CharacterRandomizer,
"RemoveAlpha": RemoveAlphaNode,
"AdaptiveNoise": AdaptiveNoise,
"CIELChNoiseGEGLLike": CIELChNoiseGEGLLike,
"ImageTypeDetector": ImageTypeDetector,
"MeanCurvatureBlurGEGLLike": MeanCurvatureBlurGEGLLike,
"RGBNoiseGEGLLike": RGBNoiseGEGLLike,
"CSVPromptLoader": CSVPromptLoader,
"ComparisonSwipe": ComparisonSwipeNode,
"FolderVideoConcatenator": FolderVideoConcatenator,
"InteractiveCrop": InteractiveCropNode,
"CaptionImageLoader": CaptionImageLoader,
"VideoAudioCombiner": VideoAudioCombiner,
"VideoAudioCombinerSimple": VideoAudioCombinerSimple,
"AceStepLoKrLoader": AceStepLoKrLoader,
"AudioWaveformSlicer": AudioWaveformSlicer,
"AudioSliceSelector": AudioSliceSelector,
"AudioConcatenate": AudioConcatenate,
"LoadGifFrames": LoadGifFrames,
"RemapGifFrames": RemapGifFrames,
"BatchToImageList": BatchToImageList,
}
# Add V3 nodes if the new API is available
if HAS_NEW_VIDEO_API:
NODE_CLASS_MAPPINGS["VideoAudioCombinerV3"] = VideoAudioCombinerV3
NODE_DISPLAY_NAME_MAPPINGS = {
"CustomCrop": "Custom Crop",
"SmartResize": "Smart Resize with Border Fill",
"NearestUpscale": "Nearest Neighbor Upscale",
"LoadImagesOriginal": "Load Images (Original Size)",
"PixelArtNormalizer": "Pixel Art Normalizer",
"FightingGameCharacter": "Fighting Game Character Generator",
"WalkingPoseGenerator": "Walking Pose Generator",
"LoadImageRemoveAlpha": "Load Image (Remove Alpha)",
"PixelArtConverterParallel": "Pixel Art Converter Parallel",
"LastImage": "Get Last Image",
"CharacterConstructor": "Character Constructor",
"CharacterRandomizer": "Character Randomizer",
"RemoveAlpha": "Remove Alpha Channel",
"AdaptiveNoise": "Adaptive Noise Filter",
"CIELChNoiseGEGLLike": "CIE LCH Noise (GEGL-like)",
"ImageTypeDetector": "Image Type Detector",
"MeanCurvatureBlurGEGLLike": "Mean Curvature Blur (GEGL-like)",
"RGBNoiseGEGLLike": "RGB Noise (GEGL-like)",
"CSVPromptLoader": "CSV Prompt Loader",
"ComparisonSwipe": "Comparison Swipe Video",
"FolderVideoConcatenator": "Folder Video Concatenator (OpenCV)",
"InteractiveCrop": "Interactive Crop",
"CaptionImageLoader": "Caption Image Loader",
"VideoAudioCombiner": "Video + Audio Combiner",
"VideoAudioCombinerSimple": "Video + Audio Combiner (Simple)",
"AceStepLoKrLoader": "AceStep LoKr Loader",
"AudioWaveformSlicer": "Audio Waveform Slicer",
"AudioSliceSelector": "Audio Slice Selector",
"AudioConcatenate": "Audio Concatenate",
"LoadGifFrames": "Load GIF Frames (Raw)",
"RemapGifFrames": "Remap GIF Frames",
"BatchToImageList": "Batch to Image List",
}
# Add V3 display names if available
if HAS_NEW_VIDEO_API:
NODE_DISPLAY_NAME_MAPPINGS["VideoAudioCombinerV3"] = "Video + Audio Combiner (V3)"
WEB_DIRECTORY = "./js"
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"]