Initial commit Smart Resolution Toolkit for ComfyUI
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
# ComfyUI-SmartResolutionPicker
|
||||
|
||||
A lightweight yet powerful resolution assistant for ComfyUI.
|
||||
It allows you to **select image size using human-friendly dropdowns** instead of typing width and height manually.
|
||||
|
||||
Designed for:
|
||||
✓ EmptyLatentImage
|
||||
✓ Video / TikTok / IG / Story formats
|
||||
✓ ControlNet / AnimateDiff / Sampler
|
||||
✓ Latent-safe (auto snap to 64)
|
||||
|
||||
---
|
||||
|
||||
## ✨ Features
|
||||
|
||||
🧠 Smart width & height calculation
|
||||
– Choose **Resolution Preset** (HD, FullHD, 2K, 4K, 8K)
|
||||
– Choose **Aspect Ratio** (1:1, 9:16, 4:5, 21:9 etc.)
|
||||
– Output: clean `width` and `height` (INT values)
|
||||
|
||||
⚙ Latent-safe scaling
|
||||
– Automatically snaps resolution to the nearest multiple of 64
|
||||
– 100% compatible with latent operations
|
||||
|
||||
🎯 Two Nodes Included
|
||||
|
||||
| Node | Description |
|
||||
|------|-------------|
|
||||
| Smart Resolution Picker | Returns width & height (INT) for image/latent initialization |
|
||||
| Smart Latent Generator | Directly creates empty LATENT tensor from resolution + ratio |
|
||||
|
||||
---
|
||||
|
||||
## 📐 Available Resolution Presets
|
||||
|
||||
| Name | Size |
|
||||
|------|------|
|
||||
| SD | 512 × 512 |
|
||||
| HD | 1280 × 720 |
|
||||
| FullHD | 1920 × 1080 |
|
||||
| 2K Cinema | 2048 × 1080 |
|
||||
| QHD | 2560 × 1440 |
|
||||
| 4K UHD | 3840 × 2160 |
|
||||
| 8K UHD | 7680 × 4320 |
|
||||
|
||||
---
|
||||
|
||||
## 📸 Available Aspect Ratios
|
||||
|
||||
| Ratio | Common Usage |
|
||||
|-------|--------------|
|
||||
| 1:1 | Square / Album Cover |
|
||||
| 4:5 | Instagram Portrait |
|
||||
| 3:4 | Classic Portrait / Photography |
|
||||
| 2:3 | DSLR Photo / Print |
|
||||
| 5:4 | Medium Format |
|
||||
| 9:16 | TikTok / Reel / Story |
|
||||
| 16:9 | YouTube / Widescreen |
|
||||
| 21:9 | Cinematic Ultra-wide |
|
||||
|
||||
---
|
||||
|
||||
## 🚀 SmartLatentGenerator Node
|
||||
Generates latent **directly**, no need for EmptyLatentImage.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[SmartLatentGenerator] --> B[Sampler / KSampler]
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
from .smart_resolution import SmartResolutionPicker
|
||||
from .smart_latent import SmartLatentGenerator
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"SmartResolutionPicker": SmartResolutionPicker,
|
||||
"SmartLatentGenerator": SmartLatentGenerator,
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"SmartResolutionPicker": "Smart Resolution Picker",
|
||||
"SmartLatentGenerator": "Smart Latent Generator",
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,36 @@
|
||||
PRESETS = {
|
||||
"SD–512px": 512,
|
||||
"HD–1280px": 1280,
|
||||
"FullHD–1920px": 1920,
|
||||
"2K–2048px": 2048,
|
||||
"QHD–2560px": 2560,
|
||||
"4K–3840px": 3840,
|
||||
"8K–7680px": 7680,
|
||||
}
|
||||
|
||||
ASPECT_RATIOS = {
|
||||
# Square
|
||||
"1:1-AlbumArt": (1, 1),
|
||||
|
||||
# Portrait Formats
|
||||
"4:5-InstagramPortrait": (4, 5),
|
||||
"2:3-ClassicPortrait": (2, 3),
|
||||
"3:4-EditorialPortrait": (3, 4),
|
||||
|
||||
# Vertical Video
|
||||
"9:16-TikTokReel": (9, 16),
|
||||
|
||||
# Landscape / Video
|
||||
"4:3-ClassicVideo": (4, 3),
|
||||
"16:9-Widescreen": (16, 9),
|
||||
|
||||
# Cinematic Aspect
|
||||
"21:9-CinemaScope": (21, 9),
|
||||
|
||||
# Ultra Wide
|
||||
"32:9-UltraWideBanner": (32, 9),
|
||||
}
|
||||
|
||||
def snap64(x):
|
||||
"""Snap to nearest multiple of 64 — Latent-safe resolution"""
|
||||
return max(64, int(round(x / 64.0)) * 64)
|
||||
@@ -0,0 +1,29 @@
|
||||
import torch
|
||||
from .latent_utils import PRESETS, ASPECT_RATIOS, snap64
|
||||
|
||||
class SmartLatentGenerator:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"resolution_preset": (list(PRESETS.keys()), {"default": "FullHD_1920x1080"}),
|
||||
"aspect_ratio": (list(ASPECT_RATIOS.keys()), {"default": "16:9_Widescreen"}),
|
||||
"batch_size": ("INT", {"default": 1, "min": 1, "max": 16}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("LATENT",)
|
||||
RETURN_NAMES = ("LATENT",)
|
||||
FUNCTION = "generate"
|
||||
CATEGORY = "latent/generator"
|
||||
|
||||
def generate(self, resolution_preset, aspect_ratio, batch_size):
|
||||
long_side = PRESETS[resolution_preset]
|
||||
ar_w, ar_h = ASPECT_RATIOS[aspect_ratio]
|
||||
|
||||
scale = long_side / float(max(ar_w, ar_h))
|
||||
width = snap64(ar_w * scale)
|
||||
height = snap64(ar_h * scale)
|
||||
|
||||
latent = torch.zeros([batch_size, 4, height // 8, width // 8])
|
||||
return ({"samples": latent},)
|
||||
@@ -0,0 +1,26 @@
|
||||
from .latent_utils import PRESETS, ASPECT_RATIOS, snap64
|
||||
|
||||
class SmartResolutionPicker:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"resolution_preset": (list(PRESETS.keys()), {"default": "FullHD_1920x1080"}),
|
||||
"aspect_ratio": (list(ASPECT_RATIOS.keys()), {"default": "16:9_Widescreen"}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("INT", "INT")
|
||||
RETURN_NAMES = ("width", "height")
|
||||
FUNCTION = "calculate"
|
||||
CATEGORY = "utils/latent"
|
||||
|
||||
def calculate(self, resolution_preset, aspect_ratio):
|
||||
long_side = PRESETS[resolution_preset]
|
||||
ar_w, ar_h = ASPECT_RATIOS[aspect_ratio]
|
||||
|
||||
scale = long_side / float(max(ar_w, ar_h))
|
||||
width = snap64(ar_w * scale)
|
||||
height = snap64(ar_h * scale)
|
||||
|
||||
return (width, height)
|
||||
Reference in New Issue
Block a user