Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions Samples/CameraCaptureUI/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
page_type: sample
languages:
- csharp
- cppwinrt
- cpp
products:
- windows
- windows-app-sdk
name: "CameraCaptureUI Sample"
urlFragment: CameraCaptureUISample
description: "Demonstrates how to capture photos and videos using the CameraCaptureUI API in WinAppSDK, showcasing how to integrate camera functionality into desktop apps."
extendedZipContent:
- path: LICENSE
target: LICENSE
---


# Camera Capture UI Sample Application

This sample demonstrates how to capture photos and videos using the **CameraCaptureUI** API in a **WinUI3** app. It shows how to use the CameraCaptureUI API to launch the camera for photo and video captures within a desktop application. The sample highlights setting custom camera capture options such as format and resolution, handling successful captures, and displaying the captured media.

> **Note**: This sample is targeted and tested for the **Windows App SDK 1.7 Experimental 1** and **Visual Studio 2022**.


## Features

This sample demonstrates:

- **Photo Capture**: Capturing images with optional settings, including format and resolution.
- **Video Capture**: Capturing videos, with options settings for format and maximum resolution.
- **BitmapImage Display**: Displaying captured photos using `BitmapImage` in XAML.
- **Media Playback**: Playing back captured videos using `MediaPlayerElement`.



## Prerequisites


