Skip to content

Commit ee7df2a

Browse files
committed
Refine background removal ROI and mask logic, UI flow
- Use the entire image as the region of interest for background removal instead of a central crop. - Invert the mask before applying it as alpha to correct background/foreground handling. - Store the result image path in RemoveBackgroundDialog only after user confirmation. - Add explicit PrimaryButtonClick handling for result commitment. - Refactor dialog loading logic for clearer error handling and UI state management.
1 parent 35ffd7c commit ee7df2a

2 files changed

Lines changed: 29 additions & 32 deletions

File tree

Simple Icon File Maker/Simple Icon File Maker/Helpers/BackgroundRemoverHelper.cs

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,23 +47,11 @@ public static async Task<string> RemoveBackgroundAsync(string imagePath)
4747

4848
using ImageObjectExtractor extractor = await ImageObjectExtractor.CreateWithSoftwareBitmapAsync(sourceBitmap);
4949

50-
// Use a rectangle covering the central ~90% of the image so the model
51-
// identifies the dominant object rather than a single small element.
52-
int marginX = sourceBitmap.PixelWidth / 20;
53-
int marginY = sourceBitmap.PixelHeight / 20;
54-
55-
RectInt32 rect = new()
56-
{
57-
X = marginX,
58-
Y = marginY,
59-
Width = sourceBitmap.PixelWidth - 2 * marginX,
60-
Height = sourceBitmap.PixelHeight - 2 * marginY
61-
};
62-
50+
// Hint with the entire image rect as the region of interest
6351
ImageObjectExtractorHint hint = new(
64-
includeRects: [rect],
65-
includePoints: null,
66-
excludePoints: null);
52+
includeRects: [new RectInt32(0, 0, sourceBitmap.PixelWidth, sourceBitmap.PixelHeight)],
53+
includePoints: [],
54+
excludePoints: []);
6755

6856
SoftwareBitmap mask = extractor.GetSoftwareBitmapObjectMask(hint);
6957

@@ -102,7 +90,7 @@ private static SoftwareBitmap ApplyMaskAsAlpha(SoftwareBitmap original, Software
10290
for (int i = 0; i < maskPixels.Length; i++)
10391
{
10492
int px = i * 4;
105-
int m = maskPixels[i];
93+
int m = 255 - maskPixels[i];
10694
resultPixels[px + 0] = (byte)(originalPixels[px + 0] * m / 255);
10795
resultPixels[px + 1] = (byte)(originalPixels[px + 1] * m / 255);
10896
resultPixels[px + 2] = (byte)(originalPixels[px + 2] * m / 255);

Simple Icon File Maker/Simple Icon File Maker/Views/RemoveBackgroundDialog.xaml.cs

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,36 +10,42 @@ public sealed partial class RemoveBackgroundDialog : ContentDialog
1010
public string? ResultImagePath { get; private set; }
1111

1212
private readonly string _imagePath;
13+
private string? _pendingResultPath;
1314

1415
public RemoveBackgroundDialog(string imagePath)
1516
{
1617
InitializeComponent();
1718
_imagePath = imagePath;
19+
PrimaryButtonClick += OnPrimaryButtonClick;
20+
}
21+
22+
private void OnPrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
23+
{
24+
ResultImagePath = _pendingResultPath;
1825
}
1926

2027
private async void ContentDialog_Loaded(object sender, RoutedEventArgs e)
2128
{
22-
try
29+
BeforeImage.Source = new BitmapImage(new Uri(_imagePath));
30+
31+
bool isAvailable = await BackgroundRemoverHelper.IsAvailableAsync();
32+
if (!isAvailable)
2333
{
24-
BeforeImage.Source = new BitmapImage(new Uri(_imagePath));
25-
26-
bool available = await BackgroundRemoverHelper.IsAvailableAsync();
27-
if (!available)
28-
{
29-
StatusInfoBar.Title = "Not Available";
30-
StatusInfoBar.Message = "The AI background removal model is not available on this device. This feature requires a Copilot+ PC with the latest Windows updates.";
31-
StatusInfoBar.Severity = InfoBarSeverity.Warning;
32-
StatusInfoBar.IsOpen = true;
33-
ProcessingRing.IsActive = false;
34-
return;
35-
}
34+
StatusInfoBar.Title = "Not Available";
35+
StatusInfoBar.Message = "The AI background removal model is not available on this device. This feature requires a Copilot+ PC with the latest Windows updates.";
36+
StatusInfoBar.Severity = InfoBarSeverity.Warning;
37+
StatusInfoBar.IsOpen = true;
38+
ProcessingRing.IsActive = false;
39+
return;
40+
}
3641

42+
try
43+
{
3744
string resultPath = await BackgroundRemoverHelper.RemoveBackgroundAsync(_imagePath);
38-
ResultImagePath = resultPath;
45+
_pendingResultPath = resultPath;
3946

4047
AfterImage.Source = new BitmapImage(new Uri(resultPath));
4148

42-
ProcessingRing.IsActive = false;
4349
IsPrimaryButtonEnabled = true;
4450
}
4551
catch (Exception ex)
@@ -48,6 +54,9 @@ private async void ContentDialog_Loaded(object sender, RoutedEventArgs e)
4854
StatusInfoBar.Message = $"Failed to remove background: {ex.Message}";
4955
StatusInfoBar.Severity = InfoBarSeverity.Error;
5056
StatusInfoBar.IsOpen = true;
57+
}
58+
finally
59+
{
5160
ProcessingRing.IsActive = false;
5261
}
5362
}

0 commit comments

Comments
 (0)