Repository navigation
fix(runners): normalize painted inpainting masks for each provider (fixes #106) - #159
Merged
Merged
Conversation
…ixes #106) - Document canonical Berry mask convention: painted white = edit, transparent = protect - Add mask_converter module with provider-specific normalization functions - ComfyUI: invert alpha (LoadImage MASK = 1 - alpha) - WebUI: convert alpha to grayscale (white=edit, black=protect) - OpenAI: invert alpha (transparent=edit for API) - Fal.ai: validate only (matches Berry convention) - Validate source/mask dimension alignment before conversion - Update creative_runner to apply conversions before execution - Bump cache version 0.1.0 -> 0.2.0 to invalidate old results - Add comprehensive test suite: 13 mask converter tests - Test edge cases: partial alpha, fully painted, fully transparent - Preserve original Berry assets unchanged - Clean up temporary converted masks after ComfyUI upload Issue #106 reported that ComfyUI LoadImage MASK output inverts alpha, causing painted regions to be protected instead of edited. This fix ensures consistent mask semantics across all supported providers. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
BerryUIKI
enabled auto-merge (squash)
October 6, 2026 15:59
Pillow (PIL) is required by mask_converter.py for image manipulation during mask normalization. CI was failing due to missing dependency.
…ests - Replace 1x1 PNG_BYTES with proper 512x512 images matching test dimensions - Mock normalize_mask_for_comfyui in inpaint test to avoid file system issues - Update test_comfy_asset_transfer_contract to detect converted mask uploads - All creative_runner_upload tests now passing (5/5) The mask conversion creates temporary files with different names, so tests need to account for the conversion step and the temporary file cleanup.
The test was using a 1x1 pixel PNG which caused PIL.UnidentifiedImageError when the mask converter tried to validate dimensions. Now creates a proper 512x512 RGBA PNG for testing.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #106 by normalizing Berry-painted masks to each provider's specific mask semantics. The canonical Berry convention (painted white = edit, transparent = protect) is now correctly converted for ComfyUI, WebUI, OpenAI, and Fal.ai.
Problem
Different providers interpret mask alpha channels differently:
1 - alpha, so painted regions (alpha=255) became 0 (protect) instead of 1 (edit)The original implementation passed Berry masks directly without conversion, causing painted regions to be protected instead of edited in ComfyUI and OpenAI.
Implementation
Canonical Berry Convention
Documented in
mask_converter.py:Provider-Specific Conversions
ComfyUI (
normalize_mask_for_comfyui):WebUI (
normalize_mask_for_webui):OpenAI (
normalize_mask_for_openai):Fal.ai (
normalize_mask_for_fal_ai):Integration Points
creative_runner._run_comfy(): Converts and uploads mask, validates dimensionswebui_runner._run_inpaint(): Converts mask before base64 encodingcreative_runner._run_cloud(): Converts based on provider_idCache Invalidation
Runner version bumped from
0.1.0to0.2.0incompute_creative_cache_hash()to prevent reuse of results generated with incorrect mask semantics.Tests
New Test Suite (
test_mask_converter.py- 13 tests, all passing)Existing Tests
Verification
What Was Tested
What Remains Unverified
Contract tests verify payload construction and mask conversion logic. Live inference testing requires:
Architecture Preservation
Documentation
Added
MASK_NORMALIZATION.mddocumenting:Related Issues
Fixes #106
🤖 Generated with Claude Code