6.2 KiB
6.2 KiB
Image Studio Masking Feature Analysis
Summary
This document identifies which Image Studio operations require or would benefit from masking capabilities.
Operations Requiring Masking
✅ Currently Implemented
1. Inpaint & Fix (inpaint)
- Status: ✅ Mask Required
- Backend Support: Yes (
mask_bytesparameter inStabilityAIService.inpaint()) - Frontend: ✅ Mask editor integrated via
ImageMaskEditor - Use Case: Edit specific regions of an image with precise control
- Mask Type: Required (but can work without mask using prompt-only mode)
Operations That Could Benefit from Optional Masking
🔄 Recommended for Enhancement
2. General Edit (general_edit)
- Status: ✅ Optional mask now enabled
- Backend Support: ✅ HuggingFace image-to-image with mask support
- Frontend: ✅ Mask editor automatically shown
- Use Case: Selective editing of specific regions in prompt-based edits
- Implementation: Mask passed to HuggingFace
image_to_imagemethod (model-dependent support)
3. Search & Replace (search_replace)
- Status: ✅ Optional mask now enabled
- Backend Support: ✅ Stability AI search-and-replace with mask parameter
- Frontend: ✅ Mask editor automatically shown
- Use Case: More precise object replacement when search prompt is ambiguous
- Implementation: Mask passed to Stability
search_and_replaceAPI endpoint
4. Search & Recolor (search_recolor)
- Status: ✅ Optional mask now enabled
- Backend Support: ✅ Stability AI search-and-recolor with mask parameter
- Frontend: ✅ Mask editor automatically shown
- Use Case: Precise color changes when select prompt matches multiple objects
- Implementation: Mask passed to Stability
search_and_recolorAPI endpoint
Operations Not Requiring Masking
❌ No Masking Needed
5. Remove Background (remove_background)
- Reason: Automatic subject detection, no manual masking required
6. Outpaint (outpaint)
- Reason: Expands canvas boundaries, no selective editing needed
7. Replace Background & Relight (relight)
- Reason: Uses reference images for background/lighting, no masking needed
8. Create Studio (Image Generation)
- Reason: Generates images from scratch, no input image to mask
9. Upscale Studio (Image Upscaling)
- Reason: Upscales entire image uniformly, no selective processing
Current Implementation Status
Frontend (EditStudio.tsx)
- ✅ Mask editor dialog integrated
- ✅ Shows "Create Mask" button when
fields.mask === true - ✅ Currently only enabled for
inpaintoperation
Backend (edit_service.py)
- ✅
mask_base64parameter accepted inEditStudioRequest - ✅ Mask passed to
StabilityAIService.inpaint()for inpainting - ⚠️ Mask not utilized for
general_edit(HuggingFace) even though supported
Recommendations
High Priority
- Enable optional masking for
general_edit- Update
SUPPORTED_OPERATIONS["general_edit"]["fields"]["mask"]toTrue(optional) - Ensure HuggingFace provider receives mask when provided
- Update frontend to show mask editor for this operation
- Update
Medium Priority
-
Add optional masking for
search_replace- Allow mask to override or refine
search_promptdetection - Update backend to use mask when provided alongside search_prompt
- Update frontend UI to show mask option
- Allow mask to override or refine
-
Add optional masking for
search_recolor- Allow mask to override or refine
select_promptselection - Update backend to use mask when provided alongside select_prompt
- Update frontend UI to show mask option
- Allow mask to override or refine
Low Priority
- Consider mask preview/validation
- Show mask overlay on base image before submission
- Validate mask dimensions match base image
- Provide mask editing hints/tips
Technical Notes
Mask Format
- Format: Grayscale image (PNG recommended)
- Encoding: Base64 data URL (
data:image/png;base64,...) - Convention:
- White pixels = region to edit/modify
- Black pixels = region to preserve
- Gray pixels = partial influence (for soft masks)
Backend Mask Handling
# Current pattern in edit_service.py
mask_bytes = self._decode_base64_image(request.mask_base64)
if mask_bytes:
# Use mask in operation
result = await stability_service.inpaint(
image=image_bytes,
prompt=request.prompt,
mask=mask_bytes, # Optional but recommended
...
)
Frontend Mask Editor Integration
// Current pattern in EditStudio.tsx
<EditImageUploader
requiresMask={fields.mask} // Shows mask controls when true
onOpenMaskEditor={() => setShowMaskEditor(true)}
/>
<ImageMaskEditor
baseImage={baseImage}
maskImage={maskImage}
onMaskChange={(mask) => setMaskImage(mask)}
onClose={() => setShowMaskEditor(false)}
/>
Testing Checklist
- Mask editor opens for
inpaintoperation - Mask can be drawn/erased on canvas
- Mask exports as base64 grayscale image
- Mask is sent to backend for inpainting
- Optional mask works for
general_edit(backend implemented) - Optional mask works for
search_replace(backend implemented) - Optional mask works for
search_recolor(backend implemented) - Mask editor automatically shows for all mask-enabled operations
- Mask validation (dimensions, format) - Future enhancement
- Mask preview overlay before submission - Future enhancement
Related Files
-
Frontend Components:
frontend/src/components/ImageStudio/ImageMaskEditor.tsx- Mask editor componentfrontend/src/components/ImageStudio/EditStudio.tsx- Edit Studio main componentfrontend/src/components/ImageStudio/EditImageUploader.tsx- Image uploader with mask support
-
Backend Services:
backend/services/image_studio/edit_service.py- Edit operation orchestrationbackend/services/stability_service.py- Stability AI integration (inpaint, erase)backend/routers/image_studio.py- API endpoints
-
Documentation:
.cursor/rules/image-studio.mdc- Development rules including masking guidelines