diff --git a/Samples/WindowsAIFoundry/cs-winui/Examples/ImageForegroundExtractor.md b/Samples/WindowsAIFoundry/cs-winui/Examples/ImageForegroundExtractor.md new file mode 100644 index 000000000..5a286763f --- /dev/null +++ b/Samples/WindowsAIFoundry/cs-winui/Examples/ImageForegroundExtractor.md @@ -0,0 +1,5 @@ +using var inputImage = await LoadYourImageAsSoftwareBitmap(); +using ImageForegroundExtractor extractor = await ImageForegroundExtractor.CreateAsync(); +using var foregroundMask = extractor.GetMaskFromSoftwareBitmap(inputImage); +// Apply the mask to extract the foreground +var foregroundImage = inputImage.ApplyMask(foregroundMask); \ No newline at end of file diff --git a/Samples/WindowsAIFoundry/cs-winui/Examples/ImageForegroundExtractorInit.md b/Samples/WindowsAIFoundry/cs-winui/Examples/ImageForegroundExtractorInit.md new file mode 100644 index 000000000..b2a03ce69 --- /dev/null +++ b/Samples/WindowsAIFoundry/cs-winui/Examples/ImageForegroundExtractorInit.md @@ -0,0 +1,4 @@ +if (ImageForegroundExtractor.GetReadyState() == AIFeatureReadyState.NotReady) +{ + await ImageForegroundExtractor.EnsureReadyAsync(); +} \ No newline at end of file diff --git a/Samples/WindowsAIFoundry/cs-winui/MainWindow.xaml b/Samples/WindowsAIFoundry/cs-winui/MainWindow.xaml index f1cbb2d63..1825d8881 100644 --- a/Samples/WindowsAIFoundry/cs-winui/MainWindow.xaml +++ b/Samples/WindowsAIFoundry/cs-winui/MainWindow.xaml @@ -29,6 +29,9 @@ + diff --git a/Samples/WindowsAIFoundry/cs-winui/MainWindow.xaml.cs b/Samples/WindowsAIFoundry/cs-winui/MainWindow.xaml.cs index c52ee9c45..2c3baa421 100644 --- a/Samples/WindowsAIFoundry/cs-winui/MainWindow.xaml.cs +++ b/Samples/WindowsAIFoundry/cs-winui/MainWindow.xaml.cs @@ -35,6 +35,9 @@ private void NavView_SelectionChanged(NavigationView sender, NavigationViewSelec case "ImageObjectExtractor": rootFrame.Navigate(typeof(ImageObjectExtractorPage)); break; + case "ImageForegroundExtractor": + rootFrame.Navigate(typeof(ImageForegroundExtractorPage)); + break; case "ImageDescription": rootFrame.Navigate(typeof (ImageDescriptionPage)); break; diff --git a/Samples/WindowsAIFoundry/cs-winui/Models/ImageForegroundExtractorModel.cs b/Samples/WindowsAIFoundry/cs-winui/Models/ImageForegroundExtractorModel.cs new file mode 100644 index 000000000..eda185605 --- /dev/null +++ b/Samples/WindowsAIFoundry/cs-winui/Models/ImageForegroundExtractorModel.cs @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +using WindowsAISample.Models.Contracts; +using System; +using System.Threading; +using System.Threading.Tasks; +using Windows.Graphics.Imaging; +using Microsoft.Windows.AI; +using Microsoft.Windows.AI.Imaging; + +namespace WindowsAISample.Models; + +class ImageForegroundExtractorModel : IModelManager +{ + public async Task CreateModelSessionWithProgress(IProgress progress, CancellationToken cancellationToken = default) + { + if (ImageForegroundExtractor.GetReadyState() == AIFeatureReadyState.NotReady) + { + var foregroundExtractorDeploymentOperation = ImageForegroundExtractor.EnsureReadyAsync(); + foregroundExtractorDeploymentOperation.Progress = (_, modelDeploymentProgress) => + { + progress.Report(modelDeploymentProgress % 0.75); // all progress is within 75% + }; + using var _ = cancellationToken.Register(() => foregroundExtractorDeploymentOperation.Cancel()); + await foregroundExtractorDeploymentOperation; + } + else + { + progress.Report(0.75); + } + progress.Report(1.0); // 100% progress + } + + public async Task ExtractForegroundMaskAsync(SoftwareBitmap inputImage, CancellationToken cancellationToken = default) + { + using var extractor = await ImageForegroundExtractor.CreateAsync(); + return extractor.GetMaskFromSoftwareBitmap(inputImage); + } +} diff --git a/Samples/WindowsAIFoundry/cs-winui/Pages/ImageForegroundExtractorPage.xaml b/Samples/WindowsAIFoundry/cs-winui/Pages/ImageForegroundExtractorPage.xaml new file mode 100644 index 000000000..49a0a78c4 --- /dev/null +++ b/Samples/WindowsAIFoundry/cs-winui/Pages/ImageForegroundExtractorPage.xaml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + Input image + + + + Output image + + + + + + + + + + + + + + + + diff --git a/Samples/WindowsAIFoundry/cs-winui/Pages/ImageForegroundExtractorPage.xaml.cs b/Samples/WindowsAIFoundry/cs-winui/Pages/ImageForegroundExtractorPage.xaml.cs new file mode 100644 index 000000000..7a22c8afa --- /dev/null +++ b/Samples/WindowsAIFoundry/cs-winui/Pages/ImageForegroundExtractorPage.xaml.cs @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +using Microsoft.UI.Xaml.Controls; + +namespace WindowsAISample.Pages; + +/// +/// An empty page that can be used on its own or navigated to within a Frame. +/// +public sealed partial class ImageForegroundExtractorPage : Page +{ + public ImageForegroundExtractorPage() + { + InitializeComponent(); + } +} diff --git a/Samples/WindowsAIFoundry/cs-winui/ViewModels/CopilotRootViewModel.cs b/Samples/WindowsAIFoundry/cs-winui/ViewModels/CopilotRootViewModel.cs index 763e7bde5..fd916c61b 100644 --- a/Samples/WindowsAIFoundry/cs-winui/ViewModels/CopilotRootViewModel.cs +++ b/Samples/WindowsAIFoundry/cs-winui/ViewModels/CopilotRootViewModel.cs @@ -17,6 +17,7 @@ internal CopilotRootViewModel() ImageObjectExtractor = new(new Models.ImageObjectExtractorModel()); ImageDescriptionGenerator = new(new Models.ImageDescriptionModel()); ImageObjectRemover = new(new Models.ImageObjectRemoverModel()); + ImageForegroundExtractor = new(new Models.ImageForegroundExtractorModel()); } public LanguageModelViewModel LanguageModel { get; } @@ -30,4 +31,6 @@ internal CopilotRootViewModel() public ImageObjectExtractorViewModel ImageObjectExtractor { get; } public ImageObjectRemoverViewModel ImageObjectRemover { get; } + + public ImageForegroundExtractorViewModel ImageForegroundExtractor { get; } } diff --git a/Samples/WindowsAIFoundry/cs-winui/ViewModels/ImageForegroundExtractorViewModel.cs b/Samples/WindowsAIFoundry/cs-winui/ViewModels/ImageForegroundExtractorViewModel.cs new file mode 100644 index 000000000..b71a6944e --- /dev/null +++ b/Samples/WindowsAIFoundry/cs-winui/ViewModels/ImageForegroundExtractorViewModel.cs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +using WindowsAISample.Models.Contracts; +using WindowsAISample.Util; +using Microsoft.UI.Xaml.Media.Imaging; +using System; +using System.Windows.Input; +using Windows.Graphics.Imaging; +using WindowsAISample.Models; + +namespace WindowsAISample.ViewModels; + +internal partial class ImageForegroundExtractorViewModel : InputImageViewModelBase +{ + private readonly AsyncCommand _extractForegroundCommand; + + public ImageForegroundExtractorViewModel(ImageForegroundExtractorModel imageForegroundExtractorSession) + : base(imageForegroundExtractorSession) + { + _extractForegroundCommand = new( + async _ => + { + if (Input == null) + { + throw new InvalidOperationException(); + } + + var foregroundMask = await Session.ExtractForegroundMaskAsync(Input); + var outputBitmap = Input.ApplyMask(foregroundMask); + + return await DispatcherQueue.EnqueueAsync(async () => + { + return await outputBitmap.ToSourceAsync(); + }); + }, + (_) => IsAvailable && Input is not null); + } + + public ICommand ExtractForegroundCommand => _extractForegroundCommand; + + protected override void OnIsAvailableChanged() + { + _extractForegroundCommand.FireCanExecuteChanged(); + } +}