メインコンテンツへスキップ
見出し画像

Fixed ComfyUI-Custom-Scripts

    D:\USERFILES\ComfyUI\ComfyUI\custom_nodes\ComfyUI-Custom-Scripts\py\constrain_image.py

    
    ---
    
    ## Errors That Occurred
    
    ### Error 1: `ZeroDivisionError: division by zero`
    ```python
    if constrained_width / constrained_height > aspect_ratio:
       ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
       # constrained_height is 0, causing division by zero failure

    Error 2: `ValueError: height and width must be > 0`

    resized_image = img.resize((constrained_width, constrained_height), Image.LANCZOS)
    # PIL does not accept dimensions of 0 or less

    Root Cause Analysis

    When a user sets `max_height=0` or `max_width=0`:

    1. User sets max_height = 0
       ↓
    2. constrained_height = min(max(current_height, min_height), max_height)
       = min(max(768, 0), 0)
       = min(768, 0)
       = 0  ← Becomes zero!
       ↓
    3. aspect_ratio = current_width / current_height
       = 1024 / 0  ← Division by zero error!

    And if this somehow passes:

    4. resized_image = img.resize((1, 0))
       ← PIL raises "height must be > 0" error and fails

    Complete Fixed Code

    Fixed Code (Lines 28-86):

    def constrain_image(self, images, max_width, max_height, min_width, min_height, crop_if_required):
        crop_if_required = crop_if_required == "yes"
        results = []
        for image in images:
            i = 255. * image.cpu().numpy()
            img = Image.fromarray(np.clip(i, 0, 255).astype(np.uint8)).convert("RGB")
    
            current_width, current_height = img.size
            
            # ========== Check Point 1: Image Size Zero Check ==========
            # Zero value check (set minimum value to 1)
            if current_height <= 0:
                current_height = 1
            if current_width <= 0:
                current_width = 1
            
            aspect_ratio = current_width / current_height  # ✓ Safe
    
            # ========== Check Point 2: Parameter Zero Check ==========
            # If max_width or max_height is 0, use the original size
            if max_width <= 0:
                max_width = current_width
            if max_height <= 0:
                max_height = current_height
    
            # ========== Check Point 3: Initial Calculation ==========
            constrained_width = min(max(current_width, min_width), max_width)
            constrained_height = min(max(current_height, min_height), max_height)
    
            # ========== Check Point 4: Zero Prevention After Calculation ==========
            # Prevent zero after calculation
            if constrained_width <= 0:
                constrained_width = 1
            if constrained_height <= 0:
                constrained_height = 1
    
            # ========== Check Point 5: Aspect Ratio Adjustment ==========
            if constrained_width / constrained_height > aspect_ratio:
                constrained_width = max(int(constrained_height * aspect_ratio), 1)
                if crop_if_required and current_width > 0:
                    constrained_height = max(int(current_height / (current_width / max(constrained_width, 1))), 1)
            else:
                constrained_height = max(int(constrained_width / aspect_ratio), 1)
                if crop_if_required and current_height > 0:
                    constrained_width = max(int(current_width / (current_height / max(constrained_height, 1))), 1)
    
            # ========== Check Point 6: Final Verification ==========
            # Final check: ensure size is positive
            constrained_width = max(int(constrained_width), 1)
            constrained_height = max(int(constrained_height), 1)
    
            # ========== Execute PIL Resize ==========
            resized_image = img.resize((constrained_width, constrained_height), Image.LANCZOS)
    
            if crop_if_required and (constrained_width > max_width or constrained_height > max_height):
                left = max((constrained_width - max_width) // 2, 0)
                top = max((constrained_height - max_height) // 2, 0)
                right = min(constrained_width, max_width) + left
                bottom = min(constrained_height, max_height) + top
                resized_image = resized_image.crop((left, top, right, bottom))
    
            resized_image = np.array(resized_image).astype(np.float32) / 255.0
            resized_image = torch.from_numpy(resized_image)[None,]
            results.append(resized_image)
                
        return (results,)

    Detailed Explanation of 6 Check Points

    1️⃣ Check Point 1: Image Size Zero Check (Lines 37-41)

    if current_height <= 0:
        current_height = 1
    if current_width <= 0:
        current_width = 1

    What it does:

    • If the image height retrieved from PIL is 0 or negative, force it to 1

    Why it is needed:

    • The image file might be corrupted

    • Prevents division by zero

    • Used in `aspect_ratio = current_width / current_height`

    Example:

    Original image: current_height = 0
    After fix: current_height = 1 ← Avoids zero division

    2️⃣ Check Point 2: Parameter Zero Check (Lines 45-49)

    if max_width <= 0:
        max_width = current_width
    if max_height <= 0:
        max_height = current_height

    What it does:

    • If a user sets `max_width=0` or `max_height=0`, set the upper limit to the original image size

    Why it is needed:

    • Users might accidentally set zero values

    • Prevents `min(..., max_width)` from becoming 0

    Concrete Example:

    User sets: max_height = 0
    
    Before fix (calculation):
      constrained_height = min(max(768, 0), 0)
                        = min(768, 0)
                        = 0  ← Fails!
    
    After fix:
      max_height = 768 (original size)
      constrained_height = min(max(768, 0), 768)
                        = min(768, 768)
                        = 768  ✓ Success

    3️⃣ Check Point 3: Initial Calculation (Lines 51-52)

    constrained_width = min(max(current_width, min_width), max_width)
    constrained_height = min(max(current_height, min_height), max_height)

    What it does:

    • Apply both minimum and maximum value constraints simultaneously

    • `max(...)` ensures at least the minimum value

    • `min(...)` ensures at most the maximum value

    Calculation Logic:

    constrained_height = min(max(current_height, min_height), max_height)
                        = min(   apply minimum constraint,      apply maximum constraint )
    
    Example: current_height=768, min_height=0, max_height=1024
             = min(max(768, 0), 1024)
             = min(768, 1024)
             = 768 ✓

    Note: At this point, values might still become 0


    4️⃣ Check Point 4: Zero Prevention After Calculation (Lines 54-58)

    if constrained_width <= 0:
        constrained_width = 1
    if constrained_height <= 0:
        constrained_height = 1

    What it does:

    • After Check Point 3 calculation, if a value becomes 0 or negative, force it to 1

    Why it is needed:

    • Even after Check Point 2's fix, Check Point 3's result might not be safe

    • Double-check strategy

    Example:

    Check Point 2 fix: max_height = 768
    Check Point 3: constrained_height = min(768, 768) = 768
    Check Point 4: 768 > 0, so no change ✓
    
    However, other calculation paths might yield 0, so we need this safeguard

    5️⃣ Check Point 5: Aspect Ratio Adjustment (Lines 60-67)

    if constrained_width / constrained_height > aspect_ratio:
        constrained_width = max(int(constrained_height * aspect_ratio), 1)
        if crop_if_required and current_width > 0:
            constrained_height = max(int(current_height / (current_width / max(constrained_width, 1))), 1)
    else:
        constrained_height = max(int(constrained_width / aspect_ratio), 1)
        if crop_if_required and current_height > 0:
            constrained_width = max(int(current_width / (current_height / max(constrained_height, 1))), 1)

    What it does:

    • Adjust width or height while maintaining the aspect ratio (width-to-height ratio)

    • Ensure calculated results are at least 1 by using `max(..., 1)`

    Logic:

    • If width is too large compared to height → Adjust width based on height

    • If height is too large compared to width → Adjust height based on width

    Important: No division by zero occurs at this point (guaranteed by Check Point 4)


    6️⃣ Check Point 6: Final Verification (Lines 69-71)

    constrained_width = max(int(constrained_width), 1)
    constrained_height = max(int(constrained_height), 1)
    
    resized_image = img.resize((constrained_width, constrained_height), Image.LANCZOS)

    What it does:

    • Final verification after all calculation steps

    • Convert floating-point numbers to integers using `int()`

    • Ensure values are at least 1 by using `max(..., 1)`

    • Triple-check strategy

    Example:

    Calculation result: constrained_width = 0.5
    Step 1: int(0.5) = 0
    Step 2: max(0, 1) = 1 ✓
    
    Calculation result: constrained_height = 0.0
    Step 1: int(0.0) = 0
    Step 2: max(0, 1) = 1 ✓

    This is where `img.resize()` is called:

    • PIL accepts only positive integers

    • Only values of 1 or higher pass through all checks


    Fix Summary Flow Diagram

    Input: max_height=0
      ↓
    [Check Point 1] Verify image size (if 0, set to 1)
      ↓
    [Check Point 2] max_height=0 → Fix to max_height = current_height ✅
      ↓
    [Check Point 3] Calculate constraints
      ↓
    [Check Point 4] Result is 0? → Fix to 1
      ↓
    [Check Point 5] Adjust aspect ratio (guarantee minimum 1)
      ↓
    [Check Point 6] Final check (int conversion + max(..., 1))
      ↓
    PIL.resize((1 or more, 1 or more)) → Success! ✅

    Before and After Comparison

    | Item | Before Fix | After Fix |
    |------|-----------|-----------|
    | Zero Division Prevention | None | 6 check points |
    | max_width=0 Handling | None | Check Point 2 fix |
    | Post-Calculation Check | None | Check Point 4 rechecks |
    | PIL Pre-Call Check | None | Check Point 6 final verification |
    | Error: ZeroDivisionError | Occurs | None (safe) |
    | Error: ValueError height/width | Occurs | None (safe) |


    Mathematical Guarantee

    After all 6 check points, the following is absolutely guaranteed:

    1 ≤ constrained_width < ∞  (positive integer)
    1 ≤ constrained_height < ∞  (positive integer)

    Therefore:

    • `constrained_width / constrained_height` is always valid (never divides by zero)

    • `PIL.Image.resize((constrained_width, constrained_height))` will always succeed

    • No exceptions will be raised


    Why Multiple Check Points Are Necessary

    Each check point handles a different failure scenario:

    1. Check Point 1: Handles corrupted image files

    2. Check Point 2: Handles user input errors (0 values)

    3. Check Point 3: Calculates constrained dimensions

    4. Check Point 4: Catches unexpected zero values from Check Point 3

    5. Check Point 5: Maintains aspect ratio with guaranteed minimums

    6. Check Point 6: Final guarantee before passing to PIL

    Redundancy is safety. Each check point is independent and acts as a fallback for the others.


    Code Execution Example with max_height=0

    Input parameters:
      current_width = 1024
      current_height = 768
      max_width = 1024
      max_height = 0
      min_width = 0
      min_height = 0
    
    Step 1: Check image size
      current_height = 768 > 0 → No change
      current_width = 1024 > 0 → No change
      aspect_ratio = 1024 / 768 = 1.333
    
    Step 2: Check parameters
      max_height = 0 ≤ 0 → Fix to current_height = 768 ✅
    
    Step 3: Calculate constraints
      constrained_width = min(max(1024, 0), 1024) = 1024
      constrained_height = min(max(768, 0), 768) = 768
    
    Step 4: Check after calculation
      constrained_width = 1024 > 0 → No change
      constrained_height = 768 > 0 → No change
    
    Step 5: Aspect ratio adjustment
      1024 / 768 = 1.333 vs 1.333 → Equal, use else branch
      constrained_height = max(int(1024 / 1.333), 1) = max(768, 1) = 768
    
    Step 6: Final check
      constrained_width = max(int(1024), 1) = 1024 ✓
      constrained_height = max(int(768), 1) = 768 ✓
    
    PIL.resize((1024, 768)) → SUCCESS! ✓

    This fix ensures absolute safety at every calculation step!

    \py\constrain_image.py
    
    ---
    
    ## Errors That Occurred
    
    ### Error 1: `ZeroDivisionError: division by zero`
    ```python
    if constrained_width / constrained_height > aspect_ratio:
       ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
       # constrained_height is 0, causing division by zero failure

    Error 2: `ValueError: height and width must be > 0`

    resized_image = img.resize((constrained_width, constrained_height), Image.LANCZOS)
    # PIL does not accept dimensions of 0 or less

    Root Cause Analysis

    When a user sets `max_height=0` or `max_width=0`:

    1. User sets max_height = 0
       ↓
    2. constrained_height = min(max(current_height, min_height), max_height)
       = min(max(768, 0), 0)
       = min(768, 0)
       = 0  ← Becomes zero!
       ↓
    3. aspect_ratio = current_width / current_height
       = 1024 / 0  ← Division by zero error!

    And if this somehow passes:

    4. resized_image = img.resize((1, 0))
       ← PIL raises "height must be > 0" error and fails

    Complete Fixed Code

    Fixed Code (Lines 28-86):

    def constrain_image(self, images, max_width, max_height, min_width, min_height, crop_if_required):
        crop_if_required = crop_if_required == "yes"
        results = []
        for image in images:
            i = 255. * image.cpu().numpy()
            img = Image.fromarray(np.clip(i, 0, 255).astype(np.uint8)).convert("RGB")
    
            current_width, current_height = img.size
            
            # ========== Check Point 1: Image Size Zero Check ==========
            # Zero value check (set minimum value to 1)
            if current_height <= 0:
                current_height = 1
            if current_width <= 0:
                current_width = 1
            
            aspect_ratio = current_width / current_height  # ✓ Safe
    
            # ========== Check Point 2: Parameter Zero Check ==========
            # If max_width or max_height is 0, use the original size
            if max_width <= 0:
                max_width = current_width
            if max_height <= 0:
                max_height = current_height
    
            # ========== Check Point 3: Initial Calculation ==========
            constrained_width = min(max(current_width, min_width), max_width)
            constrained_height = min(max(current_height, min_height), max_height)
    
            # ========== Check Point 4: Zero Prevention After Calculation ==========
            # Prevent zero after calculation
            if constrained_width <= 0:
                constrained_width = 1
            if constrained_height <= 0:
                constrained_height = 1
    
            # ========== Check Point 5: Aspect Ratio Adjustment ==========
            if constrained_width / constrained_height > aspect_ratio:
                constrained_width = max(int(constrained_height * aspect_ratio), 1)
                if crop_if_required and current_width > 0:
                    constrained_height = max(int(current_height / (current_width / max(constrained_width, 1))), 1)
            else:
                constrained_height = max(int(constrained_width / aspect_ratio), 1)
                if crop_if_required and current_height > 0:
                    constrained_width = max(int(current_width / (current_height / max(constrained_height, 1))), 1)
    
            # ========== Check Point 6: Final Verification ==========
            # Final check: ensure size is positive
            constrained_width = max(int(constrained_width), 1)
            constrained_height = max(int(constrained_height), 1)
    
            # ========== Execute PIL Resize ==========
            resized_image = img.resize((constrained_width, constrained_height), Image.LANCZOS)
    
            if crop_if_required and (constrained_width > max_width or constrained_height > max_height):
                left = max((constrained_width - max_width) // 2, 0)
                top = max((constrained_height - max_height) // 2, 0)
                right = min(constrained_width, max_width) + left
                bottom = min(constrained_height, max_height) + top
                resized_image = resized_image.crop((left, top, right, bottom))
    
            resized_image = np.array(resized_image).astype(np.float32) / 255.0
            resized_image = torch.from_numpy(resized_image)[None,]
            results.append(resized_image)
                
        return (results,)

    Detailed Explanation of 6 Check Points

    1️⃣ Check Point 1: Image Size Zero Check (Lines 37-41)

    if current_height <= 0:
        current_height = 1
    if current_width <= 0:
        current_width = 1

    What it does:

    • If the image height retrieved from PIL is 0 or negative, force it to 1

    Why it is needed:

    • The image file might be corrupted

    • Prevents division by zero

    • Used in `aspect_ratio = current_width / current_height`

    Example:

    Original image: current_height = 0
    After fix: current_height = 1 ← Avoids zero division

    2️⃣ Check Point 2: Parameter Zero Check (Lines 45-49)

    if max_width <= 0:
        max_width = current_width
    if max_height <= 0:
        max_height = current_height

    What it does:

    • If a user sets `max_width=0` or `max_height=0`, set the upper limit to the original image size

    Why it is needed:

    • Users might accidentally set zero values

    • Prevents `min(..., max_width)` from becoming 0

    Concrete Example:

    User sets: max_height = 0
    
    Before fix (calculation):
      constrained_height = min(max(768, 0), 0)
                        = min(768, 0)
                        = 0  ← Fails!
    
    After fix:
      max_height = 768 (original size)
      constrained_height = min(max(768, 0), 768)
                        = min(768, 768)
                        = 768  ✓ Success

    3️⃣ Check Point 3: Initial Calculation (Lines 51-52)

    constrained_width = min(max(current_width, min_width), max_width)
    constrained_height = min(max(current_height, min_height), max_height)

    What it does:

    • Apply both minimum and maximum value constraints simultaneously

    • `max(...)` ensures at least the minimum value

    • `min(...)` ensures at most the maximum value

    Calculation Logic:

    constrained_height = min(max(current_height, min_height), max_height)
                        = min(   apply minimum constraint,      apply maximum constraint )
    
    Example: current_height=768, min_height=0, max_height=1024
             = min(max(768, 0), 1024)
             = min(768, 1024)
             = 768 ✓

    Note: At this point, values might still become 0


    4️⃣ Check Point 4: Zero Prevention After Calculation (Lines 54-58)

    if constrained_width <= 0:
        constrained_width = 1
    if constrained_height <= 0:
        constrained_height = 1

    What it does:

    • After Check Point 3 calculation, if a value becomes 0 or negative, force it to 1

    Why it is needed:

    • Even after Check Point 2's fix, Check Point 3's result might not be safe

    • Double-check strategy

    Example:

    Check Point 2 fix: max_height = 768
    Check Point 3: constrained_height = min(768, 768) = 768
    Check Point 4: 768 > 0, so no change ✓
    
    However, other calculation paths might yield 0, so we need this safeguard

    5️⃣ Check Point 5: Aspect Ratio Adjustment (Lines 60-67)

    if constrained_width / constrained_height > aspect_ratio:
        constrained_width = max(int(constrained_height * aspect_ratio), 1)
        if crop_if_required and current_width > 0:
            constrained_height = max(int(current_height / (current_width / max(constrained_width, 1))), 1)
    else:
        constrained_height = max(int(constrained_width / aspect_ratio), 1)
        if crop_if_required and current_height > 0:
            constrained_width = max(int(current_width / (current_height / max(constrained_height, 1))), 1)

    What it does:

    • Adjust width or height while maintaining the aspect ratio (width-to-height ratio)

    • Ensure calculated results are at least 1 by using `max(..., 1)`

    Logic:

    • If width is too large compared to height → Adjust width based on height

    • If height is too large compared to width → Adjust height based on width

    Important: No division by zero occurs at this point (guaranteed by Check Point 4)


    6️⃣ Check Point 6: Final Verification (Lines 69-71)

    constrained_width = max(int(constrained_width), 1)
    constrained_height = max(int(constrained_height), 1)
    
    resized_image = img.resize((constrained_width, constrained_height), Image.LANCZOS)

    What it does:

    • Final verification after all calculation steps

    • Convert floating-point numbers to integers using `int()`

    • Ensure values are at least 1 by using `max(..., 1)`

    • Triple-check strategy

    Example:

    Calculation result: constrained_width = 0.5
    Step 1: int(0.5) = 0
    Step 2: max(0, 1) = 1 ✓
    
    Calculation result: constrained_height = 0.0
    Step 1: int(0.0) = 0
    Step 2: max(0, 1) = 1 ✓

    This is where `img.resize()` is called:

    • PIL accepts only positive integers

    • Only values of 1 or higher pass through all checks


    Fix Summary Flow Diagram

    Input: max_height=0
      ↓
    [Check Point 1] Verify image size (if 0, set to 1)
      ↓
    [Check Point 2] max_height=0 → Fix to max_height = current_height ✅
      ↓
    [Check Point 3] Calculate constraints
      ↓
    [Check Point 4] Result is 0? → Fix to 1
      ↓
    [Check Point 5] Adjust aspect ratio (guarantee minimum 1)
      ↓
    [Check Point 6] Final check (int conversion + max(..., 1))
      ↓
    PIL.resize((1 or more, 1 or more)) → Success! ✅

    Before and After Comparison

    | Item | Before Fix | After Fix |
    |------|-----------|-----------|
    | Zero Division Prevention | None | 6 check points |
    | max_width=0 Handling | None | Check Point 2 fix |
    | Post-Calculation Check | None | Check Point 4 rechecks |
    | PIL Pre-Call Check | None | Check Point 6 final verification |
    | Error: ZeroDivisionError | Occurs | None (safe) |
    | Error: ValueError height/width | Occurs | None (safe) |


    Mathematical Guarantee

    After all 6 check points, the following is absolutely guaranteed:

    1 ≤ constrained_width < ∞  (positive integer)
    1 ≤ constrained_height < ∞  (positive integer)

    Therefore:

    • `constrained_width / constrained_height` is always valid (never divides by zero)

    • `PIL.Image.resize((constrained_width, constrained_height))` will always succeed

    • No exceptions will be raised


    Why Multiple Check Points Are Necessary

    Each check point handles a different failure scenario:

    1. Check Point 1: Handles corrupted image files

    2. Check Point 2: Handles user input errors (0 values)

    3. Check Point 3: Calculates constrained dimensions

    4. Check Point 4: Catches unexpected zero values from Check Point 3

    5. Check Point 5: Maintains aspect ratio with guaranteed minimums

    6. Check Point 6: Final guarantee before passing to PIL

    Redundancy is safety. Each check point is independent and acts as a fallback for the others.


    Code Execution Example with max_height=0

    Input parameters:
      current_width = 1024
      current_height = 768
      max_width = 1024
      max_height = 0
      min_width = 0
      min_height = 0
    
    Step 1: Check image size
      current_height = 768 > 0 → No change
      current_width = 1024 > 0 → No change
      aspect_ratio = 1024 / 768 = 1.333
    
    Step 2: Check parameters
      max_height = 0 ≤ 0 → Fix to current_height = 768 ✅
    
    Step 3: Calculate constraints
      constrained_width = min(max(1024, 0), 1024) = 1024
      constrained_height = min(max(768, 0), 768) = 768
    
    Step 4: Check after calculation
      constrained_width = 1024 > 0 → No change
      constrained_height = 768 > 0 → No change
    
    Step 5: Aspect ratio adjustment
      1024 / 768 = 1.333 vs 1.333 → Equal, use else branch
      constrained_height = max(int(1024 / 1.333), 1) = max(768, 1) = 768
    
    Step 6: Final check
      constrained_width = max(int(1024), 1) = 1024 ✓
      constrained_height = max(int(768), 1) = 768 ✓
    
    PIL.resize((1024, 768)) → SUCCESS! ✓

    This fix ensures absolute safety at every calculation step!

     
     

    GJL

     
     
    Road bike&Cycling Road Race, Respecting Mr.Greg LeMond, & Anti Doping, Football, Rock&Pops, History.

    あなたへのおすすめ