* See [System requirements for Windows app development](https://docs.microsoft.com/windows/apps/windows-app-sdk/system-requirements).
* Make sure that your development environment is set up correctly—see [Install tools for developing apps for Windows 10 and Windows 11](https://docs.microsoft.com/windows/apps/windows-app-sdk/set-up-your-development-environment).
* The C# sample requires Visual Studio 2022 and .NET 6.

## Building and Running the Sample

* Open the solution file (`.sln`) in Visual Studio.
* Press Ctrl+Shift+B, or select **Build** \> **Build Solution**.


## Related Documentation and Code Samples
* [Windows App SDK](https://docs.microsoft.com/windows/apps/windows-app-sdk/)
* [CameraCaptureUI API Spec Documentation](https://github.com/microsoft/WindowsAppSDK/blob/main/specs/CameraCaptureUI/CameraCaptureUI.md)
* [Windows Media Playback API](https://learn.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.mediaplayerelement?view=winrt-26100)
* [BitmapImage Class Documentation](https://learn.microsoft.com/en-us/dotnet/api/system.windows.media.imaging.bitmapimage?view=windowsdesktop-8.0)



40 changes: 40 additions & 0 deletions Samples/CameraCaptureUI/cpp-winui/cpp-winui.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.12.35514.174 d17.12
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpp-winui", "cpp-winui\cpp-winui.vcxproj", "{2D525B7C-DAFB-477D-86AC-9D9CD85BD8BC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|arm64 = Debug|arm64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|arm64 = Release|arm64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2D525B7C-DAFB-477D-86AC-9D9CD85BD8BC}.Debug|arm64.ActiveCfg = Debug|arm64
{2D525B7C-DAFB-477D-86AC-9D9CD85BD8BC}.Debug|arm64.Build.0 = Debug|arm64
{2D525B7C-DAFB-477D-86AC-9D9CD85BD8BC}.Debug|arm64.Deploy.0 = Debug|arm64
{2D525B7C-DAFB-477D-86AC-9D9CD85BD8BC}.Debug|x64.ActiveCfg = Debug|x64
{2D525B7C-DAFB-477D-86AC-9D9CD85BD8BC}.Debug|x64.Build.0 = Debug|x64
{2D525B7C-DAFB-477D-86AC-9D9CD85BD8BC}.Debug|x64.Deploy.0 = Debug|x64
{2D525B7C-DAFB-477D-86AC-9D9CD85BD8BC}.Debug|x86.ActiveCfg = Debug|Win32
{2D525B7C-DAFB-477D-86AC-9D9CD85BD8BC}.Debug|x86.Build.0 = Debug|Win32
{2D525B7C-DAFB-477D-86AC-9D9CD85BD8BC}.Debug|x86.Deploy.0 = Debug|Win32
{2D525B7C-DAFB-477D-86AC-9D9CD85BD8BC}.Release|arm64.ActiveCfg = Release|arm64
{2D525B7C-DAFB-477D-86AC-9D9CD85BD8BC}.Release|arm64.Build.0 = Release|arm64
{2D525B7C-DAFB-477D-86AC-9D9CD85BD8BC}.Release|arm64.Deploy.0 = Release|arm64
{2D525B7C-DAFB-477D-86AC-9D9CD85BD8BC}.Release|x64.ActiveCfg = Release|x64
{2D525B7C-DAFB-477D-86AC-9D9CD85BD8BC}.Release|x64.Build.0 = Release|x64
{2D525B7C-DAFB-477D-86AC-9D9CD85BD8BC}.Release|x64.Deploy.0 = Release|x64
{2D525B7C-DAFB-477D-86AC-9D9CD85BD8BC}.Release|x86.ActiveCfg = Release|Win32
{2D525B7C-DAFB-477D-86AC-9D9CD85BD8BC}.Release|x86.Build.0 = Release|Win32
{2D525B7C-DAFB-477D-86AC-9D9CD85BD8BC}.Release|x86.Deploy.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
21 changes: 21 additions & 0 deletions Samples/CameraCaptureUI/cpp-winui/cpp-winui/App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!-- Copyright (c) Microsoft Corporation.
Licensed under the MIT License. -->
<Application
x:Class="cpp_winui.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:cpp_winui">

<Application.Resources>
<!-- Application-specific resources -->
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!--
Styles that define common aspects of the platform look and feel
Required by Visual Studio project and item templates
-->
<ResourceDictionary Source="ms-appx:///Styles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
38 changes: 38 additions & 0 deletions Samples/CameraCaptureUI/cpp-winui/cpp-winui/App.xaml.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#include "pch.h"

#include "App.xaml.h"
#include "MainWindow.xaml.h"

namespace winrt
{
using namespace Windows::Foundation;
using namespace Microsoft::UI::Xaml;
}

namespace winrt::cpp_winui::implementation
{
App::App()
{
InitializeComponent();

#if defined _DEBUG && !defined DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
UnhandledException([](winrt::IInspectable const&, winrt::UnhandledExceptionEventArgs const& e)
{
if (IsDebuggerPresent())
{
auto errorMessage = e.Message();
__debugbreak();
}
});
#endif
}

void App::OnLaunched(winrt::LaunchActivatedEventArgs const&)
{
window = winrt::make<MainWindow>();
window.Activate();
}
}
19 changes: 19 additions & 0 deletions Samples/CameraCaptureUI/cpp-winui/cpp-winui/App.xaml.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#pragma once
#include "App.xaml.g.h"
#include "pch.h"

namespace winrt::cpp_winui::implementation
{
struct App : AppT<App>
{
App();

void OnLaunched(Microsoft::UI::Xaml::LaunchActivatedEventArgs const&);

private:
Microsoft::UI::Xaml::Window window{ nullptr };
};
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
29 changes: 29 additions & 0 deletions Samples/CameraCaptureUI/cpp-winui/cpp-winui/MainPage.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!-- Copyright (c) Microsoft Corporation.
Licensed under the MIT License. -->
<Page
x:Class="cpp_winui.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:cpp_winui"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<NavigationView x:Name="NavView"
Loaded="NavView_Loaded"
ItemInvoked="NavView_ItemInvoked"
BackRequested="NavView_BackRequested">
<NavigationView.MenuItems>
<NavigationViewItemHeader x:Name="MainPagesHeader" Content="Scenarios"/>
</NavigationView.MenuItems>

<Grid RowDefinitions="*,Auto">
<ScrollViewer>
<Frame Padding="50" x:Name="ContentFrame" Navigated="ContentFrame_Navigated" />
</ScrollViewer>
<InfoBar x:Name="infoBar" Grid.Row="1" />
</Grid>
</NavigationView>
</Grid>
</Page>
156 changes: 156 additions & 0 deletions Samples/CameraCaptureUI/cpp-winui/cpp-winui/MainPage.xaml.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#include "pch.h"
#include "MainPage.xaml.h"
#if __has_include("MainPage.g.cpp")
#include "MainPage.g.cpp"
#endif

namespace winrt
{
using namespace Microsoft::UI::Xaml;
using namespace Microsoft::UI::Xaml::Controls;
using namespace Microsoft::UI::Xaml::Media;
using namespace Microsoft::UI::Xaml::Media::Animation;
using namespace Microsoft::UI::Xaml::Navigation;
using namespace Windows::UI::Xaml::Interop;
}

namespace winrt::cpp_winui::implementation
{
cpp_winui::MainPage MainPage::current{ nullptr };

MainPage::MainPage()
{
InitializeComponent();
MainPage::current = *this;
}

void MainPage::NotifyUser(hstring const& strMessage, InfoBarSeverity const& severity)
{
// If called from the UI thread, then update immediately.
// Otherwise, schedule a task on the UI thread to perform the update.
if (this->DispatcherQueue().HasThreadAccess())
{
UpdateStatus(strMessage, severity);
}
else
{
DispatcherQueue().TryEnqueue([strongThis = get_strong(), this, strMessage, severity]
{ UpdateStatus(strMessage, severity); });
}
}

void MainPage::UpdateStatus(hstring const& strMessage, InfoBarSeverity severity)
{
infoBar().Message(strMessage);
infoBar().IsOpen(!strMessage.empty());
infoBar().Severity(severity);
}

void MainPage::NavView_Loaded(IInspectable const&, RoutedEventArgs const&)
{
for (auto&& s : Scenarios())
{
FontIcon fontIcon{};
fontIcon.FontFamily(winrt::FontFamily(L"Segoe MDL2 Assets"));
fontIcon.Glyph(L"\uE82D");

NavigationViewItem navViewItem{};
navViewItem.Content(box_value(s.Title));
navViewItem.Tag(box_value(s.ClassName));
navViewItem.Icon(fontIcon);
NavView().MenuItems().Append(navViewItem);
}

// NavView doesn't load any page by default, so load home page.
NavView().SelectedItem(NavView().MenuItems().GetAt(0));

// If navigation occurs on SelectionChanged, this isn't needed.
// Because we use ItemInvoked to navigate, we need to call Navigate
// here to load the home page.
if (Scenarios().Size() > 0)
{
NavView_Navigate(Scenarios().GetAt(0).ClassName, nullptr);
}
}


void MainPage::NavView_ItemInvoked(NavigationView const&, NavigationViewItemInvokedEventArgs const& args)
{
if (args.IsSettingsInvoked() == true)
{
hstring xamltypename = winrt::xaml_typename<SettingsPage>().Name;
NavView_Navigate(xamltypename, args.RecommendedNavigationTransitionInfo());
}
else if (args.InvokedItemContainer() != nullptr)
{
auto navItemTag = winrt::unbox_value<hstring>(args.InvokedItemContainer().Tag());
if (navItemTag != L"")
{
NavView_Navigate(navItemTag, args.RecommendedNavigationTransitionInfo());
}
}
}

void MainPage::NavView_Navigate(hstring navItemTag, NavigationTransitionInfo const&)
{
TypeName pageType;

if (navItemTag == winrt::xaml_typename<SettingsPage>().Name)
{
pageType = winrt::xaml_typename<SettingsPage>();
}
else
{
pageType.Name = navItemTag;
pageType.Kind = TypeKind::Metadata;
}

// Get the page type before navigation so you can prevent duplicate
// entries in the backstack.
TypeName prePageType = ContentFrame().CurrentSourcePageType();

// Only navigate if the selected page isn't currently loaded.
if (prePageType.Name != pageType.Name)
{
DrillInNavigationTransitionInfo drillIn;
ContentFrame().Navigate(pageType, nullptr, drillIn);
}
}

void MainPage::NavView_BackRequested(NavigationView const&, NavigationViewBackRequestedEventArgs const&)
{
if (ContentFrame().CanGoBack())
{
ContentFrame().GoBack();
}
}

void MainPage::ContentFrame_Navigated(IInspectable const&, NavigationEventArgs const& e)
{
NavView().IsBackEnabled(ContentFrame().CanGoBack());

if (ContentFrame().SourcePageType().Name == winrt::xaml_typename<SettingsPage>().Name)
{
// SettingsItem is not part of NavView.MenuItems, and doesn't have a Tag.
NavView().SelectedItem((NavView().SettingsItem().as<NavigationViewItem>()));
NavView().Header(winrt::box_value(L"Settings"));
}
else
{
for (auto&& item : NavView().MenuItems())
{
auto navViewItem = item.try_as<NavigationViewItem>();
if (navViewItem != nullptr &&
winrt::unbox_value<hstring>(navViewItem.Tag()) == e.SourcePageType().Name)
{
NavView().SelectedItem(navViewItem);
NavView().Header(navViewItem.Content());
break;
}
}
}
}
}
Loading