mcpField
C
comfyui-node-datatypes

comfyui-node-datatypes

github.com/jtydhr88開発308115 回インストール2 週間前に更新
リポジトリ

comfyui-node-datatypes について

ComfyUI のカスタムノードを開発する人向けのデータ型リファレンスです。テンソル、モデル、3D ファイル、ウィジェットなどの構造を説明します。

主な機能

  1. 01画像、マスク、潜在表現の形式
  2. 02音声、動画、条件付けデータの構造
  3. 03モデルと 3D 型のリファレンス
  4. 04ノードウィジェットの型
  5. 05特殊型と動的型の説明

活用シーン

  1. 01ノードの入出力形式の確認
  2. 02ComfyUI の画像や動画データの処理
  3. 03カスタムノードの型定義

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jtydhr88/comfyui-custom-node-skills --skill comfyui-node-datatypes

インストール後、Claude Code で/comfyui-node-datatypesを入力して読み込まれたか確認します。

詳細

ComfyUI のデータ型

ComfyUI では、ノードの入力と出力に特定のデータ型を使用します。テンソルの形状とデータ形式を理解することが重要です。

完全な型リファレンス

テンソル/データ型
型V3 クラス形式説明
IMAGEio.Imagetorch.Tensor [B,H,W,C] float32 0-1RGB 画像のバッチ
MASKio.Masktorch.Tensor [H,W] または [B,H,W] float32 0-1グレースケールのマスク
LATENTio.Latent{"samples": Tensor[B,C,H,W] or [B,C,T,H,W], "noise_mask"?: Tensor, "batch_index"?: list[int], "type"?: str}潜在空間(4D 画像/5D 動画)
CONDITIONINGio.Conditioninglist[tuple[Tensor, PooledDict]]プール出力を伴うテキストコンディショニング
AUDIOio.Audio{"waveform": Tensor[B,C,T], "sample_rate": int}オーディオデータ
VIDEOio.VideoVideoInput ABC動画データ(抽象基底クラス)
SIGMASio.Sigmastorch.Tensor 1D、長さは steps+1ノイズスケジュール
NOISEio.Noisegenerate_noise() を持つオブジェクトノイズジェネレーター
LORA_MODELio.LoraModeldict[str, torch.Tensor]LoRA の重み差分
LOSS_MAPio.LossMap{"loss": list[torch.Tensor]}損失マップ
TRACKSio.Tracks{"track_path": Tensor, "track_visibility": Tensor}モーショントラッキングデータ
WAN_CAMERA_EMBEDDINGio.WanCameraEmbeddingtorch.TensorWAN カメラ埋め込み
LATENT_OPERATIONio.LatentOperationCallable[[Tensor], Tensor]潜在変換関数
TIMESTEPS_RANGEio.TimestepsRangetuple[int, int]範囲 0.0-1.0
DICTio.Dictdict汎用辞書
ARRAYio.Arraylist汎用リスト/配列
LAYERSio.Layers{"version": int, "canvas"?: (w, h), "layers": list[LayerItem]}レイヤースタック(v0.31+);LayerItem:image テンソル、type: "raster"、z_index、省略可能な x、y、mask、name、opacity、blend_mode(io.Layers.BlendMode)、visible、flip_h/v、rotation、w、h
モデル型(不透明で、通常はそのまま受け渡します)
型V3 クラスPython 型
MODELio.ModelModelPatcher
CLIPio.ClipCLIP
VAEio.VaeVAE
CONTROL_NETio.ControlNetControlNet
CLIP_VISIONio.ClipVisionClipVisionModel
CLIP_VISION_OUTPUTio.ClipVisionOutputClipVisionOutput
STYLE_MODELio.StyleModelStyleModel
GLIGENio.GligenModelPatcher(Gligen をラップ)
UPSCALE_MODELio.UpscaleModelImageModelDescriptor
BACKGROUND_REMOVALio.BackgroundRemovalBackgroundRemovalModel(例:BiRefNet)
LATENT_UPSCALE_MODELio.LatentUpscaleModelAny
SAMPLERio.SamplerSampler
GUIDERio.GuiderCFGGuider
HOOKSio.HooksHookGroup
HOOK_KEYFRAMESio.HookKeyframesHookKeyframeGroup
MODEL_PATCHio.ModelPatchAny
AUDIO_ENCODERio.AudioEncoderAny
AUDIO_ENCODER_OUTPUTio.AudioEncoderOutputAny
PHOTOMAKERio.PhotomakerAny
POINTio.PointAny
FACE_ANALYSISio.FaceAnalysisAny
BBOXio.BBOXAny
SEGSio.SEGSAny
3D タイプ
タイプV3 クラスPython 型説明
MESHio.MeshMESH(vertices, faces)頂点と面のテンソルを持つ3Dメッシュ
VOXELio.VoxelVOXEL(data)ボクセルデータのテンソル
SPLATio.SplatSPLATガウシアンスプラットデータ
FILE_3Dio.File3DAnyFile3Dサポートされている任意の3D形式
FILE_3D_GLBio.File3DGLBFile3Dバイナリ glTF
FILE_3D_GLTFio.File3DGLTFFile3DJSONベースの glTF
FILE_3D_FBXio.File3DFBXFile3DFBX形式
FILE_3D_OBJio.File3DOBJFile3DOBJ形式
FILE_3D_STLio.File3DSTLFile3DSTL形式(3Dプリント用)
FILE_3D_USDZio.File3DUSDZFile3DApple AR形式
FILE_3D_PLYio.File3DPLYFile3DPLY(点群/スプラット)
FILE_3D_SPLATio.File3DSPLATFile3D.splat ガウシアンスプラットファイル
FILE_3D_SPZio.File3DSPZFile3D圧縮スプラット(.spz)
FILE_3D_KSPLATio.File3DKSPLATFile3D.ksplat 形式
FILE_3D_SPLAT_ANYio.File3DSplatAnyFile3D任意のスプラット形式
FILE_3D_POINT_CLOUD_ANYio.File3DPointCloudAnyFile3D任意の点群形式
SVGio.SVGSVG拡大縮小可能なベクターグラフィックス
LOAD_3Dio.Load3DModel3DDict(下記参照)レンダリングを含む3Dモデル
LOAD_3D_ANIMATIONio.Load3DAnimationLoad3D と同じアニメーション付き3Dモデル
LOAD3D_CAMERAio.Load3DCameraCameraInfo(下記参照)3Dカメラ情報
LOAD3D_MODEL_INFOio.Load3DModelInfolist[Model3DTransform]モデルごとの変換情報(位置/クォータニオン/スケール)

