diff --git a/README.md b/README.md index 17295fe..7921fb9 100644 --- a/README.md +++ b/README.md @@ -349,15 +349,13 @@ resolutions and outputs `width`, `height`, and a `resolution` string. Use position inside the filtered pool. Connect `SxCP Global Seed` or Seed Locker's `seed_config` when the bucket choice must be reproducible. -`SxCP Krea2 Resolution Selector` outputs model-friendly `width`, `height`, -`resolution`, aspect ratio, megapixel, and hosted API fields for Krea2. Use -`profile=turbo_local_2k` for local Turbo generation up to a 2K long edge, or -`profile=raw_local_1k` for RAW/local 1K limits. `profile=api_hosted_1k` keeps -the official API fields visible: `api_aspect_ratio` and `api_resolution=1K`. -The node searches for the best multiple-of-16 size for the selected aspect ratio -and megapixel preset, then clamps to the selected profile's limit. Use -`max_for_aspect` to get the highest valid size for that aspect ratio, or -`random_1_to_limit` with a seed config for reproducible random sizes. +`SxCP Krea2 Resolution Selector` is a simple size picker: choose `megapixels` +and `aspect_ratio`, then use the output `width` and `height`. It assumes local +Krea2 Turbo 2K limits, searches for the best multiple-of-16 size, and clamps the +selected megapixel target when that aspect ratio cannot fit it. `max_for_aspect` +returns the largest valid size for the chosen ratio. The official Krea API +aspect ratios are listed first, with a few local helper ratios such as `8:9` +after them. `SxCP Camera Control` and `SxCP Camera Orbit Control` output `camera_config`, which can be connected to the prompt builder or the Insta/OF pair node. They diff --git a/__init__.py b/__init__.py index 65f23fc..ab0c768 100644 --- a/__init__.py +++ b/__init__.py @@ -45,10 +45,8 @@ SDXL_BUCKET_RESOLUTIONS = [ ] KREA2_API_ASPECT_RATIOS = ["1:1", "4:3", "3:2", "16:9", "2.35:1", "4:5", "2:3", "9:16"] -KREA2_ASPECT_RATIOS = KREA2_API_ASPECT_RATIOS + ["21:9", "9:21", "3:1", "1:3", "custom", "random_api"] +KREA2_ASPECT_RATIOS = KREA2_API_ASPECT_RATIOS + ["8:9", "21:9", "9:21", "3:1", "1:3"] KREA2_MEGAPIXEL_PRESETS = [ - "max_for_aspect", - "random_1_to_limit", "1.0MP", "1.25MP", "1.5MP", @@ -62,7 +60,7 @@ KREA2_MEGAPIXEL_PRESETS = [ "3.5MP", "3.75MP", "4.0MP", - "custom", + "max_for_aspect", ] @@ -259,15 +257,8 @@ NODE_INPUT_TOOLTIPS = { "seed_config": "Optional seed config. The composition seed controls bucket choice, so Seed Locker can keep sizes fixed while rerolling pose/person.", }, "SxCPKrea2ResolutionSelector": { - "profile": "api_hosted_1k returns official API fields; raw_local_1k and turbo_local_2k return explicit ComfyUI width/height under known local limits.", - "aspect_ratio": "Official Krea API ratios are listed first. custom uses custom_aspect_width/custom_aspect_height; random_api chooses from official ratios.", - "megapixel_preset": "Pick a target megapixel count, max_for_aspect, random_1_to_limit, or custom_megapixels.", - "round_to": "Krea2 local inference pads to multiples of 16; 32/64 are stricter bucket-friendly choices.", - "custom_max_long_edge": "Only used by custom_limit. Local Turbo documentation uses 2048 as the 2K upper edge.", - "custom_max_megapixels": "Only used by custom_limit. The selector still respects custom_max_long_edge.", - "seed": "Used only for random_api or random_1_to_limit. Connect Seed Config for deterministic workflow-wide randomness.", - "row_number": "Deterministic row offset for random ratio/megapixel choices.", - "seed_config": "Optional seed config. The composition seed controls resolution choices when connected.", + "megapixels": "Target megapixel preset. If it cannot fit the aspect ratio under the 2K Krea2 Turbo limit, the node clamps to the maximum valid size.", + "aspect_ratio": "Krea API ratios are listed first; local-only helper ratios like 8:9 are included after them.", }, "SxCPCameraControl": { "camera_mode": "Camera style preset. Use from_camera_config in Insta/OF options to consume this.", @@ -1041,23 +1032,8 @@ class SxCPKrea2ResolutionSelector: def INPUT_TYPES(cls): return { "required": { - "profile": ( - ["turbo_local_2k", "raw_local_1k", "api_hosted_1k", "custom_limit"], - {"default": "turbo_local_2k"}, - ), + "megapixels": (KREA2_MEGAPIXEL_PRESETS, {"default": "1.0MP"}), "aspect_ratio": (KREA2_ASPECT_RATIOS, {"default": "1:1"}), - "megapixel_preset": (KREA2_MEGAPIXEL_PRESETS, {"default": "1.0MP"}), - "custom_megapixels": ("FLOAT", {"default": 1.0, "min": 0.10, "max": 16.0, "step": 0.05}), - "round_to": (["16", "32", "64"], {"default": "16"}), - "custom_aspect_width": ("FLOAT", {"default": 1.0, "min": 0.10, "max": 100.0, "step": 0.05}), - "custom_aspect_height": ("FLOAT", {"default": 1.0, "min": 0.10, "max": 100.0, "step": 0.05}), - "custom_max_long_edge": ("INT", {"default": 2048, "min": 256, "max": 8192, "step": 16}), - "custom_max_megapixels": ("FLOAT", {"default": 4.20, "min": 0.10, "max": 64.0, "step": 0.05}), - "seed": ("INT", {"default": -1, "min": -1, "max": 0xFFFFFFFF, "step": 1}), - "row_number": ("INT", {"default": 1, "min": 1, "max": 1000000, "step": 1}), - }, - "optional": { - "seed_config": (SXCP_SEED_CONFIG,), }, } @@ -1078,10 +1054,6 @@ class SxCPKrea2ResolutionSelector: FUNCTION = "select" CATEGORY = "prompt_builder/util" - @staticmethod - def _configured_seed(seed_config): - return SxCPSDXLBucketSize._configured_bucket_seed(seed_config) - @staticmethod def _aspect_value(aspect_ratio, custom_aspect_width, custom_aspect_height, rng): selected = str(aspect_ratio or "1:1").strip() @@ -1191,56 +1163,11 @@ class SxCPKrea2ResolutionSelector: return 1.0 return None - @classmethod - def IS_CHANGED(cls, *args, **kwargs): - aspect_ratio = kwargs.get("aspect_ratio") - if aspect_ratio is None and len(args) > 1: - aspect_ratio = args[1] - megapixel_preset = kwargs.get("megapixel_preset") - if megapixel_preset is None and len(args) > 2: - megapixel_preset = args[2] - seed_value = kwargs.get("seed") - if seed_value is None and len(args) > 9: - seed_value = args[9] - seed_config = kwargs.get("seed_config", "") - if not seed_config and len(args) > 11: - seed_config = args[11] - try: - seed = int(seed_value) - except (TypeError, ValueError): - seed = -1 - uses_random = str(aspect_ratio) == "random_api" or str(megapixel_preset) == "random_1_to_limit" - if uses_random and seed < 0 and cls._configured_seed(seed_config) is None: - return random.random() - return tuple(args), tuple(sorted(kwargs.items())) - - def select( - self, - profile, - aspect_ratio, - megapixel_preset, - custom_megapixels, - round_to, - custom_aspect_width, - custom_aspect_height, - custom_max_long_edge, - custom_max_megapixels, - seed, - row_number, - seed_config="", - ): - configured_seed = self._configured_seed(seed_config) - if configured_seed is None and int(seed) < 0: - rng = random.Random(random.getrandbits(64)) - seed_label = "fresh" - else: - selected_seed = configured_seed if configured_seed is not None else int(seed) - rng = random.Random(f"krea2_resolution:{selected_seed}:{int(row_number)}") - seed_label = str(selected_seed) - - multiple = int(round_to) if str(round_to).isdigit() else 16 - max_long_edge, max_profile_mp, profile_label = self._profile_limits(profile, custom_max_long_edge, custom_max_megapixels) - resolved_aspect, ratio = self._aspect_value(aspect_ratio, custom_aspect_width, custom_aspect_height, rng) + def select(self, megapixels, aspect_ratio): + multiple = 16 + profile = "turbo_local_2k" + max_long_edge, max_profile_mp, _profile_label = self._profile_limits(profile, 2048, 4.20) + resolved_aspect, ratio = self._aspect_value(aspect_ratio, 1.0, 1.0, random.Random("krea2_resolution")) api_aspect_ratio = resolved_aspect if resolved_aspect in KREA2_API_ASPECT_RATIOS else self._closest_api_aspect(ratio) continuous_max_mp = self._continuous_limit_mp(ratio, max_long_edge, max_profile_mp) @@ -1248,19 +1175,10 @@ class SxCPKrea2ResolutionSelector: ratio, continuous_max_mp, max_long_edge, max_profile_mp, multiple ) - preset = str(megapixel_preset or "1.0MP").strip() + preset = str(megapixels or "1.0MP").strip() target_mp = self._preset_megapixels(preset) - if preset == "custom": - target_mp = max(0.10, float(custom_megapixels)) - elif preset == "max_for_aspect": + if preset == "max_for_aspect": target_mp = max_actual_mp - elif preset == "random_1_to_limit": - available = [self._preset_megapixels(value) for value in KREA2_MEGAPIXEL_PRESETS if value.endswith("MP")] - available = [value for value in available if value is not None and 1.0 <= value <= max_actual_mp + 0.001] - if not available: - target_mp = max_actual_mp - else: - target_mp = rng.choice(available) if target_mp is None: target_mp = 1.0 @@ -1278,17 +1196,15 @@ class SxCPKrea2ResolutionSelector: resolution = f"{width}x{height}" api_resolution = "1K" summary_parts = [ - f"{profile_label}", f"{resolution}", f"{actual_mp:.2f} MP", f"aspect {resolved_aspect} ({actual_ratio:.3f})", f"max for aspect {max_width}x{max_height} / {max_actual_mp:.2f} MP", - f"API {api_aspect_ratio} {api_resolution}", + f"Krea2 Turbo 2K", + f"API equivalent {api_aspect_ratio} {api_resolution}", ] if clamped: summary_parts.append(f"target {target_mp:.2f} MP clamped to aspect/profile limit") - if preset.startswith("random") or resolved_aspect == "random_api": - summary_parts.append(f"seed {seed_label}, row {int(row_number)}") summary = "; ".join(summary_parts) config = {