Load3D.Model3DDict: {"image": str, "mask": str, "normal": str, "camera_info": CameraInfo, "recording"?: str, "model_3d_info"?: list[Model3DTransform]}

Load3DCamera.CameraInfo(右手系、Y軸上向き、カメラは-Z方向を向きます): 必須キーは position、target、zoom、cameraType('perspective' | 'orthographic')です。オプションキーは quaternion(カメラのワールド回転)、useCustomUp(bool、v0.40以降:ワールドの+Yではなくクォータニオンの上方向を使用)、fov(垂直方向、度数、透視投影のみ)、aspect、near、far、frustum(正投影のみ:{left, right, top, bottom})です。

Load3DModelInfo.Model3DTransform: ワールド空間での {"position": dict, "quaternion": dict, "scale": dict} です。

ウィジェットタイプ(UIコントロールの作成)
タイプV3 クラスPython 型説明
INTio.Intint最小値/最大値/ステップを指定できる整数
FLOATio.Floatfloat最小値/最大値/ステップ/丸めを指定できる浮動小数点数
STRINGio.Stringstrテキスト(1行/複数行)
BOOLEANio.Booleanboolラベル付きの切り替え
COMBOio.Combostrドロップダウン選択
COMBO (multi)io.MultiCombolist[str]複数選択ドロップダウン
COLORio.Colorstr (hex)カラーピッカー、デフォルトは #ffffff
COLORSio.Colorslist[str] (hex)カラーパレット(色のリスト)
BOUNDING_BOXio.BoundingBox{"x": int, "y": int, "width": int, "height": int}矩形領域
BOUNDING_BOXESio.BoundingBoxeslist[{"x", "y", "width", "height", "metadata": dict}]複数のラベル付き領域
CURVEio.Curvelist[tuple[float, float]]スプライン曲線の点
RANGEio.RangeRangeInput(最小値/最大値+任意の中間値)グラデーション表示付きのレベル/範囲エディター
IMAGECOMPAREio.ImageComparedict画像比較ウィジェット
WEBCAMio.Webcamstrウェブカメラ撮影ウィジェット
HISTOGRAMio.Histogramlist[int]ヒストグラムのビン数
VIDEO_EDITio.VideoEdit{"trim"?: {start_time, duration}, "crop"?: {x, y, width, height}}動画のトリミング/クロップエディター(features=["trim","crop"])
RESOLUTION_PREVIEWio.ResolutionPreviewdict名前で他のウィジェットに紐付けられた、リアルタイムの解像度プレビュー
COMPOSITORio.Compositordict (LayerState)レイヤーエディターの状態、デフォルトは {}
CAMERA_INFO_STATEio.CameraInfoStatedictカメラエディターの状態(入力のみ)
特殊な型
型V3 クラス説明
* (ANY)io.AnyType任意の型に一致します
COMFY_MULTITYPED_V3io.MultiType1 つの入力で複数の特定の型を受け入れます
COMFY_MATCHTYPE_V3io.MatchType入力と出力をまたいで汎用的な型マッチングを行います
COMFY_AUTOGROW_V3io.Autogrow動的に拡張する入力です
COMFY_DYNAMICCOMBO_V3io.DynamicComboオプションごとにサブ入力を表示するコンボです
COMFY_DYNAMICSLOT_V3io.DynamicSlot接続時にサブ入力を表示する接続スロットです(コアノードではまだ使用されていません)
COMFY_DYNAMICGROUP_V3(internal _DynamicGroup)繰り返し表示されるウィジェット行です。エクスポートされず、安定していないため、使用しないでください(v1.57.0 以降、フロントエンドでサポート)
FLOW_CONTROLio.FlowControl内部テスト専用
ACCUMULATIONio.Accumulation内部テスト専用

IMAGE 型

画像は、形状が [B, H, W, C] の torch.Tensor です。

  • B = バッチサイズ(単一画像の場合は 1)
  • H = ピクセル単位の高さ
  • W = ピクセル単位の幅
  • C = チャンネル数(RGB の場合は 3、値の範囲は 0.0〜1.0)
import torch
import numpy as np
from PIL import Image as PILImage

class ImageProcessor(io.ComfyNode):
    @classmethod
    def define_schema(cls):
        return io.Schema(
            node_id="ImageProcessor",
            display_name="Image Processor",
            category="image",
            inputs=[io.Image.Input("image")],
            outputs=[io.Image.Output("IMAGE")],
        )

    @classmethod
    def execute(cls, image):
        b, h, w, c = image.shape
        result = torch.clamp(image * 1.5, 0.0, 1.0)
        return io.NodeOutput(result)
画像の読み込み/保存
from PIL import ImageOps

# Load from file → tensor
def load_image(path):
    img = PILImage.open(path)
    img = ImageOps.exif_transpose(img)   # fix rotation from camera EXIF
    if img.mode == "I":                  # handle 16-bit images
        img = img.point(lambda i: i * (1 / 255))
    img = img.convert("RGB")
    return torch.from_numpy(np.array(img).astype(np.float32) / 255.0).unsqueeze(0)

# Tensor → save to file
def save_image(tensor, path):
    if tensor.dim() == 4:
        tensor = tensor[0]
    PILImage.fromarray(np.clip(255.0 * tensor.cpu().numpy(), 0, 255).astype(np.uint8)).save(path)

# Batch operations
batch = torch.cat([img1, img2], dim=0)    # stack into batch
single = image[i]                          # extract from batch [H,W,C]
single_batch = image.unsqueeze(0)          # add batch dim [1,H,W,C]

MASK 型

形状が [H, W] または [B, H, W] で、値が 0.0〜1.0 の torch.Tensor です。

# Invert mask
inverted = 1.0 - mask

# Mask ↔ Image conversion
alpha = mask.unsqueeze(0).unsqueeze(-1)                   # [1,H,W,1]
gray_mask = 0.299*img[:,:,:,0] + 0.587*img[:,:,:,1] + 0.114*img[:,:,:,2]
image_from_mask = mask.unsqueeze(-1).repeat(1, 1, 1, 3)  # [B,H,W,3]

# Ensure batch dim
if mask.dim() == 2:
    mask = mask.unsqueeze(0)  # [1, H, W]

LATENT 型

型付きキーを持つ辞書です。

class LatentDict(TypedDict):
    samples: torch.Tensor       # [B, C, H, W] (image) or [B, C, T, H, W] (video) - required
    noise_mask: NotRequired[torch.Tensor]
    batch_index: NotRequired[list[int]]
    type: NotRequired[str]      # only for "audio", "hunyuan3dv2"

画像モデル(SD1.5、SDXL、SD3、Flux):4D [B, C, H, W] — SD1.5/SDXL は 4 チャンネル、SD3/Flux は 16 チャンネルです。潜在表現の寸法はピクセル寸法の 1/8 です。

動画モデル(Hunyuan Video、Wan、Cosmos、LTX Video、Mochi):5D [B, C, T, H, W] — T は時間(フレーム)方向の寸法です。

samples = latent["samples"]
# Check dimensionality:
if samples.ndim == 5:
    B, C, T, H, W = samples.shape   # video latent
else:
    B, C, H, W = samples.shape      # image latent

# Always preserve extra keys when modifying:
result = latent.copy()
result["samples"] = modified_samples

CONDITIONING 型

list[tuple[Tensor, PooledDict]] — (cond_tensor, metadata_dict) のペアのリストです。

PooledDict には、さまざまなモデル向けの多数の任意キーが含まれます。

class PooledDict(TypedDict):
    pooled_output: torch.Tensor
    control: NotRequired[ControlNet]
    area: NotRequired[tuple[int, ...]]
    strength: NotRequired[float]           # default 1.0
    mask: NotRequired[torch.Tensor]
    start_percent: NotRequired[float]      # 0.0-1.0
    end_percent: NotRequired[float]        # 0.0-1.0
    guidance: NotRequired[float]           # Flux-like models
    hooks: NotRequired[HookGroup]
    # ... many more model-specific keys (SDXL, SVD, WAN, etc.)

コンディショニングを結合するには、result = cond_a + cond_b とします(リストの連結)。

VIDEO 型

VideoInput は、次のメソッドを持つ抽象基底クラスです。

class VideoInput(ABC):
    def get_components(self) -> VideoComponents    # images tensor + audio + frame_rate
    def save_to(self, path, format=VideoContainer.AUTO, codec=VideoCodec.AUTO, metadata=None,
                bit_depth=None,     # None keeps native depth
                crf=None,           # H.264/AV1 CRF; None -> 18 (H.264) / 24 (AV1)
                color_space=None,   # "sRGB" | "HDR" (BT.2020 HLG) | "HDR PQ"
                preset=None)        # H.264 encoder preset, e.g. "ultrafast"
    def as_trimmed(self, start_time=None, duration=None, strict_duration=False) -> VideoInput | None
    def as_cropped(self, x=0, y=0, width=0, height=0) -> VideoInput  # clamped, even-aligned; empty/full rect = self
    def get_stream_source(self) -> str | BytesIO
    def get_dimensions(self) -> tuple[int, int]     # (width, height)
    def get_duration(self) -> float                  # seconds
    def get_frame_count(self) -> int
    def get_frame_rate(self) -> Fraction
    def get_container_format(self) -> str
    def get_bit_depth(self) -> int                   # max component bits of the stream, e.g. 8/10/12 (default 8)
    def get_color_space(self) -> str                 # "sRGB" | "HDR" | "HDR PQ" | "auto" (unknown)

高ビット深度と HDR(v0.34 以降)は、エンドツーエンドでサポートされています。ローダーは get_bit_depth()/get_color_space() を返し、保存ノードはそれらを保持します。コーデック:Types.VideoCodec.AUTO/H264/AV1。コンテナ:Types.VideoContainer.AUTO/MP4/MKV/WEBM。

具象実装(from comfy_api.latest import InputImpl 経由):

  • VideoFromFile(file, *, start_time=0, duration=0, crop=None) — パスまたは BytesIO。crop=(x, y, w, h)
  • VideoFromComponents(components, bit_depth=8, color_space="sRGB") — テンソルから作成
  • VideoFromList(videos, complete_audio=None, codec=AUTO) — 連結(v0.36 以降)

3D 型

File3D
from comfy_api.latest import Types

# File3D wraps a 3D file (disk path or BytesIO stream)
file_3d = Types.File3D(source="/path/to/model.glb", file_format="glb")
file_3d.format              # "glb"
file_3d.is_disk_backed      # True
file_3d.get_data()          # BytesIO
file_3d.get_bytes()         # raw bytes
file_3d.save_to("/output/model.glb")
MESH、VOXEL、SPLAT
from comfy_api.latest import Types

mesh = Types.MESH(vertices=torch.tensor(...), faces=torch.tensor(...))  # (B,N,3), (B,M,3)
voxel = Types.VOXEL(data=torch.tensor(...), voxel_colors=None, resolution=None)
splat = Types.SPLAT(...)   # gaussian splat data

MESH の任意フィールド(キーワードで渡してください。v0.34 で metallic_roughness が vertex_counts の前に挿入され、位置引数による呼び出しが壊れました):uvs (B,N,2)、vertex_colors (B,N,3|4)、texture (B,H,W,3 baseColor)、metallic_roughness (B,H,W,3;G=roughness、B=metallic)、vertex_counts/face_counts (B,) パディングされたバッチの実際の長さ(両方指定するか、どちらも指定しないでください)、unlit、normals (B,N,3)、tangents (B,N,4)、normal_map、occlusion_in_mr、material (dict)、emissive。

特殊機能を持つウィジェット型

Color
io.Color.Input("color", default="#ff0000", socketless=True)
# Value is a hex string like "#ff0000"
Colors(パレット)
io.Colors.Input("palette", default=["#ff0000", "#00ff00"], socketless=True)
# Value is list[str] of hex colors
BoundingBox
io.BoundingBox.Input("bbox",
    default={"x": 0, "y": 0, "width": 512, "height": 512},
    socketless=True,
    component="my_component",  # optional custom UI component
)
# Value is {"x": int, "y": int, "width": int, "height": int}
BoundingBoxes(複数領域)
io.BoundingBoxes.Input("regions", default=[], socketless=True)
# Value is list of {"x": int, "y": int, "width": int, "height": int, "metadata": dict}
Curve
from comfy_api.input import CurveInput

io.Curve.Input("curve",
    default=[(0.0, 0.0), (1.0, 1.0)],  # linear
    socketless=True,
)
# In execute(), normalize the raw value first:
curve = CurveInput.from_raw(curve)
Range(レベルエディター)
from comfy_api.input import RangeInput

io.Range.Input("levels",
    default={"min": 0.0, "max": 1.0},
    display=None,                # widget visualization mode
    gradient_stops=None,         # gradient background for the slider
    show_midpoint=True,          # show gamma midpoint handle
    midpoint_scale=None,
    value_min=0.0, value_max=1.0,  # UI bounds
)
# In execute(), normalize with RangeInput.from_raw(value):
# .min_val, .max_val, .midpoint (gamma = -log2(midpoint), 0.5 = linear)
# .to_lut(size) generates a GIMP-style levels lookup table
MultiCombo
io.MultiCombo.Input("tags",
    options=["tag1", "tag2", "tag3"],
    default=["tag1"],
    placeholder="Select tags...",
    chip=True,  # show as chips
)
# Value is list[str]
Webcam
io.Webcam.Input("webcam_capture")
# Value is str (captured image data)
ImageCompare
io.ImageCompare.Input("comparison", socketless=True)
# Value is dict

カスタム型

# Simple: create inline custom type
MyData = io.Custom("MY_DATA_TYPE")

# Use in inputs/outputs
io.Schema(
    inputs=[MyData.Input("data")],
    outputs=[MyData.Output("MY_DATA")],
)
上級:@comfytype デコレーター

型ヒントやカスタム Input/Output クラスを使うカスタム型の場合:

from comfy_api.latest._io import comfytype, ComfyTypeIO

@comfytype(io_type="MY_DATA_TYPE")
class MyData(ComfyTypeIO):
    Type = dict[str, Any]  # type hint for the data

RAM キャッシュのサイズ設定:デフォルトの RAM 圧力キャッシュは、出力内の CPU テンソル(リスト/タプル/辞書の内部も含む)を計測します。不透明なオブジェクトは小さなデフォルト値として扱われます。大きなテンソルを保持するカスタムクラスでは、正しくサイズが計測され、削除されるように def _comfy_cache_tensors(self): return (self.a, self.b) を追加してください(コアの MESH/VOXEL/SPLAT も同様です。v0.35 以降)。

AnyType/ワイルドカード

# Accept any single type (always a connection input, no widget)
io.AnyType.Input("anything")

# Accept specific multiple types
io.MultiType.Input("data", types=[io.Image, io.Mask, io.Latent])

# MultiType with widget override (shows widget for first type)
io.MultiType.Input(
    io.Float.Input("value", default=1.0),
    types=[io.Float, io.Int],
)

comfy_api.latest からのインポート

from comfy_api.latest import (
    ComfyExtension,  # extension registration
    ComfyAPI,        # runtime API (progress, node replacement)
    io,              # all io types (io.Image, io.Schema, io.ComfyNode, etc.)
    ui,              # UI output helpers (ui.PreviewImage, ui.SavedImages, etc.)
    Input,           # Input.Image (ImageInput), Input.Audio, Input.Mask, Input.Latent, Input.Video
    InputImpl,       # InputImpl.VideoFromFile, .VideoFromComponents, .VideoFromList
    Types,           # Types.MESH, Types.VOXEL, Types.File3D, Types.VideoCodec, etc.
)

テンソルの安全な取り扱い

テンソルの有無を確認する際は、真偽値による判定ではなく、必ず is not None を使用してください。

# CORRECT
if image is not None:
    process(image)

# WRONG — multi-element tensors don't support bool()
if image:       # raises RuntimeError
    process(image)

# For boolean conditions on tensors, use .all() or .any()
if (mask > 0.5).all():
    ...

型変換パターン

# IMAGE [B,H,W,C] → MASK [B,H,W]
mask = 0.299 * image[:,:,:,0] + 0.587 * image[:,:,:,1] + 0.114 * image[:,:,:,2]

# MASK [B,H,W] → IMAGE [B,H,W,C]
image = mask.unsqueeze(-1).repeat(1, 1, 1, 3)

# Resize image tensor
import torch.nn.functional as F
resized = F.interpolate(
    image.permute(0, 3, 1, 2),  # [B,C,H,W] for interpolate
    size=(new_h, new_w), mode='bilinear', align_corners=False
).permute(0, 2, 3, 1)  # back to [B,H,W,C]

関連項目

  • comfyui-node-basics - ノードクラスの構造と登録
  • comfyui-node-inputs - 入力設定の詳細(ウィジェットのオプション)
  • comfyui-node-outputs - 出力の型と UI 出力
  • comfyui-node-advanced - MatchType、MultiType、Autogrow、DynamicCombo

コメント