feat: 切换后端至PaddleOCR-NCNN,切换工程为CMake

1.项目后端整体迁移至PaddleOCR-NCNN算法,已通过基本的兼容性测试
2.工程改为使用CMake组织,后续为了更好地兼容第三方库,不再提供QMake工程
3.重整权利声明文件,重整代码工程,确保最小化侵权风险

Log: 切换后端至PaddleOCR-NCNN,切换工程为CMake
Change-Id: I4d5d2c5d37505a4a24b389b1a4c5d12f17bfa38c
This commit is contained in:
wangzhengyang
2022-05-10 09:54:44 +08:00
parent ecdd171c6f
commit 718c41634f
10018 changed files with 3593797 additions and 186748 deletions

View File

@ -0,0 +1,40 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FaceDetection", "FaceDetection\FaceDetection.vcxproj", "{0FAE44E0-6C15-4CCA-ABDA-29556B391390}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|ARM = Release|ARM
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0FAE44E0-6C15-4CCA-ABDA-29556B391390}.Debug|ARM.ActiveCfg = Debug|ARM
{0FAE44E0-6C15-4CCA-ABDA-29556B391390}.Debug|ARM.Build.0 = Debug|ARM
{0FAE44E0-6C15-4CCA-ABDA-29556B391390}.Debug|ARM.Deploy.0 = Debug|ARM
{0FAE44E0-6C15-4CCA-ABDA-29556B391390}.Debug|Win32.ActiveCfg = Debug|Win32
{0FAE44E0-6C15-4CCA-ABDA-29556B391390}.Debug|Win32.Build.0 = Debug|Win32
{0FAE44E0-6C15-4CCA-ABDA-29556B391390}.Debug|Win32.Deploy.0 = Debug|Win32
{0FAE44E0-6C15-4CCA-ABDA-29556B391390}.Debug|x64.ActiveCfg = Debug|x64
{0FAE44E0-6C15-4CCA-ABDA-29556B391390}.Debug|x64.Build.0 = Debug|x64
{0FAE44E0-6C15-4CCA-ABDA-29556B391390}.Debug|x64.Deploy.0 = Debug|x64
{0FAE44E0-6C15-4CCA-ABDA-29556B391390}.Release|ARM.ActiveCfg = Release|ARM
{0FAE44E0-6C15-4CCA-ABDA-29556B391390}.Release|ARM.Build.0 = Release|ARM
{0FAE44E0-6C15-4CCA-ABDA-29556B391390}.Release|ARM.Deploy.0 = Release|ARM
{0FAE44E0-6C15-4CCA-ABDA-29556B391390}.Release|Win32.ActiveCfg = Release|Win32
{0FAE44E0-6C15-4CCA-ABDA-29556B391390}.Release|Win32.Build.0 = Release|Win32
{0FAE44E0-6C15-4CCA-ABDA-29556B391390}.Release|Win32.Deploy.0 = Release|Win32
{0FAE44E0-6C15-4CCA-ABDA-29556B391390}.Release|x64.ActiveCfg = Release|x64
{0FAE44E0-6C15-4CCA-ABDA-29556B391390}.Release|x64.Build.0 = Release|x64
{0FAE44E0-6C15-4CCA-ABDA-29556B391390}.Release|x64.Deploy.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,7 @@
<Application
x:Class="FaceDetection.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:FaceDetection">
</Application>

View File

@ -0,0 +1,125 @@
//
// App.xaml.cpp
// Implementation of the App class.
//
#include "pch.h"
#include "MainPage.xaml.h"
using namespace FaceDetection;
using namespace Platform;
using namespace Windows::ApplicationModel;
using namespace Windows::ApplicationModel::Activation;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Interop;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
// The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
App::App()
{
InitializeComponent();
Suspending += ref new SuspendingEventHandler(this, &App::OnSuspending);
}
/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used such as when the application is launched to open a specific file.
/// </summary>
/// <param name="e">Details about the launch request and process.</param>
void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e)
{
#if _DEBUG
// Show graphics profiling information while debugging.
if (IsDebuggerPresent())
{
// Display the current frame rate counters
DebugSettings->EnableFrameRateCounter = true;
}
#endif
auto rootFrame = dynamic_cast<Frame^>(Window::Current->Content);
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == nullptr)
{
// Create a Frame to act as the navigation context and associate it with
// a SuspensionManager key
rootFrame = ref new Frame();
// Set the default language
rootFrame->Language = Windows::Globalization::ApplicationLanguages::Languages->GetAt(0);
rootFrame->NavigationFailed += ref new Windows::UI::Xaml::Navigation::NavigationFailedEventHandler(this, &App::OnNavigationFailed);
if (e->PreviousExecutionState == ApplicationExecutionState::Terminated)
{
// TODO: Restore the saved session state only when appropriate, scheduling the
// final launch steps after the restore is complete
}
if (rootFrame->Content == nullptr)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
rootFrame->Navigate(TypeName(MainPage::typeid), e->Arguments);
}
// Place the frame in the current Window
Window::Current->Content = rootFrame;
// Ensure the current window is active
Window::Current->Activate();
}
else
{
if (rootFrame->Content == nullptr)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
rootFrame->Navigate(TypeName(MainPage::typeid), e->Arguments);
}
// Ensure the current window is active
Window::Current->Activate();
}
}
/// <summary>
/// Invoked when application execution is being suspended. Application state is saved
/// without knowing whether the application will be terminated or resumed with the contents
/// of memory still intact.
/// </summary>
/// <param name="sender">The source of the suspend request.</param>
/// <param name="e">Details about the suspend request.</param>
void App::OnSuspending(Object^ sender, SuspendingEventArgs^ e)
{
(void) sender; // Unused parameter
(void) e; // Unused parameter
//TODO: Save application state and stop any background activity
}
/// <summary>
/// Invoked when Navigation to a certain page fails
/// </summary>
/// <param name="sender">The Frame which failed navigation</param>
/// <param name="e">Details about the navigation failure</param>
void App::OnNavigationFailed(Platform::Object ^sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs ^e)
{
throw ref new FailureException("Failed to load Page " + e->SourcePageType.Name);
}

View File

@ -0,0 +1,27 @@
//
// App.xaml.h
// Declaration of the App class.
//
#pragma once
#include "App.g.h"
namespace FaceDetection
{
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
ref class App sealed
{
protected:
virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e) override;
internal:
App();
private:
void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ e);
void OnNavigationFailed(Platform::Object ^sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs ^e);
};
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 801 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

View File

@ -0,0 +1,199 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{0fae44e0-6c15-4cca-abda-29556b391390}</ProjectGuid>
<RootNamespace>FaceDetection</RootNamespace>
<DefaultLanguage>en-US</DefaultLanguage>
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
<AppContainerApplication>true</AppContainerApplication>
<ApplicationType>Windows Store</ApplicationType>
<ApplicationTypeRevision>8.1</ApplicationTypeRevision>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="opencv.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="opencv.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="opencv.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="opencv.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="opencv.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="opencv.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<PackageCertificateKeyFile>FaceDetection_TemporaryKey.pfx</PackageCertificateKeyFile>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
</ClCompile>
<Link>
<AdditionalDependencies>opencv_objdetect300$(DebugSuffix).lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
</ClCompile>
<Link>
<AdditionalDependencies>opencv_objdetect300$(DebugSuffix).lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="App.xaml.h">
<DependentUpon>App.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="MainPage.xaml.h">
<DependentUpon>MainPage.xaml</DependentUpon>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="MainPage.xaml">
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
<None Include="FaceDetection_TemporaryKey.pfx" />
</ItemGroup>
<ItemGroup>
<Image Include="Assets\group1.jpg" />
<Image Include="Assets\group2.JPG" />
<Image Include="Assets\group3.jpg" />
<Image Include="Assets\Logo.scale-100.png" />
<Image Include="Assets\SmallLogo.scale-100.png" />
<Image Include="Assets\StoreLogo.scale-100.png" />
<Image Include="Assets\SplashScreen.scale-100.png" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="App.xaml.cpp">
<DependentUpon>App.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="MainPage.xaml.cpp">
<DependentUpon>MainPage.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Xml Include="Assets\haarcascade_frontalface_alt.xml" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Common">
<UniqueIdentifier>0fae44e0-6c15-4cca-abda-29556b391390</UniqueIdentifier>
</Filter>
<Filter Include="Assets">
<UniqueIdentifier>cee6a8fd-c14c-4eab-b410-54073b7fc217</UniqueIdentifier>
<Extensions>bmp;fbx;gif;jpg;jpeg;tga;tiff;tif;png</Extensions>
</Filter>
<Image Include="Assets\Logo.scale-100.png">
<Filter>Assets</Filter>
</Image>
<Image Include="Assets\SmallLogo.scale-100.png">
<Filter>Assets</Filter>
</Image>
<Image Include="Assets\StoreLogo.scale-100.png">
<Filter>Assets</Filter>
</Image>
<Image Include="Assets\SplashScreen.scale-100.png">
<Filter>Assets</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="App.xaml.cpp" />
<ClCompile Include="MainPage.xaml.cpp" />
<ClCompile Include="pch.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="App.xaml.h" />
<ClInclude Include="MainPage.xaml.h" />
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest" />
</ItemGroup>
<ItemGroup>
<None Include="FaceDetection_TemporaryKey.pfx" />
<None Include="$(OpenCV_Bin)opencv_core300$(DebugSuffix).dll" />
<None Include="$(OpenCV_Bin)opencv_imgproc300$(DebugSuffix).dll" />
<None Include="$(OpenCV_Bin)opencv_features2d300$(DebugSuffix).dll" />
<None Include="$(OpenCV_Bin)opencv_flann300$(DebugSuffix).dll" />
<None Include="$(OpenCV_Bin)opencv_ml300$(DebugSuffix).dll" />
<None Include="$(OpenCV_Bin)opencv_objdetect300$(DebugSuffix).dll" />
<None Include="$(OpenCV_Bin)opencv_imgcodecs300$(DebugSuffix).dll" />
</ItemGroup>
<ItemGroup>
<Page Include="MainPage.xaml" />
</ItemGroup>
<ItemGroup>
<Image Include="Assets\group1.jpg">
<Filter>Assets</Filter>
</Image>
<Image Include="Assets\group2.JPG">
<Filter>Assets</Filter>
</Image>
<Image Include="Assets\group3.jpg">
<Filter>Assets</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<Xml Include="Assets\haarcascade_frontalface_alt.xml">
<Filter>Assets</Filter>
</Xml>
</ItemGroup>
</Project>

View File

@ -0,0 +1,34 @@
<Page x:Class="FaceDetection.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:FaceDetection"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button x:Name="InitBtn"
Width="218"
Height="67"
Margin="69,81,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Click="InitBtn_Click"
Content="Initialize" />
<Button x:Name="detectBtn"
Width="218"
Height="67"
Margin="69,168,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Click="detectBtn_Click"
Content="Detect Faces" />
<StackPanel x:Name="cvContainer"
Width="883"
Height="446"
Margin="354,84,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top" />
</Grid>
</Page>

View File

@ -0,0 +1,81 @@
//
// MainPage.xaml.cpp
// Implementation of the MainPage class.
//
#include "pch.h"
#include "MainPage.xaml.h"
#include <opencv2\imgproc\types_c.h>
#include <opencv2\imgcodecs.hpp>
#include <opencv2\core.hpp>
#include <opencv2\imgproc.hpp>
#include <opencv2\highgui.hpp>
#include <opencv2\highgui\highgui_winrt.hpp>
#include <Robuffer.h>
using namespace FaceDetection;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
using namespace Windows::UI::Xaml::Media::Imaging;
using namespace Windows::Storage::Streams;
using namespace Microsoft::WRL;
// Name of the resource classifier used to detect human faces (frontal)
cv::String face_cascade_name = "Assets/haarcascade_frontalface_alt.xml";
cv::String window_name = "Faces";
MainPage::MainPage()
{
InitializeComponent();
}
void FaceDetection::MainPage::InitBtn_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
// load Image and Init recognizer
cv::Mat image = cv::imread("Assets/group1.jpg");
groupFaces = cv::Mat(image.rows, image.cols, CV_8UC4);
cv::cvtColor(image, groupFaces, COLOR_BGR2BGRA);
cv::winrt_initContainer(cvContainer);
cv::imshow(window_name, groupFaces);
if (!face_cascade.load(face_cascade_name)) {
Windows::UI::Popups::MessageDialog("Couldn't load face detector \n").ShowAsync();
}
}
void FaceDetection::MainPage::detectBtn_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
if (!groupFaces.empty()) {
std::vector<cv::Rect> facesColl;
cv::Mat frame_gray;
cvtColor(groupFaces, frame_gray, COLOR_BGR2GRAY);
cv::equalizeHist(frame_gray, frame_gray);
// Detect faces
face_cascade.detectMultiScale(frame_gray, facesColl, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, cv::Size(1, 1));
for (unsigned int i = 0; i < facesColl.size(); i++)
{
auto face = facesColl[i];
cv::rectangle(groupFaces, face, cv::Scalar(0, 255, 255), 5);
}
cv::imshow(window_name, groupFaces);
} else {
Windows::UI::Popups::MessageDialog("Initialize image before processing \n").ShowAsync();
}
}

View File

@ -0,0 +1,32 @@
//
// MainPage.xaml.h
// Declaration of the MainPage class.
//
#pragma once
#include "MainPage.g.h"
#include <opencv2\core\core.hpp>
#include <opencv2\objdetect.hpp>
namespace FaceDetection
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public ref class MainPage sealed
{
public:
MainPage();
private:
void InitBtn_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void detectBtn_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
private:
cv::Mat groupFaces;
void UpdateImage(const cv::Mat& image);
cv::CascadeClassifier face_cascade;
};
}

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest">
<Identity Name="f8308285-aea6-41b1-a76e-9954cfd46c7e"
Publisher="CN=ericmitt"
Version="1.0.0.0" />
<Properties>
<DisplayName>FaceDetection</DisplayName>
<PublisherDisplayName>ericmitt</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Prerequisites>
<OSMinVersion>6.3.0</OSMinVersion>
<OSMaxVersionTested>6.3.0</OSMaxVersionTested>
</Prerequisites>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="FaceDetection.App">
<m2:VisualElements
DisplayName="FaceDetection"
Square150x150Logo="Assets\Logo.png"
Square30x30Logo="Assets\SmallLogo.png"
Description="FaceDetection"
ForegroundText="light"
BackgroundColor="#464646">
<m2:SplashScreen Image="Assets\SplashScreen.png" />
</m2:VisualElements>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
</Capabilities>
</Package>

View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros">
<Runtime Condition="'$(ApplicationType)'=='Windows Phone'">WP</Runtime>
<Runtime Condition="'$(ApplicationType)'=='Windows Store'">WS</Runtime>
<OpenCV_Bin>$(OPENCV_WINRT_INSTALL_DIR)\$(Runtime)\8.1\$(PlatformTarget)\$(PlatformTarget)\vc12\bin\</OpenCV_Bin>
<OpenCV_Lib>$(OPENCV_WINRT_INSTALL_DIR)\$(Runtime)\8.1\$(PlatformTarget)\$(PlatformTarget)\vc12\lib\</OpenCV_Lib>
<OpenCV_Include>$(OPENCV_WINRT_INSTALL_DIR)\$(Runtime)\8.1\$(PlatformTarget)\include\</OpenCV_Include>
<!--debug suffix for OpenCV dlls and libs -->
<DebugSuffix Condition="'$(Configuration)'=='Debug'">d</DebugSuffix>
<DebugSuffix Condition="'$(Configuration)'!='Debug'"></DebugSuffix>
</PropertyGroup>
<ItemGroup>
<!--Add required OpenCV dlls here-->
<None Include="$(OpenCV_Bin)opencv_core300$(DebugSuffix).dll">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="$(OpenCV_Bin)opencv_imgcodecs300$(DebugSuffix).dll">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="$(OpenCV_Bin)opencv_imgproc300$(DebugSuffix).dll">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="$(OpenCV_Bin)opencv_features2d300$(DebugSuffix).dll">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="$(OpenCV_Bin)opencv_flann300$(DebugSuffix).dll">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="$(OpenCV_Bin)opencv_ml300$(DebugSuffix).dll">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="$(OpenCV_Bin)opencv_objdetect300$(DebugSuffix).dll">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="$(OpenCV_Bin)opencv_videoio300$(DebugSuffix).dll">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="$(OpenCV_Bin)opencv_highgui300$(DebugSuffix).dll">
<DeploymentContent>true</DeploymentContent>
</None>
</ItemGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(OpenCV_Include);%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<!--Add required OpenCV libs here-->
<AdditionalDependencies>opencv_core300$(DebugSuffix).lib;opencv_imgproc300$(DebugSuffix).lib;opencv_imgcodecs300$(DebugSuffix).lib;opencv_flann300$(DebugSuffix).lib;opencv_videoio300$(DebugSuffix).lib;opencv_features2d300$(DebugSuffix).lib;opencv_objdetect300$(DebugSuffix).lib;opencv_ml300$(DebugSuffix).lib;opencv_highgui300$(DebugSuffix).lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OpenCV_Lib);%(AdditionalLibraryDirectories);</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
</Project>

View File

@ -0,0 +1,6 @@
//
// pch.cpp
// Include the standard header and generate the precompiled header.
//
#include "pch.h"

View File

@ -0,0 +1,11 @@
//
// pch.h
// Header for standard system include files.
//
#pragma once
#include <collection.h>
#include <ppltasks.h>
#include "App.xaml.h"

View File

@ -0,0 +1,75 @@
<!--
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
-->
<common:LayoutAwarePage
x:Class="SDKSample.MediaCapture.AdvancedCapture"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:$rootsnamespace$"
xmlns:common="using:SDKSample.Common"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid x:Name="LayoutRoot" Background="White" HorizontalAlignment="Left" VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid x:Name="Input" Grid.Row="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock TextWrapping="Wrap" Grid.Row="0" Text="This scenario shows how to enumerate cameras in the system. Choose a camera from the list to preview, record or take a photo from the chosen camera. You can add the gray scale effect using the checkbox provided." Style="{StaticResource BasicTextStyle}" HorizontalAlignment="Left"/>
<StackPanel Orientation="Horizontal" Grid.Row="1" Margin="0,10,0,0">
<ListBox x:Name="EnumedDeviceList2" SelectionChanged="lstEnumedDevices_SelectionChanged" />
<Button x:Name="btnStartDevice2" Click="btnStartDevice_Click" IsEnabled="true" Margin="0,0,10,0" Content="StartDevice"/>
<Button x:Name="btnStartPreview2" Click="btnStartPreview_Click" IsEnabled="true" Margin="0,0,10,0" Content="StartPreview"/>
<ComboBox x:Name="EffectTypeCombo" Width="120" SelectedIndex="0">
<ComboBoxItem Content="Preview"/>
<ComboBoxItem Content="Grayscale"/>
<ComboBoxItem Content="Canny"/>
<ComboBoxItem Content="Sobel"/>
<ComboBoxItem Content="Histogram"/>
</ComboBox>
<Button Content="Apply" HorizontalAlignment="Stretch" VerticalAlignment="Top" Click="Button_Click"/>
</StackPanel>
<StackPanel x:Name="EffectTypeCombo1" Orientation="Horizontal" Grid.Row="1" Margin="324,5,-324,7"/>
</Grid>
<Grid x:Name="Output" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1">
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<StackPanel>
<TextBlock Style="{StaticResource BasicTextStyle}" HorizontalAlignment='Center' VerticalAlignment='Center' TextAlignment='Center' Text='Preview' />
<Canvas x:Name="previewCanvas2" Background="Gray">
<CaptureElement x:Name="previewElement2" />
</Canvas>
</StackPanel>
<StackPanel/>
<StackPanel/>
</StackPanel>
</Grid>
<!-- Add Storyboards to the visual states below as necessary for supporting the various layouts -->
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="FullScreenLandscape"/>
<VisualState x:Name="Filled"/>
<VisualState x:Name="FullScreenPortrait"/>
<VisualState x:Name="Snapped"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</common:LayoutAwarePage>

View File

@ -0,0 +1,613 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
//
// AdvancedCapture.xaml.cpp
// Implementation of the AdvancedCapture class
//
#include "pch.h"
#include "AdvancedCapture.xaml.h"
using namespace SDKSample::MediaCapture;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Navigation;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::System;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Platform;
using namespace Windows::UI;
using namespace Windows::UI::Core;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::Storage;
using namespace Windows::Media::MediaProperties;
using namespace Windows::Storage::Streams;
using namespace Windows::System;
using namespace Windows::UI::Xaml::Media::Imaging;
using namespace Windows::Devices::Enumeration;
ref class ReencodeState sealed
{
public:
ReencodeState()
{
}
virtual ~ReencodeState()
{
if (InputStream != nullptr)
{
delete InputStream;
}
if (OutputStream != nullptr)
{
delete OutputStream;
}
}
internal:
Windows::Storage::Streams::IRandomAccessStream ^InputStream;
Windows::Storage::Streams::IRandomAccessStream ^OutputStream;
Windows::Storage::StorageFile ^PhotoStorage;
Windows::Graphics::Imaging::BitmapDecoder ^Decoder;
Windows::Graphics::Imaging::BitmapEncoder ^Encoder;
};
AdvancedCapture::AdvancedCapture()
{
InitializeComponent();
ScenarioInit();
}
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached. The Parameter
/// property is typically used to configure the page.</param>
void AdvancedCapture::OnNavigatedTo(NavigationEventArgs^ e)
{
// A pointer back to the main page. This is needed if you want to call methods in MainPage such
// as NotifyUser()
rootPage = MainPage::Current;
m_orientationChangedEventToken = Windows::Graphics::Display::DisplayProperties::OrientationChanged += ref new Windows::Graphics::Display::DisplayPropertiesEventHandler(this, &AdvancedCapture::DisplayProperties_OrientationChanged);
}
void AdvancedCapture::OnNavigatedFrom(NavigationEventArgs^ e)
{
Windows::Media::MediaControl::SoundLevelChanged -= m_eventRegistrationToken;
Windows::Graphics::Display::DisplayProperties::OrientationChanged -= m_orientationChangedEventToken;
}
void AdvancedCapture::ScenarioInit()
{
rootPage = MainPage::Current;
btnStartDevice2->IsEnabled = true;
btnStartPreview2->IsEnabled = false;
m_bRecording = false;
m_bPreviewing = false;
m_bEffectAdded = false;
previewElement2->Source = nullptr;
ShowStatusMessage("");
EffectTypeCombo->IsEnabled = false;
previewCanvas2->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
EnumerateWebcamsAsync();
m_bSuspended = false;
}
void AdvancedCapture::ScenarioReset()
{
previewCanvas2->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
ScenarioInit();
}
void AdvancedCapture::Failed(Windows::Media::Capture::MediaCapture ^currentCaptureObject, Windows::Media::Capture::MediaCaptureFailedEventArgs^ currentFailure)
{
String ^message = "Fatal error" + currentFailure->Message;
create_task(Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::High,
ref new Windows::UI::Core::DispatchedHandler([this, message]()
{
ShowStatusMessage(message);
})));
}
void AdvancedCapture::btnStartDevice_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
try
{
EnableButton(false, "StartDevice");
ShowStatusMessage("Starting device");
auto mediaCapture = ref new Windows::Media::Capture::MediaCapture();
m_mediaCaptureMgr = mediaCapture;
auto settings = ref new Windows::Media::Capture::MediaCaptureInitializationSettings();
auto chosenDevInfo = m_devInfoCollection->GetAt(EnumedDeviceList2->SelectedIndex);
settings->VideoDeviceId = chosenDevInfo->Id;
if (chosenDevInfo->EnclosureLocation != nullptr && chosenDevInfo->EnclosureLocation->Panel == Windows::Devices::Enumeration::Panel::Back)
{
m_bRotateVideoOnOrientationChange = true;
m_bReversePreviewRotation = false;
}
else if (chosenDevInfo->EnclosureLocation != nullptr && chosenDevInfo->EnclosureLocation->Panel == Windows::Devices::Enumeration::Panel::Front)
{
m_bRotateVideoOnOrientationChange = true;
m_bReversePreviewRotation = true;
}
else
{
m_bRotateVideoOnOrientationChange = false;
}
create_task(mediaCapture->InitializeAsync(settings)).then([this](task<void> initTask)
{
try
{
initTask.get();
auto mediaCapture = m_mediaCaptureMgr.Get();
DisplayProperties_OrientationChanged(nullptr);
EnableButton(true, "StartPreview");
EnableButton(true, "StartStopRecord");
EnableButton(true, "TakePhoto");
ShowStatusMessage("Device initialized successful");
EffectTypeCombo->IsEnabled = true;
mediaCapture->Failed += ref new Windows::Media::Capture::MediaCaptureFailedEventHandler(this, &AdvancedCapture::Failed);
}
catch (Exception ^ e)
{
ShowExceptionMessage(e);
}
});
}
catch (Platform::Exception^ e)
{
ShowExceptionMessage(e);
}
}
void AdvancedCapture::btnStartPreview_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
m_bPreviewing = false;
try
{
ShowStatusMessage("Starting preview");
EnableButton(false, "StartPreview");
auto mediaCapture = m_mediaCaptureMgr.Get();
previewCanvas2->Visibility = Windows::UI::Xaml::Visibility::Visible;
previewElement2->Source = mediaCapture;
create_task(mediaCapture->StartPreviewAsync()).then([this](task<void> previewTask)
{
try
{
previewTask.get();
m_bPreviewing = true;
ShowStatusMessage("Start preview successful");
}
catch (Exception ^e)
{
ShowExceptionMessage(e);
}
});
}
catch (Platform::Exception^ e)
{
m_bPreviewing = false;
previewElement2->Source = nullptr;
EnableButton(true, "StartPreview");
ShowExceptionMessage(e);
}
}
void AdvancedCapture::lstEnumedDevices_SelectionChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e)
{
if ( m_bPreviewing )
{
create_task(m_mediaCaptureMgr->StopPreviewAsync()).then([this](task<void> previewTask)
{
try
{
previewTask.get();
m_bPreviewing = false;
}
catch (Exception ^e)
{
ShowExceptionMessage(e);
}
});
}
btnStartDevice2->IsEnabled = true;
btnStartPreview2->IsEnabled = false;
m_bRecording = false;
previewElement2->Source = nullptr;
EffectTypeCombo->IsEnabled = false;
m_bEffectAdded = false;
m_bEffectAddedToRecord = false;
m_bEffectAddedToPhoto = false;
ShowStatusMessage("");
}
void AdvancedCapture::EnumerateWebcamsAsync()
{
try
{
ShowStatusMessage("Enumerating Webcams...");
m_devInfoCollection = nullptr;
EnumedDeviceList2->Items->Clear();
task<DeviceInformationCollection^>(DeviceInformation::FindAllAsync(DeviceClass::VideoCapture)).then([this](task<DeviceInformationCollection^> findTask)
{
try
{
m_devInfoCollection = findTask.get();
if (m_devInfoCollection == nullptr || m_devInfoCollection->Size == 0)
{
ShowStatusMessage("No WebCams found.");
}
else
{
for(unsigned int i = 0; i < m_devInfoCollection->Size; i++)
{
auto devInfo = m_devInfoCollection->GetAt(i);
EnumedDeviceList2->Items->Append(devInfo->Name);
}
EnumedDeviceList2->SelectedIndex = 0;
ShowStatusMessage("Enumerating Webcams completed successfully.");
btnStartDevice2->IsEnabled = true;
}
}
catch (Exception ^e)
{
ShowExceptionMessage(e);
}
});
}
catch (Platform::Exception^ e)
{
ShowExceptionMessage(e);
}
}
void AdvancedCapture::AddEffectToImageStream()
{
auto mediaCapture = m_mediaCaptureMgr.Get();
Windows::Media::Capture::VideoDeviceCharacteristic charecteristic = mediaCapture->MediaCaptureSettings->VideoDeviceCharacteristic;
if((charecteristic != Windows::Media::Capture::VideoDeviceCharacteristic::AllStreamsIdentical) &&
(charecteristic != Windows::Media::Capture::VideoDeviceCharacteristic::PreviewPhotoStreamsIdentical) &&
(charecteristic != Windows::Media::Capture::VideoDeviceCharacteristic::RecordPhotoStreamsIdentical))
{
Windows::Media::MediaProperties::IMediaEncodingProperties ^props = mediaCapture->VideoDeviceController->GetMediaStreamProperties(Windows::Media::Capture::MediaStreamType::Photo);
if(props->Type->Equals("Image"))
{
//Switch to a video media type instead since we can't add an effect to an image media type
Windows::Foundation::Collections::IVectorView<Windows::Media::MediaProperties::IMediaEncodingProperties^>^ supportedPropsList = mediaCapture->VideoDeviceController->GetAvailableMediaStreamProperties(Windows::Media::Capture::MediaStreamType::Photo);
{
unsigned int i = 0;
while (i < supportedPropsList->Size)
{
Windows::Media::MediaProperties::IMediaEncodingProperties^ props = supportedPropsList->GetAt(i);
String^ s = props->Type;
if(props->Type->Equals("Video"))
{
task<void>(mediaCapture->VideoDeviceController->SetMediaStreamPropertiesAsync(Windows::Media::Capture::MediaStreamType::Photo,props)).then([this](task<void> changeTypeTask)
{
try
{
changeTypeTask.get();
ShowStatusMessage("Change type on photo stream successful");
//Now add the effect on the image pin
task<void>(m_mediaCaptureMgr->AddEffectAsync(Windows::Media::Capture::MediaStreamType::Photo,"OcvTransform.OcvImageManipulations", nullptr)).then([this](task<void> effectTask3)
{
try
{
effectTask3.get();
m_bEffectAddedToPhoto = true;
ShowStatusMessage("Adding effect to photo stream successful");
EffectTypeCombo->IsEnabled = true;
}
catch(Exception ^e)
{
ShowExceptionMessage(e);
EffectTypeCombo->IsEnabled = true;
}
});
}
catch(Exception ^e)
{
ShowExceptionMessage(e);
EffectTypeCombo->IsEnabled = true;
}
});
break;
}
i++;
}
}
}
else
{
//Add the effect to the image pin if the type is already "Video"
task<void>(mediaCapture->AddEffectAsync(Windows::Media::Capture::MediaStreamType::Photo,"OcvTransform.OcvImageManipulations", nullptr)).then([this](task<void> effectTask3)
{
try
{
effectTask3.get();
m_bEffectAddedToPhoto = true;
ShowStatusMessage("Adding effect to photo stream successful");
EffectTypeCombo->IsEnabled = true;
}
catch(Exception ^e)
{
ShowExceptionMessage(e);
EffectTypeCombo->IsEnabled = true;
}
});
}
}
}
void AdvancedCapture::ShowStatusMessage(Platform::String^ text)
{
rootPage->NotifyUser(text, NotifyType::StatusMessage);
}
void AdvancedCapture::ShowExceptionMessage(Platform::Exception^ ex)
{
rootPage->NotifyUser(ex->Message, NotifyType::ErrorMessage);
}
void AdvancedCapture::EnableButton(bool enabled, String^ name)
{
if (name->Equals("StartDevice"))
{
btnStartDevice2->IsEnabled = enabled;
}
else if (name->Equals("StartPreview"))
{
btnStartPreview2->IsEnabled = enabled;
}
}
task<Windows::Storage::StorageFile^> AdvancedCapture::ReencodePhotoAsync(
Windows::Storage::StorageFile ^tempStorageFile,
Windows::Storage::FileProperties::PhotoOrientation photoRotation)
{
ReencodeState ^state = ref new ReencodeState();
return create_task(tempStorageFile->OpenAsync(Windows::Storage::FileAccessMode::Read)).then([state](Windows::Storage::Streams::IRandomAccessStream ^stream)
{
state->InputStream = stream;
return Windows::Graphics::Imaging::BitmapDecoder::CreateAsync(state->InputStream);
}).then([state](Windows::Graphics::Imaging::BitmapDecoder ^decoder)
{
state->Decoder = decoder;
return Windows::Storage::KnownFolders::PicturesLibrary->CreateFileAsync(PHOTO_FILE_NAME, Windows::Storage::CreationCollisionOption::GenerateUniqueName);
}).then([state](Windows::Storage::StorageFile ^storageFile)
{
state->PhotoStorage = storageFile;
return state->PhotoStorage->OpenAsync(Windows::Storage::FileAccessMode::ReadWrite);
}).then([state](Windows::Storage::Streams::IRandomAccessStream ^stream)
{
state->OutputStream = stream;
state->OutputStream->Size = 0;
return Windows::Graphics::Imaging::BitmapEncoder::CreateForTranscodingAsync(state->OutputStream, state->Decoder);
}).then([state, photoRotation](Windows::Graphics::Imaging::BitmapEncoder ^encoder)
{
state->Encoder = encoder;
auto properties = ref new Windows::Graphics::Imaging::BitmapPropertySet();
properties->Insert("System.Photo.Orientation",
ref new Windows::Graphics::Imaging::BitmapTypedValue((unsigned short)photoRotation, Windows::Foundation::PropertyType::UInt16));
return create_task(state->Encoder->BitmapProperties->SetPropertiesAsync(properties));
}).then([state]()
{
return state->Encoder->FlushAsync();
}).then([tempStorageFile, state](task<void> previousTask)
{
auto result = state->PhotoStorage;
delete state;
tempStorageFile->DeleteAsync(Windows::Storage::StorageDeleteOption::PermanentDelete);
previousTask.get();
return result;
});
}
Windows::Storage::FileProperties::PhotoOrientation AdvancedCapture::GetCurrentPhotoRotation()
{
bool counterclockwiseRotation = m_bReversePreviewRotation;
if (m_bRotateVideoOnOrientationChange)
{
return PhotoRotationLookup(Windows::Graphics::Display::DisplayProperties::CurrentOrientation, counterclockwiseRotation);
}
else
{
return Windows::Storage::FileProperties::PhotoOrientation::Normal;
}
}
void AdvancedCapture::PrepareForVideoRecording()
{
Windows::Media::Capture::MediaCapture ^mediaCapture = m_mediaCaptureMgr.Get();
if (mediaCapture == nullptr)
{
return;
}
bool counterclockwiseRotation = m_bReversePreviewRotation;
if (m_bRotateVideoOnOrientationChange)
{
mediaCapture->SetRecordRotation(VideoRotationLookup(Windows::Graphics::Display::DisplayProperties::CurrentOrientation, counterclockwiseRotation));
}
else
{
mediaCapture->SetRecordRotation(Windows::Media::Capture::VideoRotation::None);
}
}
void AdvancedCapture::DisplayProperties_OrientationChanged(Platform::Object^ sender)
{
Windows::Media::Capture::MediaCapture ^mediaCapture = m_mediaCaptureMgr.Get();
if (mediaCapture == nullptr)
{
return;
}
bool previewMirroring = mediaCapture->GetPreviewMirroring();
bool counterclockwiseRotation = (previewMirroring && !m_bReversePreviewRotation) ||
(!previewMirroring && m_bReversePreviewRotation);
if (m_bRotateVideoOnOrientationChange)
{
mediaCapture->SetPreviewRotation(VideoRotationLookup(Windows::Graphics::Display::DisplayProperties::CurrentOrientation, counterclockwiseRotation));
}
else
{
mediaCapture->SetPreviewRotation(Windows::Media::Capture::VideoRotation::None);
}
}
Windows::Storage::FileProperties::PhotoOrientation AdvancedCapture::PhotoRotationLookup(
Windows::Graphics::Display::DisplayOrientations displayOrientation, bool counterclockwise)
{
switch (displayOrientation)
{
case Windows::Graphics::Display::DisplayOrientations::Landscape:
return Windows::Storage::FileProperties::PhotoOrientation::Normal;
case Windows::Graphics::Display::DisplayOrientations::Portrait:
return (counterclockwise) ? Windows::Storage::FileProperties::PhotoOrientation::Rotate270:
Windows::Storage::FileProperties::PhotoOrientation::Rotate90;
case Windows::Graphics::Display::DisplayOrientations::LandscapeFlipped:
return Windows::Storage::FileProperties::PhotoOrientation::Rotate180;
case Windows::Graphics::Display::DisplayOrientations::PortraitFlipped:
return (counterclockwise) ? Windows::Storage::FileProperties::PhotoOrientation::Rotate90 :
Windows::Storage::FileProperties::PhotoOrientation::Rotate270;
default:
return Windows::Storage::FileProperties::PhotoOrientation::Unspecified;
}
}
Windows::Media::Capture::VideoRotation AdvancedCapture::VideoRotationLookup(
Windows::Graphics::Display::DisplayOrientations displayOrientation, bool counterclockwise)
{
switch (displayOrientation)
{
case Windows::Graphics::Display::DisplayOrientations::Landscape:
return Windows::Media::Capture::VideoRotation::None;
case Windows::Graphics::Display::DisplayOrientations::Portrait:
return (counterclockwise) ? Windows::Media::Capture::VideoRotation::Clockwise270Degrees :
Windows::Media::Capture::VideoRotation::Clockwise90Degrees;
case Windows::Graphics::Display::DisplayOrientations::LandscapeFlipped:
return Windows::Media::Capture::VideoRotation::Clockwise180Degrees;
case Windows::Graphics::Display::DisplayOrientations::PortraitFlipped:
return (counterclockwise) ? Windows::Media::Capture::VideoRotation::Clockwise90Degrees:
Windows::Media::Capture::VideoRotation::Clockwise270Degrees ;
default:
return Windows::Media::Capture::VideoRotation::None;
}
}
void SDKSample::MediaCapture::AdvancedCapture::Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
try
{
create_task(m_mediaCaptureMgr->ClearEffectsAsync(Windows::Media::Capture::MediaStreamType::VideoPreview)).then([this](task<void> cleanTask)
{
m_bEffectAdded = true;
int index = EffectTypeCombo->SelectedIndex;
PropertySet^ props = ref new PropertySet();
props->Insert(L"{698649BE-8EAE-4551-A4CB-3EC98FBD3D86}", index);
create_task(m_mediaCaptureMgr->AddEffectAsync(Windows::Media::Capture::MediaStreamType::VideoPreview,"OcvTransform.OcvImageManipulations", props)).then([this](task<void> effectTask)
{
try
{
effectTask.get();
auto mediaCapture = m_mediaCaptureMgr.Get();
Windows::Media::Capture::VideoDeviceCharacteristic charecteristic = mediaCapture->MediaCaptureSettings->VideoDeviceCharacteristic;
ShowStatusMessage("Add effect successful to preview stream successful");
if((charecteristic != Windows::Media::Capture::VideoDeviceCharacteristic::AllStreamsIdentical) &&
(charecteristic != Windows::Media::Capture::VideoDeviceCharacteristic::PreviewRecordStreamsIdentical))
{
Windows::Media::MediaProperties::IMediaEncodingProperties ^props = mediaCapture->VideoDeviceController->GetMediaStreamProperties(Windows::Media::Capture::MediaStreamType::VideoRecord);
Windows::Media::MediaProperties::VideoEncodingProperties ^videoEncodingProperties = static_cast<Windows::Media::MediaProperties::VideoEncodingProperties ^>(props);
if(!videoEncodingProperties->Subtype->Equals("H264")) //Can't add an effect to an H264 stream
{
task<void>(mediaCapture->AddEffectAsync(Windows::Media::Capture::MediaStreamType::VideoRecord,"OcvTransform.OcvImageManipulations", nullptr)).then([this](task<void> effectTask2)
{
try
{
effectTask2.get();
ShowStatusMessage("Add effect successful to record stream successful");
m_bEffectAddedToRecord = true;
AddEffectToImageStream();
EffectTypeCombo->IsEnabled = true;
}
catch(Exception ^e)
{
ShowExceptionMessage(e);
EffectTypeCombo->IsEnabled = true;
}
});
}
else
{
AddEffectToImageStream();
EffectTypeCombo->IsEnabled = true;
}
}
else
{
AddEffectToImageStream();
EffectTypeCombo->IsEnabled = true;
}
}
catch (Exception ^e)
{
ShowExceptionMessage(e);
EffectTypeCombo->IsEnabled = true;
}
});
});
}
catch (Platform::Exception ^e)
{
ShowExceptionMessage(e);
EffectTypeCombo->IsEnabled = true;
}
}

View File

@ -0,0 +1,95 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
//
// AdvancedCapture.xaml.h
// Declaration of the AdvancedCapture class
//
#pragma once
#include "pch.h"
#include "AdvancedCapture.g.h"
#include "MainPage.xaml.h"
#include <ppl.h>
#define VIDEO_FILE_NAME "video.mp4"
#define PHOTO_FILE_NAME "photo.jpg"
#define TEMP_PHOTO_FILE_NAME "photoTmp.jpg"
using namespace concurrency;
using namespace Windows::Devices::Enumeration;
namespace SDKSample
{
namespace MediaCapture
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
[Windows::Foundation::Metadata::WebHostHidden]
public ref class AdvancedCapture sealed
{
public:
AdvancedCapture();
protected:
virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
virtual void OnNavigatedFrom(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
private:
MainPage^ rootPage;
void ScenarioInit();
void ScenarioReset();
void Failed(Windows::Media::Capture::MediaCapture ^ mediaCapture, Windows::Media::Capture::MediaCaptureFailedEventArgs ^ args);
void btnStartDevice_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void btnStartPreview_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void lstEnumedDevices_SelectionChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e);
void EnumerateWebcamsAsync();
void AddEffectToImageStream();
void ShowStatusMessage(Platform::String^ text);
void ShowExceptionMessage(Platform::Exception^ ex);
void EnableButton(bool enabled, Platform::String ^name);
task<Windows::Storage::StorageFile^> ReencodePhotoAsync(
Windows::Storage::StorageFile ^tempStorageFile,
Windows::Storage::FileProperties::PhotoOrientation photoRotation);
Windows::Storage::FileProperties::PhotoOrientation GetCurrentPhotoRotation();
void PrepareForVideoRecording();
void DisplayProperties_OrientationChanged(Platform::Object^ sender);
Windows::Storage::FileProperties::PhotoOrientation PhotoRotationLookup(
Windows::Graphics::Display::DisplayOrientations displayOrientation, bool counterclockwise);
Windows::Media::Capture::VideoRotation VideoRotationLookup(
Windows::Graphics::Display::DisplayOrientations displayOrientation, bool counterclockwise);
Platform::Agile<Windows::Media::Capture::MediaCapture> m_mediaCaptureMgr;
Windows::Storage::StorageFile^ m_recordStorageFile;
bool m_bRecording;
bool m_bEffectAdded;
bool m_bEffectAddedToRecord;
bool m_bEffectAddedToPhoto;
bool m_bSuspended;
bool m_bPreviewing;
DeviceInformationCollection^ m_devInfoCollection;
Windows::Foundation::EventRegistrationToken m_eventRegistrationToken;
bool m_bRotateVideoOnOrientationChange;
bool m_bReversePreviewRotation;
Windows::Foundation::EventRegistrationToken m_orientationChangedEventToken;
void Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
};
}
}

View File

@ -0,0 +1,30 @@
<!--
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
-->
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.App"
RequestedTheme="Light">
<Application.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="Common/StandardStyles.xaml"/>
<ResourceDictionary Source="Sample-Utils/SampleTemplateStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

View File

@ -0,0 +1,116 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
//
// App.xaml.cpp
// Implementation of the App.xaml class.
//
#include "pch.h"
#include "MainPage.xaml.h"
#include "AdvancedCapture.xaml.h"
#include "Common\SuspensionManager.h"
using namespace SDKSample;
using namespace SDKSample::Common;
using namespace SDKSample::MediaCapture;
using namespace Concurrency;
using namespace Platform;
using namespace Windows::ApplicationModel;
using namespace Windows::ApplicationModel::Activation;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Core;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Interop;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
App::App()
{
InitializeComponent();
this->Suspending += ref new SuspendingEventHandler(this, &SDKSample::App::OnSuspending);
}
/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points will
/// be used when the application is launched to open a specific file, to display search results,
/// and so forth.
/// </summary>
/// <param name="pArgs">Details about the launch request and process.</param>
void App::OnLaunched(LaunchActivatedEventArgs^ pArgs)
{
this->LaunchArgs = pArgs;
// Do not repeat app initialization when already running, just ensure that
// the window is active
if (pArgs->PreviousExecutionState == ApplicationExecutionState::Running)
{
Window::Current->Activate();
return;
}
// Create a Frame to act as the navigation context and associate it with
// a SuspensionManager key
auto rootFrame = ref new Frame();
SuspensionManager::RegisterFrame(rootFrame, "AppFrame");
auto prerequisite = task<void>([](){});
if (pArgs->PreviousExecutionState == ApplicationExecutionState::Terminated)
{
// Restore the saved session state only when appropriate, scheduling the
// final launch steps after the restore is complete
prerequisite = SuspensionManager::RestoreAsync();
}
prerequisite.then([=]()
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
if (rootFrame->Content == nullptr)
{
if (!rootFrame->Navigate(TypeName(MainPage::typeid)))
{
throw ref new FailureException("Failed to create initial page");
}
}
// Place the frame in the current Window and ensure that it is active
Window::Current->Content = rootFrame;
Window::Current->Activate();
}, task_continuation_context::use_current());
}
/// <summary>
/// Invoked when application execution is being suspended. Application state is saved
/// without knowing whether the application will be terminated or resumed with the contents
/// of memory still intact.
/// </summary>
/// <param name="sender">The source of the suspend request.</param>
/// <param name="e">Details about the suspend request.</param>
void App::OnSuspending(Object^ sender, SuspendingEventArgs^ e)
{
(void) sender; // Unused parameter
auto deferral = e->SuspendingOperation->GetDeferral();
SuspensionManager::SaveAsync().then([=]()
{
deferral->Complete();
});
}

View File

@ -0,0 +1,35 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
//
// App.xaml.h
// Declaration of the App.xaml class.
//
#pragma once
#include "pch.h"
#include "App.g.h"
#include "MainPage.g.h"
namespace SDKSample
{
ref class App
{
internal:
App();
virtual void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ pArgs);
Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ LaunchArgs;
protected:
virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ pArgs) override;
private:
Windows::UI::Xaml::Controls::Frame^ rootFrame;
};
}

View File

@ -0,0 +1,22 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
#include "pch.h"
#include "MainPage.xaml.h"
#include "Constants.h"
using namespace SDKSample;
Platform::Array<Scenario>^ MainPage::scenariosInner = ref new Platform::Array<Scenario>
{
// The format here is the following:
// { "Description for the sample", "Fully qualified name for the class that implements the scenario" }
{ "Enumerate cameras and add a video effect", "SDKSample.MediaCapture.AdvancedCapture" },
};

View File

@ -0,0 +1,45 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
#pragma once
#include <collection.h>
namespace SDKSample
{
public value struct Scenario
{
Platform::String^ Title;
Platform::String^ ClassName;
};
partial ref class MainPage
{
public:
static property Platform::String^ FEATURE_NAME
{
Platform::String^ get()
{
return ref new Platform::String(L"OpenCV Image Manipulations sample");
}
}
static property Platform::Array<Scenario>^ scenarios
{
Platform::Array<Scenario>^ get()
{
return scenariosInner;
}
}
private:
static Platform::Array<Scenario>^ scenariosInner;
};
}

View File

@ -0,0 +1,156 @@
<!--
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
-->
<common:LayoutAwarePage
x:Class="SDKSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:common="using:SDKSample.Common"
mc:Ignorable="d"
x:Name="RootPage">
<common:LayoutAwarePage.Resources>
<Style x:Key="BaseStatusStyle" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI Semilight"/>
<Setter Property="FontSize" Value="14.667"/>
<Setter Property="Margin" Value="0,0,0,5"/>
</Style>
<Style x:Key="StatusStyle" BasedOn="{StaticResource BaseStatusStyle}" TargetType="TextBlock">
<Setter Property="Foreground" Value="Green"/>
</Style>
<Style x:Key="ErrorStyle" BasedOn="{StaticResource BaseStatusStyle}" TargetType="TextBlock">
<Setter Property="Foreground" Value="Blue"/>
</Style>
</common:LayoutAwarePage.Resources>
<Grid x:Name="LayoutRoot" Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid x:Name="ContentRoot" Background="{StaticResource ApplicationPageBackgroundThemeBrush}" Margin="100,20,100,20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- Header -->
<StackPanel Orientation="Horizontal" Grid.Row="0">
<Image x:Name="WindowsLogo" Stretch="None" Source="Assets/windows-sdk.png" AutomationProperties.Name="Windows Logo" HorizontalAlignment="Left" Grid.Column="0"/>
<TextBlock VerticalAlignment="Bottom" Style="{StaticResource TitleTextStyle}" TextWrapping="Wrap" Grid.Column="1" Text="OpenCV for Windows RT"/>
</StackPanel>
<ScrollViewer x:Name="MainScrollViewer" Grid.Row="1" ZoomMode="Disabled" IsTabStop="False" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Padding="0,0,0,20" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock x:Name="FeatureName" Grid.Row="0" Text="Add Sample Title Here" Style="{StaticResource HeaderTextStyle}" TextWrapping="Wrap"/>
<!-- Content -->
<Grid Grid.Row="1">
<!-- All XAML in this section is purely for design time so you can see sample content in the designer. -->
<!-- This will be replaced at runtime by live content. -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Text="Input" Style="{StaticResource H2Style}"/>
<TextBlock x:Name="ScenarioListLabel" Text="Select Scenario:" Grid.Row="1" Style="{StaticResource SubheaderTextStyle}" Margin="0,5,0,0" />
<ListBox x:Name="Scenarios" Margin="0,0,20,0" Grid.Row="2" AutomationProperties.Name="Scenarios" HorizontalAlignment="Left"
VerticalAlignment="Top" ScrollViewer.HorizontalScrollBarVisibility="Auto"
AutomationProperties.LabeledBy="{Binding ElementName=ScenarioListLabel}" MaxHeight="125">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBlock x:Name="DescriptionText" Margin="0,5,0,0" Text="Description:" Style="{StaticResource SubheaderTextStyle}" Grid.Row="1" Grid.Column="1"/>
<!-- Input Scenarios -->
<UserControl x:Name="InputSection" Margin="0,5,0,0" IsTabStop="False" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<!-- Output section -->
<TextBlock Text="Output" Grid.Row="5" Margin="0,25,0,20" Style="{StaticResource H2Style}" Grid.ColumnSpan="2"/>
<TextBlock x:Name="StatusBlock" Grid.Row="6" Margin="0,0,0,5" Grid.ColumnSpan="2"/>
<!-- Output Scenarios -->
<UserControl x:Name="OutputSection" Grid.Row="7" Grid.ColumnSpan="2" BorderThickness="0"/>
</Grid>
</Grid>
</Grid>
</ScrollViewer>
<!-- Footer -->
<Grid x:Name="Footer" Grid.Row="3" Margin="0,10,0,10" VerticalAlignment="Bottom" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel x:Name="FooterPanel" Orientation="Horizontal" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right"/>
</Grid>
</Grid>
<VisualStateManager.VisualStateGroups>
<!-- Visual states reflect the application's view state -->
<VisualStateGroup>
<VisualState x:Name="FullScreenLandscape">
<Storyboard>
</Storyboard>
</VisualState>
<VisualState x:Name="Filled">
<Storyboard>
</Storyboard>
</VisualState>
<VisualState x:Name="FullScreenPortrait">
<Storyboard>
</Storyboard>
</VisualState>
<VisualState x:Name="Snapped">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="ContentRoot">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Thickness>20,20,20,20</Thickness>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</common:LayoutAwarePage>

View File

@ -0,0 +1,315 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
//
// MainPage.xaml.cpp
// Implementation of the MainPage.xaml class.
//
#include "pch.h"
#include "MainPage.xaml.h"
#include "App.xaml.h"
#include <collection.h>
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Platform;
using namespace SDKSample;
using namespace Windows::UI::Xaml::Navigation;
using namespace Windows::UI::Xaml::Interop;
using namespace Windows::Graphics::Display;
using namespace Windows::UI::ViewManagement;
MainPage^ MainPage::Current = nullptr;
MainPage::MainPage()
{
InitializeComponent();
// This frame is hidden, meaning it is never shown. It is simply used to load
// each scenario page and then pluck out the input and output sections and
// place them into the UserControls on the main page.
HiddenFrame = ref new Windows::UI::Xaml::Controls::Frame();
HiddenFrame->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
ContentRoot->Children->Append(HiddenFrame);
FeatureName->Text = FEATURE_NAME;
this->SizeChanged += ref new SizeChangedEventHandler(this, &MainPage::MainPage_SizeChanged);
Scenarios->SelectionChanged += ref new SelectionChangedEventHandler(this, &MainPage::Scenarios_SelectionChanged);
MainPage::Current = this;
autoSizeInputSectionWhenSnapped = true;
}
/// <summary>
/// We need to handle SizeChanged so that we can make the sample layout property
/// in the various layouts.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void MainPage::MainPage_SizeChanged(Object^ sender, SizeChangedEventArgs^ e)
{
InvalidateSize();
MainPageSizeChangedEventArgs^ args = ref new MainPageSizeChangedEventArgs();
args->ViewState = ApplicationView::Value;
MainPageResized(this, args);
}
void MainPage::InvalidateSize()
{
// Get the window width
double windowWidth = this->ActualWidth;
if (windowWidth != 0.0)
{
// Get the width of the ListBox.
double listBoxWidth = Scenarios->ActualWidth;
// Is the ListBox using any margins that we need to consider?
double listBoxMarginLeft = Scenarios->Margin.Left;
double listBoxMarginRight = Scenarios->Margin.Right;
// Figure out how much room is left after considering the list box width
double availableWidth = windowWidth - listBoxWidth;
// Is the top most child using margins?
double layoutRootMarginLeft = ContentRoot->Margin.Left;
double layoutRootMarginRight = ContentRoot->Margin.Right;
// We have different widths to use depending on the view state
if (ApplicationView::Value != ApplicationViewState::Snapped)
{
// Make us as big as the the left over space, factoring in the ListBox width, the ListBox margins.
// and the LayoutRoot's margins
InputSection->Width = ((availableWidth) -
(layoutRootMarginLeft + layoutRootMarginRight + listBoxMarginLeft + listBoxMarginRight));
}
else
{
// Make us as big as the left over space, factoring in just the LayoutRoot's margins.
if (autoSizeInputSectionWhenSnapped)
{
InputSection->Width = (windowWidth - (layoutRootMarginLeft + layoutRootMarginRight));
}
}
}
InvalidateViewState();
}
void MainPage::InvalidateViewState()
{
// Are we going to snapped mode?
if (ApplicationView::Value == ApplicationViewState::Snapped)
{
Grid::SetRow(DescriptionText, 3);
Grid::SetColumn(DescriptionText, 0);
Grid::SetRow(InputSection, 4);
Grid::SetColumn(InputSection, 0);
Grid::SetRow(FooterPanel, 2);
Grid::SetColumn(FooterPanel, 0);
}
else
{
Grid::SetRow(DescriptionText, 1);
Grid::SetColumn(DescriptionText, 1);
Grid::SetRow(InputSection, 2);
Grid::SetColumn(InputSection, 1);
Grid::SetRow(FooterPanel, 1);
Grid::SetColumn(FooterPanel, 1);
}
// Since we don't load the scenario page in the traditional manner (we just pluck out the
// input and output sections from the page) we need to ensure that any VSM code used
// by the scenario's input and output sections is fired.
VisualStateManager::GoToState(InputSection, "Input" + LayoutAwarePage::DetermineVisualState(ApplicationView::Value), false);
VisualStateManager::GoToState(OutputSection, "Output" + LayoutAwarePage::DetermineVisualState(ApplicationView::Value), false);
}
void MainPage::PopulateScenarios()
{
ScenarioList = ref new Platform::Collections::Vector<Object^>();
// Populate the ListBox with the list of scenarios as defined in Constants.cpp.
for (unsigned int i = 0; i < scenarios->Length; ++i)
{
Scenario s = scenarios[i];
ListBoxItem^ item = ref new ListBoxItem();
item->Name = s.ClassName;
item->Content = (i + 1).ToString() + ") " + s.Title;
ScenarioList->Append(item);
}
// Bind the ListBox to the scenario list.
Scenarios->ItemsSource = ScenarioList;
Scenarios->ScrollIntoView(Scenarios->SelectedItem);
}
/// <summary>
/// This method is responsible for loading the individual input and output sections for each scenario. This
/// is based on navigating a hidden Frame to the ScenarioX.xaml page and then extracting out the input
/// and output sections into the respective UserControl on the main page.
/// </summary>
/// <param name="scenarioName"></param>
void MainPage::LoadScenario(String^ scenarioName)
{
autoSizeInputSectionWhenSnapped = true;
// Load the ScenarioX.xaml file into the Frame.
TypeName scenarioType = {scenarioName, TypeKind::Custom};
HiddenFrame->Navigate(scenarioType, this);
// Get the top element, the Page, so we can look up the elements
// that represent the input and output sections of the ScenarioX file.
Page^ hiddenPage = safe_cast<Page^>(HiddenFrame->Content);
// Get each element.
UIElement^ input = safe_cast<UIElement^>(hiddenPage->FindName("Input"));
UIElement^ output = safe_cast<UIElement^>(hiddenPage->FindName("Output"));
if (input == nullptr)
{
// Malformed input section.
NotifyUser("Cannot load scenario input section for " + scenarioName +
" Make sure root of input section markup has x:Name of 'Input'", NotifyType::ErrorMessage);
return;
}
if (output == nullptr)
{
// Malformed output section.
NotifyUser("Cannot load scenario output section for " + scenarioName +
" Make sure root of output section markup has x:Name of 'Output'", NotifyType::ErrorMessage);
return;
}
// Find the LayoutRoot which parents the input and output sections in the main page.
Panel^ panel = safe_cast<Panel^>(hiddenPage->FindName("LayoutRoot"));
if (panel != nullptr)
{
unsigned int index = 0;
UIElementCollection^ collection = panel->Children;
// Get rid of the content that is currently in the intput and output sections.
collection->IndexOf(input, &index);
collection->RemoveAt(index);
collection->IndexOf(output, &index);
collection->RemoveAt(index);
// Populate the input and output sections with the newly loaded content.
InputSection->Content = input;
OutputSection->Content = output;
ScenarioLoaded(this, nullptr);
}
else
{
// Malformed Scenario file.
NotifyUser("Cannot load scenario: " + scenarioName + ". Make sure root tag in the '" +
scenarioName + "' file has an x:Name of 'LayoutRoot'", NotifyType::ErrorMessage);
}
}
void MainPage::Scenarios_SelectionChanged(Object^ sender, SelectionChangedEventArgs^ e)
{
if (Scenarios->SelectedItem != nullptr)
{
NotifyUser("", NotifyType::StatusMessage);
LoadScenario((safe_cast<ListBoxItem^>(Scenarios->SelectedItem))->Name);
InvalidateSize();
}
}
void MainPage::NotifyUser(String^ strMessage, NotifyType type)
{
switch (type)
{
case NotifyType::StatusMessage:
// Use the status message style.
StatusBlock->Style = safe_cast<Windows::UI::Xaml::Style^>(this->Resources->Lookup("StatusStyle"));
break;
case NotifyType::ErrorMessage:
// Use the error message style.
StatusBlock->Style = safe_cast<Windows::UI::Xaml::Style^>(this->Resources->Lookup("ErrorStyle"));
break;
default:
break;
}
StatusBlock->Text = strMessage;
// Collapsed the StatusBlock if it has no text to conserve real estate.
if (StatusBlock->Text != "")
{
StatusBlock->Visibility = Windows::UI::Xaml::Visibility::Visible;
}
else
{
StatusBlock->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
}
}
void MainPage::Footer_Click(Object^ sender, RoutedEventArgs^ e)
{
auto uri = ref new Uri((String^)((HyperlinkButton^)sender)->Tag);
Windows::System::Launcher::LaunchUriAsync(uri);
}
/// <summary>
/// Populates the page with content passed during navigation. Any saved state is also
/// provided when recreating a page from a prior session.
/// </summary>
/// <param name="navigationParameter">The parameter value passed to
/// <see cref="Frame::Navigate(Type, Object)"/> when this page was initially requested.
/// </param>
/// <param name="pageState">A map of state preserved by this page during an earlier
/// session. This will be null the first time a page is visited.</param>
void MainPage::LoadState(Object^ navigationParameter, IMap<String^, Object^>^ pageState)
{
(void) navigationParameter; // Unused parameter
PopulateScenarios();
// Starting scenario is the first or based upon a previous state.
ListBoxItem^ startingScenario = nullptr;
int startingScenarioIndex = -1;
if (pageState != nullptr && pageState->HasKey("SelectedScenarioIndex"))
{
startingScenarioIndex = safe_cast<int>(pageState->Lookup("SelectedScenarioIndex"));
}
Scenarios->SelectedIndex = startingScenarioIndex != -1 ? startingScenarioIndex : 0;
InvalidateViewState();
}
/// <summary>
/// Preserves state associated with this page in case the application is suspended or the
/// page is discarded from the navigation cache. Values must conform to the serialization
/// requirements of <see cref="SuspensionManager::SessionState"/>.
/// </summary>
/// <param name="pageState">An empty map to be populated with serializable state.</param>
void MainPage::SaveState(IMap<String^, Object^>^ pageState)
{
int selectedListBoxItemIndex = Scenarios->SelectedIndex;
pageState->Insert("SelectedScenarioIndex", selectedListBoxItemIndex);
}

View File

@ -0,0 +1,105 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
//
// MainPage.xaml.h
// Declaration of the MainPage.xaml class.
//
#pragma once
#include "pch.h"
#include "MainPage.g.h"
#include "Common\LayoutAwarePage.h" // Required by generated header
#include "Constants.h"
namespace SDKSample
{
public enum class NotifyType
{
StatusMessage,
ErrorMessage
};
public ref class MainPageSizeChangedEventArgs sealed
{
public:
property Windows::UI::ViewManagement::ApplicationViewState ViewState
{
Windows::UI::ViewManagement::ApplicationViewState get()
{
return viewState;
}
void set(Windows::UI::ViewManagement::ApplicationViewState value)
{
viewState = value;
}
}
private:
Windows::UI::ViewManagement::ApplicationViewState viewState;
};
public ref class MainPage sealed
{
public:
MainPage();
protected:
virtual void LoadState(Platform::Object^ navigationParameter,
Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ pageState) override;
virtual void SaveState(Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ pageState) override;
internal:
property bool AutoSizeInputSectionWhenSnapped
{
bool get()
{
return autoSizeInputSectionWhenSnapped;
}
void set(bool value)
{
autoSizeInputSectionWhenSnapped = value;
}
}
property Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ LaunchArgs
{
Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ get()
{
return safe_cast<App^>(App::Current)->LaunchArgs;
}
}
void NotifyUser(Platform::String^ strMessage, NotifyType type);
void LoadScenario(Platform::String^ scenarioName);
event Windows::Foundation::EventHandler<Platform::Object^>^ ScenarioLoaded;
event Windows::Foundation::EventHandler<MainPageSizeChangedEventArgs^>^ MainPageResized;
private:
void PopulateScenarios();
void InvalidateSize();
void InvalidateViewState();
Platform::Collections::Vector<Object^>^ ScenarioList;
Windows::UI::Xaml::Controls::Frame^ HiddenFrame;
void Footer_Click(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
bool autoSizeInputSectionWhenSnapped;
void MainPage_SizeChanged(Object^ sender, Windows::UI::Xaml::SizeChangedEventArgs^ e);
void Scenarios_SelectionChanged(Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e);
internal:
static MainPage^ Current;
};
}

View File

@ -0,0 +1,54 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MediaCapture", "MediaCapture.vcxproj", "{C5B886A7-8300-46FF-B533-9613DE2AF637}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OcvTransform", "MediaExtensions\OcvTransform\OcvTransform.vcxproj", "{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|ARM = Release|ARM
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|ARM.ActiveCfg = Debug|ARM
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|ARM.Build.0 = Debug|ARM
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|ARM.Deploy.0 = Debug|ARM
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|Win32.ActiveCfg = Debug|Win32
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|Win32.Build.0 = Debug|Win32
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|Win32.Deploy.0 = Debug|Win32
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|x64.ActiveCfg = Debug|x64
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|x64.Build.0 = Debug|x64
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|x64.Deploy.0 = Debug|x64
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|ARM.ActiveCfg = Release|ARM
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|ARM.Build.0 = Release|ARM
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|ARM.Deploy.0 = Release|ARM
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|Win32.ActiveCfg = Release|Win32
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|Win32.Build.0 = Release|Win32
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|Win32.Deploy.0 = Release|Win32
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|x64.ActiveCfg = Release|x64
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|x64.Build.0 = Release|x64
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|x64.Deploy.0 = Release|x64
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Debug|ARM.ActiveCfg = Debug|ARM
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Debug|ARM.Build.0 = Debug|ARM
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Debug|Win32.ActiveCfg = Debug|Win32
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Debug|Win32.Build.0 = Debug|Win32
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Debug|x64.ActiveCfg = Debug|x64
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Debug|x64.Build.0 = Debug|x64
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Release|ARM.ActiveCfg = Release|ARM
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Release|ARM.Build.0 = Release|ARM
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Release|Win32.ActiveCfg = Release|Win32
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Release|Win32.Build.0 = Release|Win32
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Release|x64.ActiveCfg = Release|x64
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,200 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{C5B886A7-8300-46FF-B533-9613DE2AF637}</ProjectGuid>
<RootNamespace>SDKSample</RootNamespace>
<DefaultLanguage>en-US</DefaultLanguage>
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
<AppContainerApplication>true</AppContainerApplication>
<ProjectName>MediaCapture</ProjectName>
<ApplicationType>Windows Store</ApplicationType>
<ApplicationTypeRevision>8.1</ApplicationTypeRevision>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="opencv.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="opencv.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="opencv.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="opencv.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="opencv.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="opencv.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros">
<AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision>
<AppxBundlePlatforms>x86</AppxBundlePlatforms>
<PackageCertificateThumbprint>76D64E4F88C9B7D47ACA757CDFD15D6F3AD81D92</PackageCertificateThumbprint>
<PackageCertificateKeyFile>MediaCapture_TemporaryKey.pfx</PackageCertificateKeyFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="AdvancedCapture.xaml.h">
<DependentUpon>AdvancedCapture.xaml</DependentUpon>
<SubType>Code</SubType>
</ClInclude>
<ClInclude Include="Constants.h" />
<ClInclude Include="MainPage.xaml.h">
<DependentUpon>MainPage.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="pch.h" />
<ClInclude Include="Common\LayoutAwarePage.h" />
<ClInclude Include="Common\SuspensionManager.h" />
<ClInclude Include="App.xaml.h">
<DependentUpon>App.xaml</DependentUpon>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="AdvancedCapture.xaml">
<SubType>Designer</SubType>
</Page>
<Page Include="Common\StandardStyles.xaml">
<SubType>Designer</SubType>
</Page>
<Page Include="MainPage.xaml" />
<Page Include="Sample-Utils\SampleTemplateStyles.xaml">
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
</ItemGroup>
<ItemGroup>
<ClCompile Include="AdvancedCapture.xaml.cpp">
<DependentUpon>AdvancedCapture.xaml</DependentUpon>
<SubType>Code</SubType>
</ClCompile>
<ClCompile Include="App.xaml.cpp">
<DependentUpon>App.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="Common\LayoutAwarePage.cpp" />
<ClCompile Include="Constants.cpp" />
<ClCompile Include="Common\SuspensionManager.cpp" />
<ClCompile Include="MainPage.xaml.cpp">
<DependentUpon>MainPage.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Image Include="assets\opencv-logo-150.png" />
<Image Include="assets\opencv-logo-30.png" />
<Image Include="Assets\splash-sdk.png" />
<Image Include="Assets\StoreLogo.png" />
<Image Include="Assets\windows-sdk.scale-100.png">
<DeploymentContent>true</DeploymentContent>
</Image>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="MediaExtensions\OcvTransform\OcvTransform.vcxproj">
<Project>{ba69218f-da5c-4d14-a78d-21a9e4dec669}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ApplicationDefinition Include="App.xaml" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="AdvancedCapture.xaml.cpp" />
<ClCompile Include="App.xaml.cpp" />
<ClCompile Include="Common\LayoutAwarePage.cpp" />
<ClCompile Include="Constants.cpp" />
<ClCompile Include="Common\SuspensionManager.cpp" />
<ClCompile Include="MainPage.xaml.cpp" />
<ClCompile Include="pch.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="AdvancedCapture.xaml.h" />
<ClInclude Include="Constants.h" />
<ClInclude Include="MainPage.xaml.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="Common\LayoutAwarePage.h" />
<ClInclude Include="Common\SuspensionManager.h" />
<ClInclude Include="App.xaml.h" />
</ItemGroup>
<ItemGroup>
<Image Include="assets\opencv-logo-30.png">
<Filter>Assets</Filter>
</Image>
<Image Include="assets\opencv-logo-150.png">
<Filter>Assets</Filter>
</Image>
<Image Include="Assets\splash-sdk.png">
<Filter>Assets</Filter>
</Image>
<Image Include="Assets\StoreLogo.png">
<Filter>Assets</Filter>
</Image>
<Image Include="Assets\windows-sdk.scale-100.png" />
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest" />
</ItemGroup>
<ItemGroup>
<Page Include="AdvancedCapture.xaml" />
<Page Include="Common\StandardStyles.xaml" />
<Page Include="MainPage.xaml" />
<Page Include="Sample-Utils\SampleTemplateStyles.xaml" />
</ItemGroup>
<ItemGroup>
<Filter Include="Assets">
<UniqueIdentifier>{392352d8-f913-4741-82cf-d8075bb6f022}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="MediaCapture_TemporaryKey.pfx" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,81 @@
#pragma once
//////////////////////////////////////////////////////////////////////////
// AsyncCallback [template]
//
// Description:
// Helper class that routes IMFAsyncCallback::Invoke calls to a class
// method on the parent class.
//
// Usage:
// Add this class as a member variable. In the parent class constructor,
// initialize the AsyncCallback class like this:
// m_cb(this, &CYourClass::OnInvoke)
// where
// m_cb = AsyncCallback object
// CYourClass = parent class
// OnInvoke = Method in the parent class to receive Invoke calls.
//
// The parent's OnInvoke method (you can name it anything you like) must
// have a signature that matches the InvokeFn typedef below.
//////////////////////////////////////////////////////////////////////////
// T: Type of the parent object
template<class T>
class AsyncCallback : public IMFAsyncCallback
{
public:
typedef HRESULT (T::*InvokeFn)(IMFAsyncResult *pAsyncResult);
AsyncCallback(T *pParent, InvokeFn fn) : m_pParent(pParent), m_pInvokeFn(fn)
{
}
// IUnknown
STDMETHODIMP_(ULONG) AddRef() {
// Delegate to parent class.
return m_pParent->AddRef();
}
STDMETHODIMP_(ULONG) Release() {
// Delegate to parent class.
return m_pParent->Release();
}
STDMETHODIMP QueryInterface(REFIID iid, void** ppv)
{
if (!ppv)
{
return E_POINTER;
}
if (iid == __uuidof(IUnknown))
{
*ppv = static_cast<IUnknown*>(static_cast<IMFAsyncCallback*>(this));
}
else if (iid == __uuidof(IMFAsyncCallback))
{
*ppv = static_cast<IMFAsyncCallback*>(this);
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
// IMFAsyncCallback methods
STDMETHODIMP GetParameters(DWORD*, DWORD*)
{
// Implementation of this method is optional.
return E_NOTIMPL;
}
STDMETHODIMP Invoke(IMFAsyncResult* pAsyncResult)
{
return (m_pParent->*m_pInvokeFn)(pAsyncResult);
}
T *m_pParent;
InvokeFn m_pInvokeFn;
};

View File

@ -0,0 +1,101 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
//////////////////////////////////////////////////////////////////////////
// VideoBufferLock
//
// Description:
// Locks a video buffer that might or might not support IMF2DBuffer.
//
//////////////////////////////////////////////////////////////////////////
class VideoBufferLock
{
public:
VideoBufferLock(IMFMediaBuffer *pBuffer) : m_p2DBuffer(NULL)
{
m_pBuffer = pBuffer;
m_pBuffer->AddRef();
// Query for the 2-D buffer interface. OK if this fails.
m_pBuffer->QueryInterface(IID_PPV_ARGS(&m_p2DBuffer));
}
~VideoBufferLock()
{
UnlockBuffer();
SafeRelease(&m_pBuffer);
SafeRelease(&m_p2DBuffer);
}
// LockBuffer:
// Locks the buffer. Returns a pointer to scan line 0 and returns the stride.
// The caller must provide the default stride as an input parameter, in case
// the buffer does not expose IMF2DBuffer. You can calculate the default stride
// from the media type.
HRESULT LockBuffer(
LONG lDefaultStride, // Minimum stride (with no padding).
DWORD dwHeightInPixels, // Height of the image, in pixels.
BYTE **ppbScanLine0, // Receives a pointer to the start of scan line 0.
LONG *plStride // Receives the actual stride.
)
{
HRESULT hr = S_OK;
// Use the 2-D version if available.
if (m_p2DBuffer)
{
hr = m_p2DBuffer->Lock2D(ppbScanLine0, plStride);
}
else
{
// Use non-2D version.
BYTE *pData = NULL;
hr = m_pBuffer->Lock(&pData, NULL, NULL);
if (SUCCEEDED(hr))
{
*plStride = lDefaultStride;
if (lDefaultStride < 0)
{
// Bottom-up orientation. Return a pointer to the start of the
// last row *in memory* which is the top row of the image.
*ppbScanLine0 = pData + abs(lDefaultStride) * (dwHeightInPixels - 1);
}
else
{
// Top-down orientation. Return a pointer to the start of the
// buffer.
*ppbScanLine0 = pData;
}
}
}
return hr;
}
HRESULT UnlockBuffer()
{
if (m_p2DBuffer)
{
return m_p2DBuffer->Unlock2D();
}
else
{
return m_pBuffer->Unlock();
}
}
private:
IMFMediaBuffer *m_pBuffer;
IMF2DBuffer *m_p2DBuffer;
};

View File

@ -0,0 +1,62 @@
#pragma once
//////////////////////////////////////////////////////////////////////////
// CritSec
// Description: Wraps a critical section.
//////////////////////////////////////////////////////////////////////////
class CritSec
{
public:
CRITICAL_SECTION m_criticalSection;
public:
CritSec()
{
InitializeCriticalSectionEx(&m_criticalSection, 100, 0);
}
~CritSec()
{
DeleteCriticalSection(&m_criticalSection);
}
_Acquires_lock_(m_criticalSection)
void Lock()
{
EnterCriticalSection(&m_criticalSection);
}
_Releases_lock_(m_criticalSection)
void Unlock()
{
LeaveCriticalSection(&m_criticalSection);
}
};
//////////////////////////////////////////////////////////////////////////
// AutoLock
// Description: Provides automatic locking and unlocking of a
// of a critical section.
//
// Note: The AutoLock object must go out of scope before the CritSec.
//////////////////////////////////////////////////////////////////////////
class AutoLock
{
private:
CritSec *m_pCriticalSection;
public:
_Acquires_lock_(m_pCriticalSection)
AutoLock(CritSec& crit)
{
m_pCriticalSection = &crit;
m_pCriticalSection->Lock();
}
_Releases_lock_(m_pCriticalSection)
~AutoLock()
{
m_pCriticalSection->Unlock();
}
};

View File

@ -0,0 +1,516 @@
//-----------------------------------------------------------------------------
// File: Linklist.h
// Desc: Linked list class.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#pragma once
// Notes:
//
// The List class template implements a simple double-linked list.
// It uses STL's copy semantics.
// There are two versions of the Clear() method:
// Clear(void) clears the list w/out cleaning up the object.
// Clear(FN fn) takes a functor object that releases the objects, if they need cleanup.
// The List class supports enumeration. Example of usage:
//
// List<T>::POSIITON pos = list.GetFrontPosition();
// while (pos != list.GetEndPosition())
// {
// T item;
// hr = list.GetItemPos(&item);
// pos = list.Next(pos);
// }
// The ComPtrList class template derives from List<> and implements a list of COM pointers.
template <class T>
struct NoOp
{
void operator()(T& t)
{
}
};
template <class T>
class List
{
protected:
// Nodes in the linked list
struct Node
{
Node *prev;
Node *next;
T item;
Node() : prev(nullptr), next(nullptr)
{
}
Node(T item) : prev(nullptr), next(nullptr)
{
this->item = item;
}
T Item() const { return item; }
};
public:
// Object for enumerating the list.
class POSITION
{
friend class List<T>;
public:
POSITION() : pNode(nullptr)
{
}
bool operator==(const POSITION &p) const
{
return pNode == p.pNode;
}
bool operator!=(const POSITION &p) const
{
return pNode != p.pNode;
}
private:
const Node *pNode;
POSITION(Node *p) : pNode(p)
{
}
};
protected:
Node m_anchor; // Anchor node for the linked list.
DWORD m_count; // Number of items in the list.
Node* Front() const
{
return m_anchor.next;
}
Node* Back() const
{
return m_anchor.prev;
}
virtual HRESULT InsertAfter(T item, Node *pBefore)
{
if (pBefore == nullptr)
{
return E_POINTER;
}
Node *pNode = new Node(item);
if (pNode == nullptr)
{
return E_OUTOFMEMORY;
}
Node *pAfter = pBefore->next;
pBefore->next = pNode;
pAfter->prev = pNode;
pNode->prev = pBefore;
pNode->next = pAfter;
m_count++;
return S_OK;
}
virtual HRESULT GetItem(const Node *pNode, T* ppItem)
{
if (pNode == nullptr || ppItem == nullptr)
{
return E_POINTER;
}
*ppItem = pNode->item;
return S_OK;
}
// RemoveItem:
// Removes a node and optionally returns the item.
// ppItem can be nullptr.
virtual HRESULT RemoveItem(Node *pNode, T *ppItem)
{
if (pNode == nullptr)
{
return E_POINTER;
}
assert(pNode != &m_anchor); // We should never try to remove the anchor node.
if (pNode == &m_anchor)
{
return E_INVALIDARG;
}
T item;
// The next node's previous is this node's previous.
pNode->next->prev = pNode->prev;
// The previous node's next is this node's next.
pNode->prev->next = pNode->next;
item = pNode->item;
delete pNode;
m_count--;
if (ppItem)
{
*ppItem = item;
}
return S_OK;
}
public:
List()
{
m_anchor.next = &m_anchor;
m_anchor.prev = &m_anchor;
m_count = 0;
}
virtual ~List()
{
Clear();
}
// Insertion functions
HRESULT InsertBack(T item)
{
return InsertAfter(item, m_anchor.prev);
}
HRESULT InsertFront(T item)
{
return InsertAfter(item, &m_anchor);
}
HRESULT InsertPos(POSITION pos, T item)
{
if (pos.pNode == nullptr)
{
return InsertBack(item);
}
return InsertAfter(item, pos.pNode->prev);
}
// RemoveBack: Removes the tail of the list and returns the value.
// ppItem can be nullptr if you don't want the item back. (But the method does not release the item.)
HRESULT RemoveBack(T *ppItem)
{
if (IsEmpty())
{
return E_FAIL;
}
else
{
return RemoveItem(Back(), ppItem);
}
}
// RemoveFront: Removes the head of the list and returns the value.
// ppItem can be nullptr if you don't want the item back. (But the method does not release the item.)
HRESULT RemoveFront(T *ppItem)
{
if (IsEmpty())
{
return E_FAIL;
}
else
{
return RemoveItem(Front(), ppItem);
}
}
// GetBack: Gets the tail item.
HRESULT GetBack(T *ppItem)
{
if (IsEmpty())
{
return E_FAIL;
}
else
{
return GetItem(Back(), ppItem);
}
}
// GetFront: Gets the front item.
HRESULT GetFront(T *ppItem)
{
if (IsEmpty())
{
return E_FAIL;
}
else
{
return GetItem(Front(), ppItem);
}
}
// GetCount: Returns the number of items in the list.
DWORD GetCount() const { return m_count; }
bool IsEmpty() const
{
return (GetCount() == 0);
}
// Clear: Takes a functor object whose operator()
// frees the object on the list.
template <class FN>
void Clear(FN& clear_fn)
{
Node *n = m_anchor.next;
// Delete the nodes
while (n != &m_anchor)
{
clear_fn(n->item);
Node *tmp = n->next;
delete n;
n = tmp;
}
// Reset the anchor to point at itself
m_anchor.next = &m_anchor;
m_anchor.prev = &m_anchor;
m_count = 0;
}
// Clear: Clears the list. (Does not delete or release the list items.)
virtual void Clear()
{
NoOp<T> clearOp;
Clear<>(clearOp);
}
// Enumerator functions
POSITION FrontPosition()
{
if (IsEmpty())
{
return POSITION(nullptr);
}
else
{
return POSITION(Front());
}
}
POSITION EndPosition() const
{
return POSITION();
}
HRESULT GetItemPos(POSITION pos, T *ppItem)
{
if (pos.pNode)
{
return GetItem(pos.pNode, ppItem);
}
else
{
return E_FAIL;
}
}
POSITION Next(const POSITION pos)
{
if (pos.pNode && (pos.pNode->next != &m_anchor))
{
return POSITION(pos.pNode->next);
}
else
{
return POSITION(nullptr);
}
}
// Remove an item at a position.
// The item is returns in ppItem, unless ppItem is nullptr.
// NOTE: This method invalidates the POSITION object.
HRESULT Remove(POSITION& pos, T *ppItem)
{
if (pos.pNode)
{
// Remove const-ness temporarily...
Node *pNode = const_cast<Node*>(pos.pNode);
pos = POSITION();
return RemoveItem(pNode, ppItem);
}
else
{
return E_INVALIDARG;
}
}
};
// Typical functors for Clear method.
// ComAutoRelease: Releases COM pointers.
// MemDelete: Deletes pointers to new'd memory.
class ComAutoRelease
{
public:
void operator()(IUnknown *p)
{
if (p)
{
p->Release();
}
}
};
class MemDelete
{
public:
void operator()(void *p)
{
if (p)
{
delete p;
}
}
};
// ComPtrList class
// Derived class that makes it safer to store COM pointers in the List<> class.
// It automatically AddRef's the pointers that are inserted onto the list
// (unless the insertion method fails).
//
// T must be a COM interface type.
// example: ComPtrList<IUnknown>
//
// NULLABLE: If true, client can insert nullptr pointers. This means GetItem can
// succeed but return a nullptr pointer. By default, the list does not allow nullptr
// pointers.
template <class T, bool NULLABLE = FALSE>
class ComPtrList : public List<T*>
{
public:
typedef T* Ptr;
void Clear()
{
ComAutoRelease car;
List<Ptr>::Clear(car);
}
~ComPtrList()
{
Clear();
}
protected:
HRESULT InsertAfter(Ptr item, Node *pBefore)
{
// Do not allow nullptr item pointers unless NULLABLE is true.
if (item == nullptr && !NULLABLE)
{
return E_POINTER;
}
if (item)
{
item->AddRef();
}
HRESULT hr = List<Ptr>::InsertAfter(item, pBefore);
if (FAILED(hr) && item != nullptr)
{
item->Release();
}
return hr;
}
HRESULT GetItem(const Node *pNode, Ptr* ppItem)
{
Ptr pItem = nullptr;
// The base class gives us the pointer without AddRef'ing it.
// If we return the pointer to the caller, we must AddRef().
HRESULT hr = List<Ptr>::GetItem(pNode, &pItem);
if (SUCCEEDED(hr))
{
assert(pItem || NULLABLE);
if (pItem)
{
*ppItem = pItem;
(*ppItem)->AddRef();
}
}
return hr;
}
HRESULT RemoveItem(Node *pNode, Ptr *ppItem)
{
// ppItem can be nullptr, but we need to get the
// item so that we can release it.
// If ppItem is not nullptr, we will AddRef it on the way out.
Ptr pItem = nullptr;
HRESULT hr = List<Ptr>::RemoveItem(pNode, &pItem);
if (SUCCEEDED(hr))
{
assert(pItem || NULLABLE);
if (ppItem && pItem)
{
*ppItem = pItem;
(*ppItem)->AddRef();
}
if (pItem)
{
pItem->Release();
pItem = nullptr;
}
}
return hr;
}
};

View File

@ -0,0 +1,222 @@
//////////////////////////////////////////////////////////////////////////
//
// OpQueue.h
// Async operation queue.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////
#pragma once
#pragma warning( push )
#pragma warning( disable : 4355 ) // 'this' used in base member initializer list
/*
This header file defines an object to help queue and serialize
asynchronous operations.
Background:
To perform an operation asynchronously in Media Foundation, an object
does one of the following:
1. Calls MFPutWorkItem(Ex), using either a standard work queue
identifier or a caller-allocated work queue. The work-queue
thread invokes the object's callback.
2. Creates an async result object (IMFAsyncResult) and calls
MFInvokeCallback to invoke the object's callback.
Ultimately, either of these cause the object's callback to be invoked
from a work-queue thread. The object can then complete the operation
inside the callback.
However, the Media Foundation platform may dispatch async callbacks in
parallel on several threads. Putting an item on a work queue does NOT
guarantee that one operation will complete before the next one starts,
or even that work items will be dispatched in the same order they were
called.
To serialize async operations that should not overlap, an object should
use a queue. While one operation is pending, subsequent operations are
put on the queue, and only dispatched after the previous operation is
complete.
The granularity of a single "operation" depends on the requirements of
that particular object. A single operation might involve several
asynchronous calls before the object dispatches the next operation on
the queue.
*/
//-------------------------------------------------------------------
// OpQueue class template
//
// Base class for an async operation queue.
//
// TOperation: The class used to describe operations. This class must
// implement IUnknown.
//
// The OpQueue class is an abstract class. The derived class must
// implement the following pure-virtual methods:
//
// - IUnknown methods (AddRef, Release, QI)
//
// - DispatchOperation:
//
// Performs the asynchronous operation specified by pOp.
//
// At the end of each operation, the derived class must call
// ProcessQueue to process the next operation in the queue.
//
// NOTE: An operation is not required to complete inside the
// DispatchOperation method. A single operation might consist
// of several asynchronous method calls.
//
// - ValidateOperation:
//
// Checks whether the object can perform the operation specified
// by pOp at this time.
//
// If the object cannot perform the operation now (e.g., because
// another operation is still in progress) the method should
// return MF_E_NOTACCEPTING.
//
//-------------------------------------------------------------------
#include "linklist.h"
#include "AsyncCB.h"
template <class T, class TOperation>
class OpQueue //: public IUnknown
{
public:
typedef ComPtrList<TOperation> OpList;
HRESULT QueueOperation(TOperation *pOp);
protected:
HRESULT ProcessQueue();
HRESULT ProcessQueueAsync(IMFAsyncResult *pResult);
virtual HRESULT DispatchOperation(TOperation *pOp) = 0;
virtual HRESULT ValidateOperation(TOperation *pOp) = 0;
OpQueue(CRITICAL_SECTION& critsec)
: m_OnProcessQueue(static_cast<T *>(this), &OpQueue::ProcessQueueAsync),
m_critsec(critsec)
{
}
virtual ~OpQueue()
{
}
protected:
OpList m_OpQueue; // Queue of operations.
CRITICAL_SECTION& m_critsec; // Protects the queue state.
AsyncCallback<T> m_OnProcessQueue; // ProcessQueueAsync callback.
};
//-------------------------------------------------------------------
// Place an operation on the queue.
// Public method.
//-------------------------------------------------------------------
template <class T, class TOperation>
HRESULT OpQueue<T, TOperation>::QueueOperation(TOperation *pOp)
{
HRESULT hr = S_OK;
EnterCriticalSection(&m_critsec);
hr = m_OpQueue.InsertBack(pOp);
if (SUCCEEDED(hr))
{
hr = ProcessQueue();
}
LeaveCriticalSection(&m_critsec);
return hr;
}
//-------------------------------------------------------------------
// Process the next operation on the queue.
// Protected method.
//
// Note: This method dispatches the operation to a work queue.
//-------------------------------------------------------------------
template <class T, class TOperation>
HRESULT OpQueue<T, TOperation>::ProcessQueue()
{
HRESULT hr = S_OK;
if (m_OpQueue.GetCount() > 0)
{
hr = MFPutWorkItem2(
MFASYNC_CALLBACK_QUEUE_STANDARD, // Use the standard work queue.
0, // Default priority
&m_OnProcessQueue, // Callback method.
nullptr // State object.
);
}
return hr;
}
//-------------------------------------------------------------------
// Process the next operation on the queue.
// Protected method.
//
// Note: This method is called from a work-queue thread.
//-------------------------------------------------------------------
template <class T, class TOperation>
HRESULT OpQueue<T, TOperation>::ProcessQueueAsync(IMFAsyncResult *pResult)
{
HRESULT hr = S_OK;
TOperation *pOp = nullptr;
EnterCriticalSection(&m_critsec);
if (m_OpQueue.GetCount() > 0)
{
hr = m_OpQueue.GetFront(&pOp);
if (SUCCEEDED(hr))
{
hr = ValidateOperation(pOp);
}
if (SUCCEEDED(hr))
{
hr = m_OpQueue.RemoveFront(nullptr);
}
if (SUCCEEDED(hr))
{
(void)DispatchOperation(pOp);
}
}
if (pOp != nullptr)
{
pOp->Release();
}
LeaveCriticalSection(&m_critsec);
return hr;
}
#pragma warning( pop )

View File

@ -0,0 +1,12 @@
import "Windows.Media.idl";
#include <sdkddkver.h>
namespace OcvTransform
{
[version(NTDDI_WIN8)]
runtimeclass OcvImageManipulations
{
interface Windows.Media.IMediaExtension;
}
}

View File

@ -0,0 +1,4 @@
EXPORTS
DllCanUnloadNow PRIVATE
DllGetActivationFactory PRIVATE
DllGetClassObject PRIVATE

View File

@ -0,0 +1,247 @@
// Defines the transform class.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
#ifndef GRAYSCALE_H
#define GRAYSCALE_H
#include <new>
#include <mfapi.h>
#include <mftransform.h>
#include <mfidl.h>
#include <mferror.h>
#include <strsafe.h>
#include <assert.h>
#include <wrl\implements.h>
#include <wrl\module.h>
#include <windows.media.h>
#include "OcvImageManipulations.h"
// CLSID of the MFT.
DEFINE_GUID(CLSID_GrayscaleMFT,
0x2f3dbc05, 0xc011, 0x4a8f, 0xb2, 0x64, 0xe4, 0x2e, 0x35, 0xc6, 0x7b, 0xf4);
//
// * IMPORTANT: If you implement your own MFT, create a new GUID for the CLSID. *
//
// Configuration attributes
// {698649BE-8EAE-4551-A4CB-3EC98FBD3D86}
DEFINE_GUID(OCV_IMAGE_EFFECT,
0x698649be, 0x8eae, 0x4551, 0xa4, 0xcb, 0x3e, 0xc9, 0x8f, 0xbd, 0x3d, 0x86);
enum ProcessingType
{
Preview,
GrayScale,
Canny,
Sobel,
Histogram,
InvalidEffect
};
template <class T> void SafeRelease(T **ppT)
{
if (*ppT)
{
(*ppT)->Release();
*ppT = NULL;
}
}
// OcvImageManipulations class:
// Implements a grayscale video effect.
class OcvImageManipulations
: public Microsoft::WRL::RuntimeClass<
Microsoft::WRL::RuntimeClassFlags< Microsoft::WRL::RuntimeClassType::WinRtClassicComMix >,
ABI::Windows::Media::IMediaExtension,
IMFTransform >
{
InspectableClass(RuntimeClass_OcvTransform_OcvImageManipulations, BaseTrust)
public:
OcvImageManipulations();
~OcvImageManipulations();
STDMETHOD(RuntimeClassInitialize)();
// IMediaExtension
STDMETHODIMP SetProperties(ABI::Windows::Foundation::Collections::IPropertySet *pConfiguration);
// IMFTransform
STDMETHODIMP GetStreamLimits(
DWORD *pdwInputMinimum,
DWORD *pdwInputMaximum,
DWORD *pdwOutputMinimum,
DWORD *pdwOutputMaximum
);
STDMETHODIMP GetStreamCount(
DWORD *pcInputStreams,
DWORD *pcOutputStreams
);
STDMETHODIMP GetStreamIDs(
DWORD dwInputIDArraySize,
DWORD *pdwInputIDs,
DWORD dwOutputIDArraySize,
DWORD *pdwOutputIDs
);
STDMETHODIMP GetInputStreamInfo(
DWORD dwInputStreamID,
MFT_INPUT_STREAM_INFO * pStreamInfo
);
STDMETHODIMP GetOutputStreamInfo(
DWORD dwOutputStreamID,
MFT_OUTPUT_STREAM_INFO * pStreamInfo
);
STDMETHODIMP GetAttributes(IMFAttributes** pAttributes);
STDMETHODIMP GetInputStreamAttributes(
DWORD dwInputStreamID,
IMFAttributes **ppAttributes
);
STDMETHODIMP GetOutputStreamAttributes(
DWORD dwOutputStreamID,
IMFAttributes **ppAttributes
);
STDMETHODIMP DeleteInputStream(DWORD dwStreamID);
STDMETHODIMP AddInputStreams(
DWORD cStreams,
DWORD *adwStreamIDs
);
STDMETHODIMP GetInputAvailableType(
DWORD dwInputStreamID,
DWORD dwTypeIndex, // 0-based
IMFMediaType **ppType
);
STDMETHODIMP GetOutputAvailableType(
DWORD dwOutputStreamID,
DWORD dwTypeIndex, // 0-based
IMFMediaType **ppType
);
STDMETHODIMP SetInputType(
DWORD dwInputStreamID,
IMFMediaType *pType,
DWORD dwFlags
);
STDMETHODIMP SetOutputType(
DWORD dwOutputStreamID,
IMFMediaType *pType,
DWORD dwFlags
);
STDMETHODIMP GetInputCurrentType(
DWORD dwInputStreamID,
IMFMediaType **ppType
);
STDMETHODIMP GetOutputCurrentType(
DWORD dwOutputStreamID,
IMFMediaType **ppType
);
STDMETHODIMP GetInputStatus(
DWORD dwInputStreamID,
DWORD *pdwFlags
);
STDMETHODIMP GetOutputStatus(DWORD *pdwFlags);
STDMETHODIMP SetOutputBounds(
LONGLONG hnsLowerBound,
LONGLONG hnsUpperBound
);
STDMETHODIMP ProcessEvent(
DWORD dwInputStreamID,
IMFMediaEvent *pEvent
);
STDMETHODIMP ProcessMessage(
MFT_MESSAGE_TYPE eMessage,
ULONG_PTR ulParam
);
STDMETHODIMP ProcessInput(
DWORD dwInputStreamID,
IMFSample *pSample,
DWORD dwFlags
);
STDMETHODIMP ProcessOutput(
DWORD dwFlags,
DWORD cOutputBufferCount,
MFT_OUTPUT_DATA_BUFFER *pOutputSamples, // one per stream
DWORD *pdwStatus
);
private:
// HasPendingOutput: Returns TRUE if the MFT is holding an input sample.
BOOL HasPendingOutput() const { return m_pSample != NULL; }
// IsValidInputStream: Returns TRUE if dwInputStreamID is a valid input stream identifier.
BOOL IsValidInputStream(DWORD dwInputStreamID) const
{
return dwInputStreamID == 0;
}
// IsValidOutputStream: Returns TRUE if dwOutputStreamID is a valid output stream identifier.
BOOL IsValidOutputStream(DWORD dwOutputStreamID) const
{
return dwOutputStreamID == 0;
}
HRESULT OnGetPartialType(DWORD dwTypeIndex, IMFMediaType **ppmt);
HRESULT OnCheckInputType(IMFMediaType *pmt);
HRESULT OnCheckOutputType(IMFMediaType *pmt);
HRESULT OnCheckMediaType(IMFMediaType *pmt);
void OnSetInputType(IMFMediaType *pmt);
void OnSetOutputType(IMFMediaType *pmt);
HRESULT BeginStreaming();
HRESULT EndStreaming();
HRESULT OnProcessOutput(IMFMediaBuffer *pIn, IMFMediaBuffer *pOut);
HRESULT OnFlush();
HRESULT UpdateFormatInfo();
CRITICAL_SECTION m_critSec;
// Transformation parameters
ProcessingType m_TransformType;
// Streaming
bool m_bStreamingInitialized;
IMFSample *m_pSample; // Input sample.
IMFMediaType *m_pInputType; // Input media type.
IMFMediaType *m_pOutputType; // Output media type.
// Fomat information
UINT32 m_imageWidthInPixels;
UINT32 m_imageHeightInPixels;
DWORD m_cbImageSize; // Image size, in bytes.
IMFAttributes *m_pAttributes;
};
#endif

View File

@ -0,0 +1,327 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>OcvTransform</RootNamespace>
<ProjectName>OcvTransform</ProjectName>
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
<AppContainerApplication>true</AppContainerApplication>
<ApplicationType>Windows Store</ApplicationType>
<ApplicationTypeRevision>8.1</ApplicationTypeRevision>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<PropertyGroup>
<DefaultLanguage>en-US</DefaultLanguage>
</PropertyGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="opencv.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="opencv.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="opencv.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="opencv.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="opencv.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="opencv.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<GenerateManifest>false</GenerateManifest>
<OutDir>$(Configuration)\$(MSBuildProjectName)\</OutDir>
<LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<GenerateManifest>false</GenerateManifest>
<OutDir>$(Configuration)\$(MSBuildProjectName)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PreprocessorDefinitions>_WINRT_DLL;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
<CompileAsWinRT>false</CompileAsWinRT>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>OcvTransform.def</ModuleDefinitionFile>
</Link>
<CustomBuildStep>
<Command>mdmerge -metadata_dir "$(WindowsSDK_MetadataPath)" -o "$(ProjectDir)$(Configuration)\$(MSBuildProjectName)" -i "$(MSBuildProjectDirectory)" -v -partial</Command>
<Outputs>$(ProjectDir)$(Configuration)\$(MSBuildProjectName)\$(ProjectName).winmd</Outputs>
</CustomBuildStep>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PreprocessorDefinitions>_WINRT_DLL;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
<CompileAsWinRT>false</CompileAsWinRT>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>OcvTransform.def</ModuleDefinitionFile>
</Link>
<CustomBuildStep>
<Command>mdmerge -metadata_dir "$(WindowsSDK_MetadataPath)" -o "$(SolutionDir)$(Platform)\$(Configuration)\$(MSBuildProjectName)" -i "$(MSBuildProjectDirectory)" -v -partial</Command>
<Outputs>$(SolutionDir)$(Platform)\$(Configuration)\$(MSBuildProjectName)\$(ProjectName).winmd</Outputs>
</CustomBuildStep>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PreprocessorDefinitions>_WINRT_DLL;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
<CompileAsWinRT>false</CompileAsWinRT>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>OcvTransform.def</ModuleDefinitionFile>
</Link>
<CustomBuildStep>
<Command>mdmerge -metadata_dir "$(WindowsSDK_MetadataPath)" -o "$(SolutionDir)$(Platform)\$(Configuration)\$(MSBuildProjectName)" -i "$(MSBuildProjectDirectory)" -v -partial</Command>
<Outputs>$(SolutionDir)$(Platform)\$(Configuration)\$(MSBuildProjectName)\$(ProjectName).winmd</Outputs>
</CustomBuildStep>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PreprocessorDefinitions>_WINRT_DLL;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
<CompileAsWinRT>false</CompileAsWinRT>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>OcvTransform.def</ModuleDefinitionFile>
</Link>
<CustomBuildStep>
<Command>mdmerge -metadata_dir "$(WindowsSDK_MetadataPath)" -o "$(ProjectDir)$(Configuration)\$(MSBuildProjectName)" -i "$(MSBuildProjectDirectory)" -v -partial</Command>
<Outputs>$(ProjectDir)$(Configuration)\$(MSBuildProjectName)\$(ProjectName).winmd</Outputs>
</CustomBuildStep>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PreprocessorDefinitions>_WINRT_DLL;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
<CompileAsWinRT>false</CompileAsWinRT>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>OcvTransform.def</ModuleDefinitionFile>
</Link>
<CustomBuildStep>
<Command>mdmerge -metadata_dir "$(WindowsSDK_MetadataPath)" -o "$(SolutionDir)$(Platform)\$(Configuration)\$(MSBuildProjectName)" -i "$(MSBuildProjectDirectory)" -v -partial</Command>
<Outputs>$(SolutionDir)$(Platform)\$(Configuration)\$(MSBuildProjectName)\$(ProjectName).winmd</Outputs>
</CustomBuildStep>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PreprocessorDefinitions>_WINRT_DLL;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
<CompileAsWinRT>false</CompileAsWinRT>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>OcvTransform.def</ModuleDefinitionFile>
</Link>
<CustomBuildStep>
<Command>mdmerge -metadata_dir "$(WindowsSDK_MetadataPath)" -o "$(SolutionDir)$(Platform)\$(Configuration)\$(MSBuildProjectName)" -i "$(MSBuildProjectDirectory)" -v -partial</Command>
<Outputs>$(SolutionDir)$(Platform)\$(Configuration)\$(MSBuildProjectName)\$(ProjectName).winmd</Outputs>
</CustomBuildStep>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="OcvTransform.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="OcvTransform.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="OcvTransform.def" />
</ItemGroup>
<ItemGroup>
<Midl Include="OcvImageManipulations.idl">
<MetadataFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</MetadataFileName>
<MetadataFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</MetadataFileName>
<MetadataFileName Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
</MetadataFileName>
<MetadataFileName Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
</MetadataFileName>
<MetadataFileName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</MetadataFileName>
<MetadataFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</MetadataFileName>
<AdditionalMetadataDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(WindowsSDK_MetadataPath)</AdditionalMetadataDirectories>
<AdditionalMetadataDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(WindowsSDK_MetadataPath)</AdditionalMetadataDirectories>
<AdditionalMetadataDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">$(WindowsSDK_MetadataPath)</AdditionalMetadataDirectories>
<AdditionalMetadataDirectories Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">$(WindowsSDK_MetadataPath)</AdditionalMetadataDirectories>
<AdditionalMetadataDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(WindowsSDK_MetadataPath)</AdditionalMetadataDirectories>
<AdditionalMetadataDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(WindowsSDK_MetadataPath)</AdditionalMetadataDirectories>
<EnableWindowsRuntime Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</EnableWindowsRuntime>
<EnableWindowsRuntime Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</EnableWindowsRuntime>
<EnableWindowsRuntime Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</EnableWindowsRuntime>
<EnableWindowsRuntime Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</EnableWindowsRuntime>
<EnableWindowsRuntime Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</EnableWindowsRuntime>
<EnableWindowsRuntime Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</EnableWindowsRuntime>
<HeaderFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(Filename).h</HeaderFileName>
<HeaderFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(Filename).h</HeaderFileName>
<HeaderFileName Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">%(Filename).h</HeaderFileName>
<HeaderFileName Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">%(Filename).h</HeaderFileName>
<HeaderFileName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(Filename).h</HeaderFileName>
<HeaderFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(Filename).h</HeaderFileName>
</Midl>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ItemGroup>
<_MdMergeOutput Condition="'$(Platform)' == 'Win32'" Include="$(ProjectDir)$(Configuration)\$(MSBuildProjectName)\$(ProjectName).winmd" />
<_MdMergeOutput Condition="'$(Platform)' != 'Win32'" Include="$(SolutionDir)$(Platform)\$(Configuration)\$(MSBuildProjectName)\$(ProjectName).winmd" />
</ItemGroup>
<Target Name="CopyWinmdArtifactsOutputGroup" Returns="@(CopyWinmdArtifactsOutputGroupOutputs)">
<ItemGroup>
<CopyWinmdArtifactsOutputGroupOutputs Include="@(_MdMergeOutput)">
<TargetPath>$(ProjectName).winmd</TargetPath>
<Implementation>$(TargetName)$(TargetExt)</Implementation>
</CopyWinmdArtifactsOutputGroupOutputs>
</ItemGroup>
</Target>
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,58 @@
//////////////////////////////////////////////////////////////////////////
//
// dllmain.cpp
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////
#include <initguid.h>
#include "OcvTransform.h"
using namespace Microsoft::WRL;
namespace Microsoft { namespace Samples {
ActivatableClass(OcvImageManipulations);
}}
BOOL WINAPI DllMain( _In_ HINSTANCE hInstance, _In_ DWORD dwReason, _In_opt_ LPVOID lpReserved )
{
if( DLL_PROCESS_ATTACH == dwReason )
{
//
// Don't need per-thread callbacks
//
DisableThreadLibraryCalls( hInstance );
Module<InProc>::GetModule().Create();
}
else if( DLL_PROCESS_DETACH == dwReason )
{
Module<InProc>::GetModule().Terminate();
}
return TRUE;
}
HRESULT WINAPI DllGetActivationFactory( _In_ HSTRING activatibleClassId, _Outptr_ IActivationFactory** factory )
{
auto &module = Microsoft::WRL::Module< Microsoft::WRL::InProc >::GetModule();
return module.GetActivationFactory( activatibleClassId, factory );
}
HRESULT WINAPI DllCanUnloadNow()
{
auto &module = Microsoft::WRL::Module<Microsoft::WRL::InProc>::GetModule();
return (module.Terminate()) ? S_OK : S_FALSE;
}
STDAPI DllGetClassObject( _In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ LPVOID FAR* ppv )
{
auto &module = Microsoft::WRL::Module<Microsoft::WRL::InProc>::GetModule();
return module.GetClassObject( rclsid, riid, ppv );
}

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros">
<OpenCV_Bin>$(OPENCV_WINRT_INSTALL_DIR)\WS\8.1\$(PlatformTarget)\$(PlatformTarget)\vc12\bin\</OpenCV_Bin>
<OpenCV_Lib>$(OPENCV_WINRT_INSTALL_DIR)\WS\8.1\$(PlatformTarget)\$(PlatformTarget)\vc12\lib\</OpenCV_Lib>
<OpenCV_Include>$(OPENCV_WINRT_INSTALL_DIR)\WS\8.1\$(PlatformTarget)\include\</OpenCV_Include>
<!--debug suffix for OpenCV dlls and libs -->
<DebugSuffix Condition="'$(Configuration)'=='Debug'">d</DebugSuffix>
<DebugSuffix Condition="'$(Configuration)'!='Debug'"></DebugSuffix>
</PropertyGroup>
<ItemGroup>
<!--Add required OpenCV dlls here-->
<None Include="$(OpenCV_Bin)opencv_core300$(DebugSuffix).dll">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="$(OpenCV_Bin)opencv_imgproc300$(DebugSuffix).dll">
<DeploymentContent>true</DeploymentContent>
</None>
</ItemGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(OpenCV_Include);$(ProjectDir)\..\Common;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<!--Add required OpenCV libs here-->
<AdditionalDependencies>opencv_core300$(DebugSuffix).lib;opencv_imgproc300$(DebugSuffix).lib;runtimeobject.lib;mf.lib;mfuuid.lib;mfplat.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OpenCV_Lib);%(AdditionalLibraryDirectories);</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
</Project>

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest">
<Identity Name="Microsoft.SDKSamples.MediaCapture.CPP" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" Version="1.1.0.6" />
<Properties>
<DisplayName>MediaCapture CPP sample</DisplayName>
<PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
<Logo>Assets\windows-sdk.png</Logo>
</Properties>
<Prerequisites>
<OSMinVersion>6.3</OSMinVersion>
<OSMaxVersionTested>6.3</OSMaxVersionTested>
</Prerequisites>
<Resources>
<Resource Language="x-generate" />
</Resources>
<Applications>
<Application Id="MediaCapture.App" Executable="$targetnametoken$.exe" EntryPoint="MediaCapture.App">
<m2:VisualElements DisplayName="OCV Image Manipulations" Description="OpenCV Image Manipulations sample" BackgroundColor="#00b2f0" ForegroundText="light" Square150x150Logo="Assets\opencv-logo-150.png" Square30x30Logo="Assets\opencv-logo-30.png">
<m2:DefaultTile ShortName="Ocv ImageManipulations">
<m2:ShowNameOnTiles>
<m2:ShowOn Tile="square150x150Logo" />
</m2:ShowNameOnTiles>
</m2:DefaultTile>
<m2:SplashScreen BackgroundColor="#00b2f0" Image="Assets\splash-sdk.png" />
</m2:VisualElements>
</Application>
</Applications>
<Capabilities>
<DeviceCapability Name="webcam" />
<DeviceCapability Name="microphone" />
</Capabilities>
<Extensions>
<Extension Category="windows.activatableClass.inProcessServer">
<InProcessServer>
<Path>OcvTransform.dll</Path>
<ActivatableClass ActivatableClassId="OcvTransform.OcvImageManipulations" ThreadingModel="both" />
</InProcessServer>
</Extension>
</Extensions>
</Package>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,452 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
#include "pch.h"
#include "LayoutAwarePage.h"
#include "SuspensionManager.h"
using namespace SDKSample::Common;
using namespace Platform;
using namespace Platform::Collections;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::System;
using namespace Windows::UI::Core;
using namespace Windows::UI::ViewManagement;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Interop;
using namespace Windows::UI::Xaml::Navigation;
/// <summary>
/// Initializes a new instance of the <see cref="LayoutAwarePage"/> class.
/// </summary>
LayoutAwarePage::LayoutAwarePage()
{
if (Windows::ApplicationModel::DesignMode::DesignModeEnabled)
{
return;
}
// Create an empty default view model
DefaultViewModel = ref new Map<String^, Object^>(std::less<String^>());
// When this page is part of the visual tree make two changes:
// 1) Map application view state to visual state for the page
// 2) Handle keyboard and mouse navigation requests
Loaded += ref new RoutedEventHandler(this, &LayoutAwarePage::OnLoaded);
// Undo the same changes when the page is no longer visible
Unloaded += ref new RoutedEventHandler(this, &LayoutAwarePage::OnUnloaded);
}
static DependencyProperty^ _defaultViewModelProperty =
DependencyProperty::Register("DefaultViewModel",
TypeName(IObservableMap<String^, Object^>::typeid), TypeName(LayoutAwarePage::typeid), nullptr);
/// <summary>
/// Identifies the <see cref="DefaultViewModel"/> dependency property.
/// </summary>
DependencyProperty^ LayoutAwarePage::DefaultViewModelProperty::get()
{
return _defaultViewModelProperty;
}
/// <summary>
/// Gets an implementation of <see cref="IObservableMap&lt;String, Object&gt;"/> designed to be
/// used as a trivial view model.
/// </summary>
IObservableMap<String^, Object^>^ LayoutAwarePage::DefaultViewModel::get()
{
return safe_cast<IObservableMap<String^, Object^>^>(GetValue(DefaultViewModelProperty));
}
/// <summary>
/// Sets an implementation of <see cref="IObservableMap&lt;String, Object&gt;"/> designed to be
/// used as a trivial view model.
/// </summary>
void LayoutAwarePage::DefaultViewModel::set(IObservableMap<String^, Object^>^ value)
{
SetValue(DefaultViewModelProperty, value);
}
/// <summary>
/// Invoked when the page is part of the visual tree
/// </summary>
/// <param name="sender">Instance that triggered the event.</param>
/// <param name="e">Event data describing the conditions that led to the event.</param>
void LayoutAwarePage::OnLoaded(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
this->StartLayoutUpdates(sender, e);
// Keyboard and mouse navigation only apply when occupying the entire window
if (this->ActualHeight == Window::Current->Bounds.Height &&
this->ActualWidth == Window::Current->Bounds.Width)
{
// Listen to the window directly so focus isn't required
_acceleratorKeyEventToken = Window::Current->CoreWindow->Dispatcher->AcceleratorKeyActivated +=
ref new TypedEventHandler<CoreDispatcher^, AcceleratorKeyEventArgs^>(this,
&LayoutAwarePage::CoreDispatcher_AcceleratorKeyActivated);
_pointerPressedEventToken = Window::Current->CoreWindow->PointerPressed +=
ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this,
&LayoutAwarePage::CoreWindow_PointerPressed);
_navigationShortcutsRegistered = true;
}
}
/// <summary>
/// Invoked when the page is removed from visual tree
/// </summary>
/// <param name="sender">Instance that triggered the event.</param>
/// <param name="e">Event data describing the conditions that led to the event.</param>
void LayoutAwarePage::OnUnloaded(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
if (_navigationShortcutsRegistered)
{
Window::Current->CoreWindow->Dispatcher->AcceleratorKeyActivated -= _acceleratorKeyEventToken;
Window::Current->CoreWindow->PointerPressed -= _pointerPressedEventToken;
_navigationShortcutsRegistered = false;
}
StopLayoutUpdates(sender, e);
}
#pragma region Navigation support
/// <summary>
/// Invoked as an event handler to navigate backward in the page's associated <see cref="Frame"/>
/// until it reaches the top of the navigation stack.
/// </summary>
/// <param name="sender">Instance that triggered the event.</param>
/// <param name="e">Event data describing the conditions that led to the event.</param>
void LayoutAwarePage::GoHome(Object^ sender, RoutedEventArgs^ e)
{
(void) sender; // Unused parameter
(void) e; // Unused parameter
// Use the navigation frame to return to the topmost page
if (Frame != nullptr)
{
while (Frame->CanGoBack)
{
Frame->GoBack();
}
}
}
/// <summary>
/// Invoked as an event handler to navigate backward in the navigation stack
/// associated with this page's <see cref="Frame"/>.
/// </summary>
/// <param name="sender">Instance that triggered the event.</param>
/// <param name="e">Event data describing the conditions that led to the event.</param>
void LayoutAwarePage::GoBack(Object^ sender, RoutedEventArgs^ e)
{
(void) sender; // Unused parameter
(void) e; // Unused parameter
// Use the navigation frame to return to the previous page
if (Frame != nullptr && Frame->CanGoBack)
{
Frame->GoBack();
}
}
/// <summary>
/// Invoked as an event handler to navigate forward in the navigation stack
/// associated with this page's <see cref="Frame"/>.
/// </summary>
/// <param name="sender">Instance that triggered the event.</param>
/// <param name="e">Event data describing the conditions that led to the event.</param>
void LayoutAwarePage::GoForward(Object^ sender, RoutedEventArgs^ e)
{
(void) sender; // Unused parameter
(void) e; // Unused parameter
// Use the navigation frame to advance to the next page
if (Frame != nullptr && Frame->CanGoForward)
{
Frame->GoForward();
}
}
/// <summary>
/// Invoked on every keystroke, including system keys such as Alt key combinations, when
/// this page is active and occupies the entire window. Used to detect keyboard navigation
/// between pages even when the page itself doesn't have focus.
/// </summary>
/// <param name="sender">Instance that triggered the event.</param>
/// <param name="args">Event data describing the conditions that led to the event.</param>
void LayoutAwarePage::CoreDispatcher_AcceleratorKeyActivated(CoreDispatcher^ sender, AcceleratorKeyEventArgs^ args)
{
auto virtualKey = args->VirtualKey;
// Only investigate further when Left, Right, or the dedicated Previous or Next keys
// are pressed
if ((args->EventType == CoreAcceleratorKeyEventType::SystemKeyDown ||
args->EventType == CoreAcceleratorKeyEventType::KeyDown) &&
(virtualKey == VirtualKey::Left || virtualKey == VirtualKey::Right ||
(int)virtualKey == 166 || (int)virtualKey == 167))
{
auto coreWindow = Window::Current->CoreWindow;
auto downState = Windows::UI::Core::CoreVirtualKeyStates::Down;
bool menuKey = (coreWindow->GetKeyState(VirtualKey::Menu) & downState) == downState;
bool controlKey = (coreWindow->GetKeyState(VirtualKey::Control) & downState) == downState;
bool shiftKey = (coreWindow->GetKeyState(VirtualKey::Shift) & downState) == downState;
bool noModifiers = !menuKey && !controlKey && !shiftKey;
bool onlyAlt = menuKey && !controlKey && !shiftKey;
if (((int)virtualKey == 166 && noModifiers) ||
(virtualKey == VirtualKey::Left && onlyAlt))
{
// When the previous key or Alt+Left are pressed navigate back
args->Handled = true;
GoBack(this, ref new RoutedEventArgs());
}
else if (((int)virtualKey == 167 && noModifiers) ||
(virtualKey == VirtualKey::Right && onlyAlt))
{
// When the next key or Alt+Right are pressed navigate forward
args->Handled = true;
GoForward(this, ref new RoutedEventArgs());
}
}
}
/// <summary>
/// Invoked on every mouse click, touch screen tap, or equivalent interaction when this
/// page is active and occupies the entire window. Used to detect browser-style next and
/// previous mouse button clicks to navigate between pages.
/// </summary>
/// <param name="sender">Instance that triggered the event.</param>
/// <param name="args">Event data describing the conditions that led to the event.</param>
void LayoutAwarePage::CoreWindow_PointerPressed(CoreWindow^ sender, PointerEventArgs^ args)
{
auto properties = args->CurrentPoint->Properties;
// Ignore button chords with the left, right, and middle buttons
if (properties->IsLeftButtonPressed || properties->IsRightButtonPressed ||
properties->IsMiddleButtonPressed) return;
// If back or forward are pressed (but not both) navigate appropriately
bool backPressed = properties->IsXButton1Pressed;
bool forwardPressed = properties->IsXButton2Pressed;
if (backPressed ^ forwardPressed)
{
args->Handled = true;
if (backPressed) GoBack(this, ref new RoutedEventArgs());
if (forwardPressed) GoForward(this, ref new RoutedEventArgs());
}
}
#pragma endregion
#pragma region Visual state switching
/// <summary>
/// Invoked as an event handler, typically on the <see cref="Loaded"/> event of a
/// <see cref="Control"/> within the page, to indicate that the sender should start receiving
/// visual state management changes that correspond to application view state changes.
/// </summary>
/// <param name="sender">Instance of <see cref="Control"/> that supports visual state management
/// corresponding to view states.</param>
/// <param name="e">Event data that describes how the request was made.</param>
/// <remarks>The current view state will immediately be used to set the corresponding visual state
/// when layout updates are requested. A corresponding <see cref="Unloaded"/> event handler
/// connected to <see cref="StopLayoutUpdates"/> is strongly encouraged. Instances of
/// <see cref="LayoutAwarePage"/> automatically invoke these handlers in their Loaded and Unloaded
/// events.</remarks>
/// <seealso cref="DetermineVisualState"/>
/// <seealso cref="InvalidateVisualState"/>
void LayoutAwarePage::StartLayoutUpdates(Object^ sender, RoutedEventArgs^ e)
{
(void) e; // Unused parameter
auto control = safe_cast<Control^>(sender);
if (_layoutAwareControls == nullptr)
{
// Start listening to view state changes when there are controls interested in updates
_layoutAwareControls = ref new Vector<Control^>();
_windowSizeEventToken = Window::Current->SizeChanged += ref new WindowSizeChangedEventHandler(this, &LayoutAwarePage::WindowSizeChanged);
// Page receives notifications for children. Protect the page until we stopped layout updates for all controls.
_this = this;
}
_layoutAwareControls->Append(control);
// Set the initial visual state of the control
VisualStateManager::GoToState(control, DetermineVisualState(ApplicationView::Value), false);
}
void LayoutAwarePage::WindowSizeChanged(Object^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ e)
{
(void) sender; // Unused parameter
(void) e; // Unused parameter
InvalidateVisualState();
}
/// <summary>
/// Invoked as an event handler, typically on the <see cref="Unloaded"/> event of a
/// <see cref="Control"/>, to indicate that the sender should start receiving visual state
/// management changes that correspond to application view state changes.
/// </summary>
/// <param name="sender">Instance of <see cref="Control"/> that supports visual state management
/// corresponding to view states.</param>
/// <param name="e">Event data that describes how the request was made.</param>
/// <remarks>The current view state will immediately be used to set the corresponding visual state
/// when layout updates are requested.</remarks>
/// <seealso cref="StartLayoutUpdates"/>
void LayoutAwarePage::StopLayoutUpdates(Object^ sender, RoutedEventArgs^ e)
{
(void) e; // Unused parameter
auto control = safe_cast<Control^>(sender);
unsigned int index;
if (_layoutAwareControls != nullptr && _layoutAwareControls->IndexOf(control, &index))
{
_layoutAwareControls->RemoveAt(index);
if (_layoutAwareControls->Size == 0)
{
// Stop listening to view state changes when no controls are interested in updates
Window::Current->SizeChanged -= _windowSizeEventToken;
_layoutAwareControls = nullptr;
// Last control has received the Unload notification.
_this = nullptr;
}
}
}
/// <summary>
/// Translates <see cref="ApplicationViewState"/> values into strings for visual state management
/// within the page. The default implementation uses the names of enum values. Subclasses may
/// override this method to control the mapping scheme used.
/// </summary>
/// <param name="viewState">View state for which a visual state is desired.</param>
/// <returns>Visual state name used to drive the <see cref="VisualStateManager"/></returns>
/// <seealso cref="InvalidateVisualState"/>
String^ LayoutAwarePage::DetermineVisualState(ApplicationViewState viewState)
{
switch (viewState)
{
case ApplicationViewState::Filled:
return "Filled";
case ApplicationViewState::Snapped:
return "Snapped";
case ApplicationViewState::FullScreenPortrait:
return "FullScreenPortrait";
case ApplicationViewState::FullScreenLandscape:
default:
return "FullScreenLandscape";
}
}
/// <summary>
/// Updates all controls that are listening for visual state changes with the correct visual
/// state.
/// </summary>
/// <remarks>
/// Typically used in conjunction with overriding <see cref="DetermineVisualState"/> to
/// signal that a different value may be returned even though the view state has not changed.
/// </remarks>
void LayoutAwarePage::InvalidateVisualState()
{
if (_layoutAwareControls != nullptr)
{
String^ visualState = DetermineVisualState(ApplicationView::Value);
auto controlIterator = _layoutAwareControls->First();
while (controlIterator->HasCurrent)
{
auto control = controlIterator->Current;
VisualStateManager::GoToState(control, visualState, false);
controlIterator->MoveNext();
}
}
}
#pragma endregion
#pragma region Process lifetime management
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached. The Parameter
/// property provides the group to be displayed.</param>
void LayoutAwarePage::OnNavigatedTo(NavigationEventArgs^ e)
{
// Returning to a cached page through navigation shouldn't trigger state loading
if (_pageKey != nullptr) return;
auto frameState = SuspensionManager::SessionStateForFrame(Frame);
_pageKey = "Page-" + Frame->BackStackDepth;
if (e->NavigationMode == NavigationMode::New)
{
// Clear existing state for forward navigation when adding a new page to the
// navigation stack
auto nextPageKey = _pageKey;
int nextPageIndex = Frame->BackStackDepth;
while (frameState->HasKey(nextPageKey))
{
frameState->Remove(nextPageKey);
nextPageIndex++;
nextPageKey = "Page-" + nextPageIndex;
}
// Pass the navigation parameter to the new page
LoadState(e->Parameter, nullptr);
}
else
{
// Pass the navigation parameter and preserved page state to the page, using
// the same strategy for loading suspended state and recreating pages discarded
// from cache
LoadState(e->Parameter, safe_cast<IMap<String^, Object^>^>(frameState->Lookup(_pageKey)));
}
}
/// <summary>
/// Invoked when this page will no longer be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached. The Parameter
/// property provides the group to be displayed.</param>
void LayoutAwarePage::OnNavigatedFrom(NavigationEventArgs^ e)
{
auto frameState = SuspensionManager::SessionStateForFrame(Frame);
auto pageState = ref new Map<String^, Object^>();
SaveState(pageState);
frameState->Insert(_pageKey, pageState);
}
/// <summary>
/// Populates the page with content passed during navigation. Any saved state is also
/// provided when recreating a page from a prior session.
/// </summary>
/// <param name="navigationParameter">The parameter value passed to
/// <see cref="Frame.Navigate(Type, Object)"/> when this page was initially requested.
/// </param>
/// <param name="pageState">A map of state preserved by this page during an earlier
/// session. This will be null the first time a page is visited.</param>
void LayoutAwarePage::LoadState(Object^ navigationParameter, IMap<String^, Object^>^ pageState)
{
}
/// <summary>
/// Preserves state associated with this page in case the application is suspended or the
/// page is discarded from the navigation cache. Values must conform to the serialization
/// requirements of <see cref="SuspensionManager.SessionState"/>.
/// </summary>
/// <param name="pageState">An empty map to be populated with serializable state.</param>
void LayoutAwarePage::SaveState(IMap<String^, Object^>^ pageState)
{
}
#pragma endregion

View File

@ -0,0 +1,88 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
#pragma once
#include <collection.h>
namespace SDKSample
{
namespace Common
{
/// <summary>
/// Typical implementation of Page that provides several important conveniences:
/// <list type="bullet">
/// <item>
/// <description>Application view state to visual state mapping</description>
/// </item>
/// <item>
/// <description>GoBack, GoForward, and GoHome event handlers</description>
/// </item>
/// <item>
/// <description>Mouse and keyboard shortcuts for navigation</description>
/// </item>
/// <item>
/// <description>State management for navigation and process lifetime management</description>
/// </item>
/// <item>
/// <description>A default view model</description>
/// </item>
/// </list>
/// </summary>
[Windows::Foundation::Metadata::WebHostHidden]
public ref class LayoutAwarePage : Windows::UI::Xaml::Controls::Page
{
internal:
LayoutAwarePage();
public:
void StartLayoutUpdates(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void StopLayoutUpdates(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void InvalidateVisualState();
static property Windows::UI::Xaml::DependencyProperty^ DefaultViewModelProperty
{
Windows::UI::Xaml::DependencyProperty^ get();
};
property Windows::Foundation::Collections::IObservableMap<Platform::String^, Platform::Object^>^ DefaultViewModel
{
Windows::Foundation::Collections::IObservableMap<Platform::String^, Platform::Object^>^ get();
void set(Windows::Foundation::Collections::IObservableMap<Platform::String^, Platform::Object^>^ value);
}
protected:
virtual void GoHome(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
virtual void GoBack(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
virtual void GoForward(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
virtual Platform::String^ DetermineVisualState(Windows::UI::ViewManagement::ApplicationViewState viewState);
virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
virtual void OnNavigatedFrom(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
virtual void LoadState(Platform::Object^ navigationParameter,
Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ pageState);
virtual void SaveState(Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ pageState);
private:
Platform::String^ _pageKey;
bool _navigationShortcutsRegistered;
Platform::Collections::Map<Platform::String^, Platform::Object^>^ _defaultViewModel;
Windows::Foundation::EventRegistrationToken _windowSizeEventToken,
_acceleratorKeyEventToken, _pointerPressedEventToken;
Platform::Collections::Vector<Windows::UI::Xaml::Controls::Control^>^ _layoutAwareControls;
void WindowSizeChanged(Platform::Object^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ e);
void OnLoaded(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void OnUnloaded(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void CoreDispatcher_AcceleratorKeyActivated(Windows::UI::Core::CoreDispatcher^ sender,
Windows::UI::Core::AcceleratorKeyEventArgs^ args);
void CoreWindow_PointerPressed(Windows::UI::Core::CoreWindow^ sender,
Windows::UI::Core::PointerEventArgs^ args);
LayoutAwarePage^ _this; // Strong reference to self, cleaned up in OnUnload
};
}
}

View File

@ -0,0 +1,978 @@
<!--
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
-->
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- Non-brush values that vary across themes -->
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Default">
<x:String x:Key="BackButtonGlyph">&#xE071;</x:String>
<x:String x:Key="BackButtonSnappedGlyph">&#xE0BA;</x:String>
</ResourceDictionary>
<ResourceDictionary x:Key="HighContrast">
<x:String x:Key="BackButtonGlyph">&#xE0A6;</x:String>
<x:String x:Key="BackButtonSnappedGlyph">&#xE0C4;</x:String>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
<!-- RichTextBlock styles -->
<Style x:Key="BasicRichTextStyle" TargetType="RichTextBlock">
<Setter Property="Foreground" Value="{StaticResource ApplicationForegroundThemeBrush}"/>
<Setter Property="FontSize" Value="{StaticResource ControlContentThemeFontSize}"/>
<Setter Property="FontFamily" Value="{StaticResource ContentControlThemeFontFamily}"/>
<Setter Property="TextTrimming" Value="WordEllipsis"/>
<Setter Property="TextWrapping" Value="Wrap"/>
<Setter Property="Typography.StylisticSet20" Value="True"/>
<Setter Property="Typography.DiscretionaryLigatures" Value="True"/>
</Style>
<Style x:Key="BaselineRichTextStyle" TargetType="RichTextBlock" BasedOn="{StaticResource BasicRichTextStyle}">
<Setter Property="LineHeight" Value="20"/>
<Setter Property="LineStackingStrategy" Value="BlockLineHeight"/>
<!-- Properly align text along its baseline -->
<Setter Property="RenderTransform">
<Setter.Value>
<TranslateTransform X="-1" Y="4"/>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ItemRichTextStyle" TargetType="RichTextBlock" BasedOn="{StaticResource BaselineRichTextStyle}"/>
<Style x:Key="BodyRichTextStyle" TargetType="RichTextBlock" BasedOn="{StaticResource BaselineRichTextStyle}">
<Setter Property="FontWeight" Value="SemiLight"/>
</Style>
<!-- TextBlock styles -->
<Style x:Key="BasicTextStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="{StaticResource ApplicationForegroundThemeBrush}"/>
<Setter Property="FontSize" Value="{StaticResource ControlContentThemeFontSize}"/>
<Setter Property="FontFamily" Value="{StaticResource ContentControlThemeFontFamily}"/>
<Setter Property="TextTrimming" Value="WordEllipsis"/>
<Setter Property="TextWrapping" Value="Wrap"/>
<Setter Property="Typography.StylisticSet20" Value="True"/>
<Setter Property="Typography.DiscretionaryLigatures" Value="True"/>
</Style>
<Style x:Key="BaselineTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BasicTextStyle}">
<Setter Property="LineHeight" Value="20"/>
<Setter Property="LineStackingStrategy" Value="BlockLineHeight"/>
<!-- Properly align text along its baseline -->
<Setter Property="RenderTransform">
<Setter.Value>
<TranslateTransform X="-1" Y="4"/>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="HeaderTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BaselineTextStyle}">
<Setter Property="FontSize" Value="56"/>
<Setter Property="FontWeight" Value="Light"/>
<Setter Property="LineHeight" Value="40"/>
<Setter Property="RenderTransform">
<Setter.Value>
<TranslateTransform X="-2" Y="8"/>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="SubheaderTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BaselineTextStyle}">
<Setter Property="FontSize" Value="26.667"/>
<Setter Property="FontWeight" Value="Light"/>
<Setter Property="LineHeight" Value="30"/>
<Setter Property="RenderTransform">
<Setter.Value>
<TranslateTransform X="-1" Y="6"/>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="TitleTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BaselineTextStyle}">
<Setter Property="FontWeight" Value="SemiBold"/>
</Style>
<Style x:Key="ItemTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BaselineTextStyle}"/>
<Style x:Key="BodyTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BaselineTextStyle}">
<Setter Property="FontWeight" Value="SemiLight"/>
</Style>
<Style x:Key="CaptionTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BaselineTextStyle}">
<Setter Property="FontSize" Value="12"/>
<Setter Property="Foreground" Value="{StaticResource ApplicationSecondaryForegroundThemeBrush}"/>
</Style>
<!-- Button styles -->
<!--
TextButtonStyle is used to style a Button using subheader-styled text with no other adornment. This
style is used in the GroupedItemsPage as a group header and in the FileOpenPickerPage for triggering
commands.
-->
<Style x:Key="TextButtonStyle" TargetType="Button">
<Setter Property="MinWidth" Value="0"/>
<Setter Property="MinHeight" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="Transparent">
<TextBlock
x:Name="Text"
Text="{TemplateBinding Content}"
Margin="3,-7,3,10"
TextWrapping="NoWrap"
Style="{StaticResource SubheaderTextStyle}"/>
<Rectangle
x:Name="FocusVisualWhite"
IsHitTestVisible="False"
Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}"
StrokeEndLineCap="Square"
StrokeDashArray="1,1"
Opacity="0"
StrokeDashOffset="1.5"/>
<Rectangle
x:Name="FocusVisualBlack"
IsHitTestVisible="False"
Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}"
StrokeEndLineCap="Square"
StrokeDashArray="1,1"
Opacity="0"
StrokeDashOffset="0.5"/>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPointerOverForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPressedForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ButtonDisabledForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetName="FocusVisualWhite" Storyboard.TargetProperty="Opacity"/>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetName="FocusVisualBlack" Storyboard.TargetProperty="Opacity"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--
TextRadioButtonStyle is used to style a RadioButton using subheader-styled text with no other adornment.
This style is used in the SearchResultsPage to allow selection among filters.
-->
<Style x:Key="TextRadioButtonStyle" TargetType="RadioButton">
<Setter Property="MinWidth" Value="0"/>
<Setter Property="MinHeight" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton">
<Grid Background="Transparent">
<TextBlock
x:Name="Text"
Text="{TemplateBinding Content}"
Margin="3,-7,3,10"
TextWrapping="NoWrap"
Style="{StaticResource SubheaderTextStyle}"/>
<Rectangle
x:Name="FocusVisualWhite"
IsHitTestVisible="False"
Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}"
StrokeEndLineCap="Square"
StrokeDashArray="1,1"
Opacity="0"
StrokeDashOffset="1.5"/>
<Rectangle
x:Name="FocusVisualBlack"
IsHitTestVisible="False"
Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}"
StrokeEndLineCap="Square"
StrokeDashArray="1,1"
Opacity="0"
StrokeDashOffset="0.5"/>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPointerOverForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPressedForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ButtonDisabledForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetName="FocusVisualWhite" Storyboard.TargetProperty="Opacity"/>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetName="FocusVisualBlack" Storyboard.TargetProperty="Opacity"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused"/>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked"/>
<VisualState x:Name="Unchecked">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationSecondaryForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Indeterminate"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--
AppBarButtonStyle is used to style a Button for use in an App Bar. Content will be centered and should fit within
the 40-pixel radius glyph provided. 16-point Segoe UI Symbol is used for content text to simplify the use of glyphs
from that font. AutomationProperties.Name is used for the text below the glyph.
-->
<Style x:Key="AppBarButtonStyle" TargetType="Button">
<Setter Property="Foreground" Value="{StaticResource AppBarItemForegroundThemeBrush}"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="FontFamily" Value="Segoe UI Symbol"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="FontSize" Value="20"/>
<Setter Property="AutomationProperties.ItemType" Value="App Bar Button"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Width="100" Background="Transparent">
<StackPanel VerticalAlignment="Top" Margin="0,14,0,13">
<Grid Width="40" Height="40" Margin="0,0,0,5" HorizontalAlignment="Center">
<TextBlock x:Name="BackgroundGlyph" Text="&#xE0A8;" FontFamily="Segoe UI Symbol" FontSize="53.333" Margin="-4,-19,0,0" Foreground="{StaticResource AppBarItemBackgroundThemeBrush}"/>
<TextBlock x:Name="OutlineGlyph" Text="&#xE0A7;" FontFamily="Segoe UI Symbol" FontSize="53.333" Margin="-4,-19,0,0"/>
<ContentPresenter x:Name="Content" HorizontalAlignment="Center" Margin="-1,-1,0,0" VerticalAlignment="Center"/>
</Grid>
<TextBlock
x:Name="TextLabel"
Text="{TemplateBinding AutomationProperties.Name}"
Margin="0,0,2,0"
FontSize="12"
TextAlignment="Center"
Width="88"
MaxHeight="32"
TextTrimming="WordEllipsis"
Style="{StaticResource BasicTextStyle}"/>
</StackPanel>
<Rectangle
x:Name="FocusVisualWhite"
IsHitTestVisible="False"
Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}"
StrokeEndLineCap="Square"
StrokeDashArray="1,1"
Opacity="0"
StrokeDashOffset="1.5"/>
<Rectangle
x:Name="FocusVisualBlack"
IsHitTestVisible="False"
Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}"
StrokeEndLineCap="Square"
StrokeDashArray="1,1"
Opacity="0"
StrokeDashOffset="0.5"/>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemPointerOverBackgroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemPointerOverForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="OutlineGlyph"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="0"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemPressedForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="OutlineGlyph" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemDisabledForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemDisabledForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextLabel" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemDisabledForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="FocusVisualWhite"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0"/>
<DoubleAnimation
Storyboard.TargetName="FocusVisualBlack"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused" />
<VisualState x:Name="PointerFocused" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Standard App Bar buttons -->
<Style x:Key="SkipBackAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="SkipBackAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Skip Back"/>
<Setter Property="Content" Value="&#xE100;"/>
</Style>
<Style x:Key="SkipAheadAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="SkipAheadAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Skip Ahead"/>
<Setter Property="Content" Value="&#xE101;"/>
</Style>
<Style x:Key="PlayAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="PlayAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Play"/>
<Setter Property="Content" Value="&#xE102;"/>
</Style>
<Style x:Key="PauseAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="PauseAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Pause"/>
<Setter Property="Content" Value="&#xE103;"/>
</Style>
<Style x:Key="EditAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="EditAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Edit"/>
<Setter Property="Content" Value="&#xE104;"/>
</Style>
<Style x:Key="SaveAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="SaveAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Save"/>
<Setter Property="Content" Value="&#xE105;"/>
</Style>
<Style x:Key="DeleteAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="DeleteAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Delete"/>
<Setter Property="Content" Value="&#xE106;"/>
</Style>
<Style x:Key="DiscardAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="DiscardAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Discard"/>
<Setter Property="Content" Value="&#xE107;"/>
</Style>
<Style x:Key="RemoveAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="RemoveAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Remove"/>
<Setter Property="Content" Value="&#xE108;"/>
</Style>
<Style x:Key="AddAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="AddAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Add"/>
<Setter Property="Content" Value="&#xE109;"/>
</Style>
<Style x:Key="NoAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="NoAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="No"/>
<Setter Property="Content" Value="&#xE10A;"/>
</Style>
<Style x:Key="YesAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="YesAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Yes"/>
<Setter Property="Content" Value="&#xE10B;"/>
</Style>
<Style x:Key="MoreAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="MoreAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="More"/>
<Setter Property="Content" Value="&#xE10C;"/>
</Style>
<Style x:Key="RedoAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="RedoAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Redo"/>
<Setter Property="Content" Value="&#xE10D;"/>
</Style>
<Style x:Key="UndoAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="UndoAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Undo"/>
<Setter Property="Content" Value="&#xE10E;"/>
</Style>
<Style x:Key="HomeAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="HomeAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Home"/>
<Setter Property="Content" Value="&#xE10F;"/>
</Style>
<Style x:Key="OutAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="OutAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Out"/>
<Setter Property="Content" Value="&#xE110;"/>
</Style>
<Style x:Key="NextAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="NextAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Next"/>
<Setter Property="Content" Value="&#xE111;"/>
</Style>
<Style x:Key="PreviousAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="PreviousAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Previous"/>
<Setter Property="Content" Value="&#xE112;"/>
</Style>
<Style x:Key="FavoriteAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="FavoriteAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Favorite"/>
<Setter Property="Content" Value="&#xE113;"/>
</Style>
<Style x:Key="PhotoAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="PhotoAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Photo"/>
<Setter Property="Content" Value="&#xE114;"/>
</Style>
<Style x:Key="SettingsAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="SettingsAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Settings"/>
<Setter Property="Content" Value="&#xE115;"/>
</Style>
<Style x:Key="VideoAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="VideoAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Video"/>
<Setter Property="Content" Value="&#xE116;"/>
</Style>
<Style x:Key="RefreshAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="RefreshAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Refresh"/>
<Setter Property="Content" Value="&#xE117;"/>
</Style>
<Style x:Key="DownloadAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="DownloadAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Download"/>
<Setter Property="Content" Value="&#xE118;"/>
</Style>
<Style x:Key="MailAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="MailAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Mail"/>
<Setter Property="Content" Value="&#xE119;"/>
</Style>
<Style x:Key="SearchAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="SearchAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Search"/>
<Setter Property="Content" Value="&#xE11A;"/>
</Style>
<Style x:Key="HelpAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="HelpAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Help"/>
<Setter Property="Content" Value="&#xE11B;"/>
</Style>
<Style x:Key="UploadAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="UploadAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Upload"/>
<Setter Property="Content" Value="&#xE11C;"/>
</Style>
<Style x:Key="PinAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="PinAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Pin"/>
<Setter Property="Content" Value="&#xE141;"/>
</Style>
<Style x:Key="UnpinAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="UnpinAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Unpin"/>
<Setter Property="Content" Value="&#xE196;"/>
</Style>
<!-- Title area styles -->
<Style x:Key="PageHeaderTextStyle" TargetType="TextBlock" BasedOn="{StaticResource HeaderTextStyle}">
<Setter Property="TextWrapping" Value="NoWrap"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
<Setter Property="Margin" Value="0,0,40,40"/>
</Style>
<Style x:Key="PageSubheaderTextStyle" TargetType="TextBlock" BasedOn="{StaticResource SubheaderTextStyle}">
<Setter Property="TextWrapping" Value="NoWrap"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
<Setter Property="Margin" Value="0,0,0,40"/>
</Style>
<Style x:Key="SnappedPageHeaderTextStyle" TargetType="TextBlock" BasedOn="{StaticResource PageSubheaderTextStyle}">
<Setter Property="Margin" Value="0,0,18,40"/>
</Style>
<!--
BackButtonStyle is used to style a Button for use in the title area of a page. Margins appropriate for
the conventional page layout are included as part of the style.
-->
<Style x:Key="BackButtonStyle" TargetType="Button">
<Setter Property="MinWidth" Value="0"/>
<Setter Property="Width" Value="48"/>
<Setter Property="Height" Value="48"/>
<Setter Property="Margin" Value="36,0,36,36"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
<Setter Property="FontFamily" Value="Segoe UI Symbol"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="FontSize" Value="56"/>
<Setter Property="AutomationProperties.AutomationId" Value="BackButton"/>
<Setter Property="AutomationProperties.Name" Value="Back"/>
<Setter Property="AutomationProperties.ItemType" Value="Navigation Button"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="RootGrid">
<Grid Margin="-1,-16,0,0">
<TextBlock x:Name="BackgroundGlyph" Text="&#xE0A8;" Foreground="{StaticResource BackButtonBackgroundThemeBrush}"/>
<TextBlock x:Name="NormalGlyph" Text="{StaticResource BackButtonGlyph}" Foreground="{StaticResource BackButtonForegroundThemeBrush}"/>
<TextBlock x:Name="ArrowGlyph" Text="&#xE0A6;" Foreground="{StaticResource BackButtonPressedForegroundThemeBrush}" Opacity="0"/>
</Grid>
<Rectangle
x:Name="FocusVisualWhite"
IsHitTestVisible="False"
Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}"
StrokeEndLineCap="Square"
StrokeDashArray="1,1"
Opacity="0"
StrokeDashOffset="1.5"/>
<Rectangle
x:Name="FocusVisualBlack"
IsHitTestVisible="False"
Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}"
StrokeEndLineCap="Square"
StrokeDashArray="1,1"
Opacity="0"
StrokeDashOffset="0.5"/>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource BackButtonPointerOverBackgroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="NormalGlyph" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource BackButtonPointerOverForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource BackButtonForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation
Storyboard.TargetName="ArrowGlyph"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0"/>
<DoubleAnimation
Storyboard.TargetName="NormalGlyph"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="0"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="FocusVisualWhite"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0"/>
<DoubleAnimation
Storyboard.TargetName="FocusVisualBlack"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused" />
<VisualState x:Name="PointerFocused" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--
PortraitBackButtonStyle is used to style a Button for use in the title area of a portrait page. Margins appropriate
for the conventional page layout are included as part of the style.
-->
<Style x:Key="PortraitBackButtonStyle" TargetType="Button" BasedOn="{StaticResource BackButtonStyle}">
<Setter Property="Margin" Value="26,0,26,36"/>
</Style>
<!--
SnappedBackButtonStyle is used to style a Button for use in the title area of a snapped page. Margins appropriate
for the conventional page layout are included as part of the style.
The obvious duplication here is necessary as the glyphs used in snapped are not merely smaller versions of the same
glyph but are actually distinct.
-->
<Style x:Key="SnappedBackButtonStyle" TargetType="Button">
<Setter Property="MinWidth" Value="0"/>
<Setter Property="Margin" Value="20,0,0,0"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
<Setter Property="FontFamily" Value="Segoe UI Symbol"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="FontSize" Value="26.66667"/>
<Setter Property="AutomationProperties.AutomationId" Value="BackButton"/>
<Setter Property="AutomationProperties.Name" Value="Back"/>
<Setter Property="AutomationProperties.ItemType" Value="Navigation Button"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="RootGrid" Width="36" Height="36" Margin="-3,0,7,33">
<Grid Margin="-1,-1,0,0">
<TextBlock x:Name="BackgroundGlyph" Text="&#xE0D4;" Foreground="{StaticResource BackButtonBackgroundThemeBrush}"/>
<TextBlock x:Name="NormalGlyph" Text="{StaticResource BackButtonSnappedGlyph}" Foreground="{StaticResource BackButtonForegroundThemeBrush}"/>
<TextBlock x:Name="ArrowGlyph" Text="&#xE0C4;" Foreground="{StaticResource BackButtonPressedForegroundThemeBrush}" Opacity="0"/>
</Grid>
<Rectangle
x:Name="FocusVisualWhite"
IsHitTestVisible="False"
Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}"
StrokeEndLineCap="Square"
StrokeDashArray="1,1"
Opacity="0"
StrokeDashOffset="1.5"/>
<Rectangle
x:Name="FocusVisualBlack"
IsHitTestVisible="False"
Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}"
StrokeEndLineCap="Square"
StrokeDashArray="1,1"
Opacity="0"
StrokeDashOffset="0.5"/>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource BackButtonPointerOverBackgroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="NormalGlyph" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource BackButtonPointerOverForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource BackButtonForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation
Storyboard.TargetName="ArrowGlyph"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0"/>
<DoubleAnimation
Storyboard.TargetName="NormalGlyph"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="0"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="FocusVisualWhite"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0"/>
<DoubleAnimation
Storyboard.TargetName="FocusVisualBlack"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused" />
<VisualState x:Name="PointerFocused" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Item templates -->
<!-- Grid-appropriate 250 pixel square item template as seen in the GroupedItemsPage and ItemsPage -->
<DataTemplate x:Key="Standard250x250ItemTemplate">
<Grid HorizontalAlignment="Left" Width="250" Height="250">
<Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
<Image Source="{Binding Image}" Stretch="UniformToFill"/>
</Border>
<StackPanel VerticalAlignment="Bottom" Background="{StaticResource ListViewItemOverlayBackgroundThemeBrush}">
<TextBlock Text="{Binding Title}" Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextStyle}" Height="60" Margin="15,0,15,0"/>
<TextBlock Text="{Binding Subtitle}" Foreground="{StaticResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
</StackPanel>
</Grid>
</DataTemplate>
<!-- Grid-appropriate 500 by 130 pixel item template as seen in the GroupDetailPage -->
<DataTemplate x:Key="Standard500x130ItemTemplate">
<Grid Height="110" Width="480" Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Width="110" Height="110">
<Image Source="{Binding Image}" Stretch="UniformToFill"/>
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Top" Margin="10,0,0,0">
<TextBlock Text="{Binding Title}" Style="{StaticResource TitleTextStyle}" TextWrapping="NoWrap"/>
<TextBlock Text="{Binding Subtitle}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap"/>
<TextBlock Text="{Binding Description}" Style="{StaticResource BodyTextStyle}" MaxHeight="60"/>
</StackPanel>
</Grid>
</DataTemplate>
<!-- List-appropriate 130 pixel high item template as seen in the SplitPage -->
<DataTemplate x:Key="Standard130ItemTemplate">
<Grid Height="110" Margin="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Width="110" Height="110">
<Image Source="{Binding Image}" Stretch="UniformToFill"/>
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Top" Margin="10,0,0,0">
<TextBlock Text="{Binding Title}" Style="{StaticResource TitleTextStyle}" TextWrapping="NoWrap"/>
<TextBlock Text="{Binding Subtitle}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap"/>
<TextBlock Text="{Binding Description}" Style="{StaticResource BodyTextStyle}" MaxHeight="60"/>
</StackPanel>
</Grid>
</DataTemplate>
<!--
List-appropriate 80 pixel high item template as seen in the SplitPage when Filled, and
the following pages when snapped: GroupedItemsPage, GroupDetailPage, and ItemsPage
-->
<DataTemplate x:Key="Standard80ItemTemplate">
<Grid Margin="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Width="60" Height="60">
<Image Source="{Binding Image}" Stretch="UniformToFill"/>
</Border>
<StackPanel Grid.Column="1" Margin="10,0,0,0">
<TextBlock Text="{Binding Title}" Style="{StaticResource ItemTextStyle}" MaxHeight="40"/>
<TextBlock Text="{Binding Subtitle}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap"/>
</StackPanel>
</Grid>
</DataTemplate>
<!-- Grid-appropriate 300 by 70 pixel item template as seen in the SearchResultsPage -->
<DataTemplate x:Key="StandardSmallIcon300x70ItemTemplate">
<Grid Width="300">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Margin="10,10,0,20" Width="40" Height="40">
<Image Source="{Binding Image}" Stretch="UniformToFill"/>
</Border>
<StackPanel Grid.Column="1" Margin="10,0,10,10">
<TextBlock Text="{Binding Title}" Style="{StaticResource BodyTextStyle}" TextWrapping="NoWrap"/>
<TextBlock Text="{Binding Subtitle}" Style="{StaticResource BodyTextStyle}" Foreground="{StaticResource ApplicationSecondaryForegroundThemeBrush}" Height="40"/>
</StackPanel>
</Grid>
</DataTemplate>
<!-- List-appropriate 70 pixel high item template as seen in the SearchResultsPage when Snapped -->
<DataTemplate x:Key="StandardSmallIcon70ItemTemplate">
<Grid Margin="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Margin="0,0,0,10" Width="40" Height="40">
<Image Source="{Binding Image}" Stretch="UniformToFill"/>
</Border>
<StackPanel Grid.Column="1" Margin="10,-10,0,0">
<TextBlock Text="{Binding Title}" Style="{StaticResource BodyTextStyle}" TextWrapping="NoWrap"/>
<TextBlock Text="{Binding Subtitle}" Style="{StaticResource BodyTextStyle}" Foreground="{StaticResource ApplicationSecondaryForegroundThemeBrush}" Height="40"/>
</StackPanel>
</Grid>
</DataTemplate>
<!--
190x130 pixel item template for displaying file previews as seen in the FileOpenPickerPage
Includes an elaborate tooltip to display title and description text
-->
<DataTemplate x:Key="StandardFileWithTooltip190x130ItemTemplate">
<Grid>
<Grid Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
<Image
Source="{Binding Image}"
Width="190"
Height="130"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Stretch="Uniform"/>
</Grid>
<ToolTipService.Placement>Mouse</ToolTipService.Placement>
<ToolTipService.ToolTip>
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Margin="20">
<Image
Source="{Binding Image}"
Width="160"
Height="160"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Stretch="Uniform"/>
</Grid>
<StackPanel Width="200" Grid.Column="1" Margin="0,20,20,20">
<TextBlock Text="{Binding Title}" TextWrapping="NoWrap" Style="{StaticResource BodyTextStyle}"/>
<TextBlock Text="{Binding Description}" MaxHeight="140" Foreground="{StaticResource ApplicationSecondaryForegroundThemeBrush}" Style="{StaticResource BodyTextStyle}"/>
</StackPanel>
</Grid>
</ToolTipService.ToolTip>
</Grid>
</DataTemplate>
<!-- Default to 10-pixel spacing between grid items (after accounting for 4-pixel insets for focus) -->
<Style TargetType="GridViewItem">
<Setter Property="Margin" Value="0,0,2,2" />
</Style>
<!-- ScrollViewer styles -->
<Style x:Key="HorizontalScrollViewerStyle" TargetType="ScrollViewer">
<Setter Property="HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="VerticalScrollBarVisibility" Value="Disabled"/>
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Enabled" />
<Setter Property="ScrollViewer.VerticalScrollMode" Value="Disabled" />
<Setter Property="ScrollViewer.ZoomMode" Value="Disabled" />
</Style>
<Style x:Key="VerticalScrollViewerStyle" TargetType="ScrollViewer">
<Setter Property="HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled" />
<Setter Property="ScrollViewer.VerticalScrollMode" Value="Enabled" />
<Setter Property="ScrollViewer.ZoomMode" Value="Disabled" />
</Style>
<!-- Page layout roots typically use entrance animations and a theme-appropriate background color -->
<Style x:Key="LayoutRootStyle" TargetType="Panel">
<Setter Property="Background" Value="{StaticResource ApplicationPageBackgroundThemeBrush}"/>
<Setter Property="ChildrenTransitions">
<Setter.Value>
<TransitionCollection>
<EntranceThemeTransition/>
</TransitionCollection>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

View File

@ -0,0 +1,481 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
//
// SuspensionManager.cpp
// Implementation of the SuspensionManager class
//
#include "pch.h"
#include "SuspensionManager.h"
#include <collection.h>
#include <algorithm>
using namespace SDKSample::Common;
using namespace Concurrency;
using namespace Platform;
using namespace Platform::Collections;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Storage;
using namespace Windows::Storage::FileProperties;
using namespace Windows::Storage::Streams;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Interop;
namespace
{
Map<String^, Object^>^ _sessionState = ref new Map<String^, Object^>();
String^ sessionStateFilename = "_sessionState.dat";
// Forward declarations for object object read / write support
void WriteObject(Windows::Storage::Streams::DataWriter^ writer, Platform::Object^ object);
Platform::Object^ ReadObject(Windows::Storage::Streams::DataReader^ reader);
}
/// <summary>
/// Provides access to global session state for the current session. This state is serialized by
/// <see cref="SaveAsync"/> and restored by <see cref="RestoreAsync"/> which require values to be
/// one of the following: boxed values including integers, floating-point singles and doubles,
/// wide characters, boolean, Strings and Guids, or Map<String^, Object^> where map values are
/// subject to the same constraints. Session state should be as compact as possible.
/// </summary>
IMap<String^, Object^>^ SuspensionManager::SessionState::get(void)
{
return _sessionState;
}
/// <summary>
/// Wrap a WeakReference as a reference object for use in a collection.
/// </summary>
private ref class WeakFrame sealed
{
private:
WeakReference _frameReference;
internal:
WeakFrame(Frame^ frame) { _frameReference = frame; }
property Frame^ ResolvedFrame
{
Frame^ get(void) { return _frameReference.Resolve<Frame>(); }
};
};
namespace
{
std::vector<WeakFrame^> _registeredFrames;
DependencyProperty^ FrameSessionStateKeyProperty =
DependencyProperty::RegisterAttached("_FrameSessionStateKeyProperty",
TypeName(String::typeid), TypeName(SuspensionManager::typeid), nullptr);
DependencyProperty^ FrameSessionStateProperty =
DependencyProperty::RegisterAttached("_FrameSessionStateProperty",
TypeName(IMap<String^, Object^>::typeid), TypeName(SuspensionManager::typeid), nullptr);
}
/// <summary>
/// Registers a <see cref="Frame"/> instance to allow its navigation history to be saved to
/// and restored from <see cref="SessionState"/>. Frames should be registered once
/// immediately after creation if they will participate in session state management. Upon
/// registration if state has already been restored for the specified key
/// the navigation history will immediately be restored. Subsequent invocations of
/// <see cref="RestoreAsync(String)"/> will also restore navigation history.
/// </summary>
/// <param name="frame">An instance whose navigation history should be managed by
/// <see cref="SuspensionManager"/></param>
/// <param name="sessionStateKey">A unique key into <see cref="SessionState"/> used to
/// store navigation-related information.</param>
void SuspensionManager::RegisterFrame(Frame^ frame, String^ sessionStateKey)
{
if (frame->GetValue(FrameSessionStateKeyProperty) != nullptr)
{
throw ref new FailureException("Frames can only be registered to one session state key");
}
if (frame->GetValue(FrameSessionStateProperty) != nullptr)
{
throw ref new FailureException("Frames must be either be registered before accessing frame session state, or not registered at all");
}
// Use a dependency property to associate the session key with a frame, and keep a list of frames whose
// navigation state should be managed
frame->SetValue(FrameSessionStateKeyProperty, sessionStateKey);
_registeredFrames.insert(_registeredFrames.begin(), ref new WeakFrame(frame));
// Check to see if navigation state can be restored
RestoreFrameNavigationState(frame);
}
/// <summary>
/// Disassociates a <see cref="Frame"/> previously registered by <see cref="RegisterFrame"/>
/// from <see cref="SessionState"/>. Any navigation state previously captured will be
/// removed.
/// </summary>
/// <param name="frame">An instance whose navigation history should no longer be
/// managed.</param>
void SuspensionManager::UnregisterFrame(Frame^ frame)
{
// Remove session state and remove the frame from the list of frames whose navigation
// state will be saved (along with any weak references that are no longer reachable)
auto key = safe_cast<String^>(frame->GetValue(FrameSessionStateKeyProperty));
if (SessionState->HasKey(key)) SessionState->Remove(key);
_registeredFrames.erase(
std::remove_if(_registeredFrames.begin(), _registeredFrames.end(), [=](WeakFrame^& e)
{
auto testFrame = e->ResolvedFrame;
return testFrame == nullptr || testFrame == frame;
}),
_registeredFrames.end()
);
}
/// <summary>
/// Provides storage for session state associated with the specified <see cref="Frame"/>.
/// Frames that have been previously registered with <see cref="RegisterFrame"/> have
/// their session state saved and restored automatically as a part of the global
/// <see cref="SessionState"/>. Frames that are not registered have transient state
/// that can still be useful when restoring pages that have been discarded from the
/// navigation cache.
/// </summary>
/// <remarks>Apps may choose to rely on <see cref="LayoutAwarePage"/> to manage
/// page-specific state instead of working with frame session state directly.</remarks>
/// <param name="frame">The instance for which session state is desired.</param>
/// <returns>A collection of state subject to the same serialization mechanism as
/// <see cref="SessionState"/>.</returns>
IMap<String^, Object^>^ SuspensionManager::SessionStateForFrame(Frame^ frame)
{
auto frameState = safe_cast<IMap<String^, Object^>^>(frame->GetValue(FrameSessionStateProperty));
if (frameState == nullptr)
{
auto frameSessionKey = safe_cast<String^>(frame->GetValue(FrameSessionStateKeyProperty));
if (frameSessionKey != nullptr)
{
// Registered frames reflect the corresponding session state
if (!_sessionState->HasKey(frameSessionKey))
{
_sessionState->Insert(frameSessionKey, ref new Map<String^, Object^>());
}
frameState = safe_cast<IMap<String^, Object^>^>(_sessionState->Lookup(frameSessionKey));
}
else
{
// Frames that aren't registered have transient state
frameState = ref new Map<String^, Object^>();
}
frame->SetValue(FrameSessionStateProperty, frameState);
}
return frameState;
}
void SuspensionManager::RestoreFrameNavigationState(Frame^ frame)
{
auto frameState = SessionStateForFrame(frame);
if (frameState->HasKey("Navigation"))
{
frame->SetNavigationState(safe_cast<String^>(frameState->Lookup("Navigation")));
}
}
void SuspensionManager::SaveFrameNavigationState(Frame^ frame)
{
auto frameState = SessionStateForFrame(frame);
frameState->Insert("Navigation", frame->GetNavigationState());
}
/// <summary>
/// Save the current <see cref="SessionState"/>. Any <see cref="Frame"/> instances
/// registered with <see cref="RegisterFrame"/> will also preserve their current
/// navigation stack, which in turn gives their active <see cref="Page"/> an opportunity
/// to save its state.
/// </summary>
/// <returns>An asynchronous task that reflects when session state has been saved.</returns>
task<void> SuspensionManager::SaveAsync(void)
{
// Save the navigation state for all registered frames
for (auto&& weakFrame : _registeredFrames)
{
auto frame = weakFrame->ResolvedFrame;
if (frame != nullptr) SaveFrameNavigationState(frame);
}
// Serialize the session state synchronously to avoid asynchronous access to shared
// state
auto sessionData = ref new InMemoryRandomAccessStream();
auto sessionDataWriter = ref new DataWriter(sessionData->GetOutputStreamAt(0));
WriteObject(sessionDataWriter, _sessionState);
// Once session state has been captured synchronously, begin the asynchronous process
// of writing the result to disk
return task<unsigned int>(sessionDataWriter->StoreAsync()).then([=](unsigned int)
{
return sessionDataWriter->FlushAsync();
}).then([=](bool flushSucceeded)
{
(void)flushSucceeded; // Unused parameter
return ApplicationData::Current->LocalFolder->CreateFileAsync(sessionStateFilename,
CreationCollisionOption::ReplaceExisting);
}).then([=](StorageFile^ createdFile)
{
return createdFile->OpenAsync(FileAccessMode::ReadWrite);
}).then([=](IRandomAccessStream^ newStream)
{
return RandomAccessStream::CopyAndCloseAsync(
sessionData->GetInputStreamAt(0), newStream->GetOutputStreamAt(0));
}).then([=](UINT64 copiedBytes)
{
(void)copiedBytes; // Unused parameter
return;
});
}
/// <summary>
/// Restores previously saved <see cref="SessionState"/>. Any <see cref="Frame"/> instances
/// registered with <see cref="RegisterFrame"/> will also restore their prior navigation
/// state, which in turn gives their active <see cref="Page"/> an opportunity restore its
/// state.
/// </summary>
/// <param name="version">A version identifier compared to the session state to prevent
/// incompatible versions of session state from reaching app code. Saved state with a
/// different version will be ignored, resulting in an empty <see cref="SessionState"/>
/// dictionary.</param>
/// <returns>An asynchronous task that reflects when session state has been read. The
/// content of <see cref="SessionState"/> should not be relied upon until this task
/// completes.</returns>
task<void> SuspensionManager::RestoreAsync(void)
{
_sessionState->Clear();
task<StorageFile^> getFileTask(ApplicationData::Current->LocalFolder->GetFileAsync(sessionStateFilename));
return getFileTask.then([=](StorageFile^ stateFile)
{
task<BasicProperties^> getBasicPropertiesTask(stateFile->GetBasicPropertiesAsync());
return getBasicPropertiesTask.then([=](BasicProperties^ stateFileProperties)
{
auto size = unsigned int(stateFileProperties->Size);
if (size != stateFileProperties->Size) throw ref new FailureException("Session state larger than 4GB");
task<IRandomAccessStreamWithContentType^> openReadTask(stateFile->OpenReadAsync());
return openReadTask.then([=](IRandomAccessStreamWithContentType^ stateFileStream)
{
auto stateReader = ref new DataReader(stateFileStream);
return task<unsigned int>(stateReader->LoadAsync(size)).then([=](unsigned int bytesRead)
{
(void)bytesRead; // Unused parameter
// Deserialize the Session State
Object^ content = ReadObject(stateReader);
_sessionState = (Map<String^, Object^>^)content;
// Restore any registered frames to their saved state
for (auto&& weakFrame : _registeredFrames)
{
auto frame = weakFrame->ResolvedFrame;
if (frame != nullptr)
{
frame->ClearValue(FrameSessionStateProperty);
RestoreFrameNavigationState(frame);
}
}
}, task_continuation_context::use_current());
});
});
});
}
#pragma region Object serialization for a known set of types
namespace
{
// Codes used for identifying serialized types
enum StreamTypes {
NullPtrType = 0,
// Supported IPropertyValue types
UInt8Type, UInt16Type, UInt32Type, UInt64Type, Int16Type, Int32Type, Int64Type,
SingleType, DoubleType, BooleanType, Char16Type, GuidType, StringType,
// Additional supported types
StringToObjectMapType,
// Marker values used to ensure stream integrity
MapEndMarker
};
void WriteString(DataWriter^ writer, String^ string)
{
writer->WriteByte(StringType);
writer->WriteUInt32(writer->MeasureString(string));
writer->WriteString(string);
}
void WriteProperty(DataWriter^ writer, IPropertyValue^ propertyValue)
{
switch (propertyValue->Type)
{
case PropertyType::UInt8:
writer->WriteByte(UInt8Type);
writer->WriteByte(propertyValue->GetUInt8());
return;
case PropertyType::UInt16:
writer->WriteByte(UInt16Type);
writer->WriteUInt16(propertyValue->GetUInt16());
return;
case PropertyType::UInt32:
writer->WriteByte(UInt32Type);
writer->WriteUInt32(propertyValue->GetUInt32());
return;
case PropertyType::UInt64:
writer->WriteByte(UInt64Type);
writer->WriteUInt64(propertyValue->GetUInt64());
return;
case PropertyType::Int16:
writer->WriteByte(Int16Type);
writer->WriteUInt16(propertyValue->GetInt16());
return;
case PropertyType::Int32:
writer->WriteByte(Int32Type);
writer->WriteUInt32(propertyValue->GetInt32());
return;
case PropertyType::Int64:
writer->WriteByte(Int64Type);
writer->WriteUInt64(propertyValue->GetInt64());
return;
case PropertyType::Single:
writer->WriteByte(SingleType);
writer->WriteSingle(propertyValue->GetSingle());
return;
case PropertyType::Double:
writer->WriteByte(DoubleType);
writer->WriteDouble(propertyValue->GetDouble());
return;
case PropertyType::Boolean:
writer->WriteByte(BooleanType);
writer->WriteBoolean(propertyValue->GetBoolean());
return;
case PropertyType::Char16:
writer->WriteByte(Char16Type);
writer->WriteUInt16(propertyValue->GetChar16());
return;
case PropertyType::Guid:
writer->WriteByte(GuidType);
writer->WriteGuid(propertyValue->GetGuid());
return;
case PropertyType::String:
WriteString(writer, propertyValue->GetString());
return;
default:
throw ref new InvalidArgumentException("Unsupported property type");
}
}
void WriteStringToObjectMap(DataWriter^ writer, IMap<String^, Object^>^ map)
{
writer->WriteByte(StringToObjectMapType);
writer->WriteUInt32(map->Size);
for (auto&& pair : map)
{
WriteObject(writer, pair->Key);
WriteObject(writer, pair->Value);
}
writer->WriteByte(MapEndMarker);
}
void WriteObject(DataWriter^ writer, Object^ object)
{
if (object == nullptr)
{
writer->WriteByte(NullPtrType);
return;
}
auto propertyObject = dynamic_cast<IPropertyValue^>(object);
if (propertyObject != nullptr)
{
WriteProperty(writer, propertyObject);
return;
}
auto mapObject = dynamic_cast<IMap<String^, Object^>^>(object);
if (mapObject != nullptr)
{
WriteStringToObjectMap(writer, mapObject);
return;
}
throw ref new InvalidArgumentException("Unsupported data type");
}
String^ ReadString(DataReader^ reader)
{
int length = reader->ReadUInt32();
String^ string = reader->ReadString(length);
return string;
}
IMap<String^, Object^>^ ReadStringToObjectMap(DataReader^ reader)
{
auto map = ref new Map<String^, Object^>();
auto size = reader->ReadUInt32();
for (unsigned int index = 0; index < size; index++)
{
auto key = safe_cast<String^>(ReadObject(reader));
auto value = ReadObject(reader);
map->Insert(key, value);
}
if (reader->ReadByte() != MapEndMarker)
{
throw ref new InvalidArgumentException("Invalid stream");
}
return map;
}
Object^ ReadObject(DataReader^ reader)
{
auto type = reader->ReadByte();
switch (type)
{
case NullPtrType:
return nullptr;
case UInt8Type:
return reader->ReadByte();
case UInt16Type:
return reader->ReadUInt16();
case UInt32Type:
return reader->ReadUInt32();
case UInt64Type:
return reader->ReadUInt64();
case Int16Type:
return reader->ReadInt16();
case Int32Type:
return reader->ReadInt32();
case Int64Type:
return reader->ReadInt64();
case SingleType:
return reader->ReadSingle();
case DoubleType:
return reader->ReadDouble();
case BooleanType:
return reader->ReadBoolean();
case Char16Type:
return (char16_t)reader->ReadUInt16();
case GuidType:
return reader->ReadGuid();
case StringType:
return ReadString(reader);
case StringToObjectMapType:
return ReadStringToObjectMap(reader);
default:
throw ref new InvalidArgumentException("Unsupported property type");
}
}
}
#pragma endregion

View File

@ -0,0 +1,50 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
//
// SuspensionManager.h
// Declaration of the SuspensionManager class
//
#pragma once
#include <ppltasks.h>
namespace SDKSample
{
namespace Common
{
/// <summary>
/// SuspensionManager captures global session state to simplify process lifetime management
/// for an application. Note that session state will be automatically cleared under a variety
/// of conditions and should only be used to store information that would be convenient to
/// carry across sessions, but that should be disacarded when an application crashes or is
/// upgraded.
/// </summary>
ref class SuspensionManager sealed
{
internal:
static void RegisterFrame(Windows::UI::Xaml::Controls::Frame^ frame, Platform::String^ sessionStateKey);
static void UnregisterFrame(Windows::UI::Xaml::Controls::Frame^ frame);
static Concurrency::task<void> SaveAsync(void);
static Concurrency::task<void> RestoreAsync(void);
static property Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ SessionState
{
Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ get(void);
};
static Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ SessionStateForFrame(
Windows::UI::Xaml::Controls::Frame^ frame);
private:
static void RestoreFrameNavigationState(Windows::UI::Xaml::Controls::Frame^ frame);
static void SaveFrameNavigationState(Windows::UI::Xaml::Controls::Frame^ frame);
};
}
}

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros">
<OpenCV_Bin>$(OPENCV_WINRT_INSTALL_DIR)\WS\8.1\$(PlatformTarget)\$(PlatformTarget)\vc12\bin\</OpenCV_Bin>
<OpenCV_Lib>$(OPENCV_WINRT_INSTALL_DIR)\WS\8.1\$(PlatformTarget)\$(PlatformTarget)\vc12\lib\</OpenCV_Lib>
<OpenCV_Include>$(OPENCV_WINRT_INSTALL_DIR)\WS\8.1\$(PlatformTarget)\include\</OpenCV_Include>
<!--debug suffix for OpenCV dlls and libs -->
<DebugSuffix Condition="'$(Configuration)'=='Debug'">d</DebugSuffix>
<DebugSuffix Condition="'$(Configuration)'!='Debug'"></DebugSuffix>
</PropertyGroup>
<ItemGroup>
<!--Add required OpenCV dlls here-->
<None Include="$(OpenCV_Bin)opencv_core300$(DebugSuffix).dll">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="$(OpenCV_Bin)opencv_imgproc300$(DebugSuffix).dll">
<DeploymentContent>true</DeploymentContent>
</None>
</ItemGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(OpenCV_Include);$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<!--Add required OpenCV libs here-->
<AdditionalDependencies>opencv_core300$(DebugSuffix).lib;opencv_imgproc300$(DebugSuffix).lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OpenCV_Lib);%(AdditionalLibraryDirectories);</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
</Project>

View File

@ -0,0 +1,16 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
//
// pch.cpp
// Include the standard header and generate the precompiled header.
//
#include "pch.h"

View File

@ -0,0 +1,23 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
//
// pch.h
// Header for standard system include files.
//
#pragma once
#include <collection.h>
#include <ppltasks.h>
#include <agile.h>
#include "Common\LayoutAwarePage.h"
#include "Common\SuspensionManager.h"
#include "App.xaml.h"

View File

@ -0,0 +1,51 @@
<!--
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
-->
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="TitleTextStyle" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI Light" />
<Setter Property="FontSize" Value="16" />
</Style>
<Style x:Key="HeaderTextStyle" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI Semilight" />
<Setter Property="FontSize" Value="26.667" />
<Setter Property="Margin" Value="0,0,0,25" />
</Style>
<Style x:Key="H2Style" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontSize" Value="14.667" />
<Setter Property="Margin" Value="0,0,0,0" />
</Style>
<Style x:Key="SubheaderTextStyle" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI Semilight" />
<Setter Property="FontSize" Value="14.667" />
<Setter Property="Margin" Value="0,0,0,5" />
</Style>
<Style x:Key="BasicTextStyle" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI Light" />
<Setter Property="FontSize" Value="16" />
</Style>
<Style x:Key="SeparatorStyle" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontSize" Value="9" />
</Style>
<Style x:Key="FooterStyle" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontSize" Value="12" />
<Setter Property="Margin" Value="0,8,0,0" />
</Style>
<Style x:Key="HyperlinkStyle" TargetType="HyperlinkButton">
<Setter Property="Padding" Value="5"/>
</Style>
</ResourceDictionary>

View File

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|AnyCPU">
<Configuration>Debug</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x86">
<Configuration>Debug</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|AnyCPU">
<Configuration>Release</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x86">
<Configuration>Release</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>d70a3790-48ce-4e58-af60-ebefc22e9c7a</ProjectGuid>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '12.0'">
<VisualStudioVersion>12.0</VisualStudioVersion>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).Default.props" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).props" />
<PropertyGroup>
<TargetPlatformIdentifier>Windows</TargetPlatformIdentifier>
<TargetPlatformVersion>8.1</TargetPlatformVersion>
<RequiredPlatformVersion>8.1</RequiredPlatformVersion>
<MinimumVisualStudioVersion>$(VersionNumberMajor).$(VersionNumberMinor)</MinimumVisualStudioVersion>
<DefaultLanguage>en-US</DefaultLanguage>
<PackageCertificateKeyFile>MediaCaptureJavaScript_TemporaryKey.pfx</PackageCertificateKeyFile>
</PropertyGroup>
<ItemGroup>
<AppxManifest Include="package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
<Content Include="default.html" />
<Content Include="html\AdvancedCapture.html" />
<Content Include="images\logo.scale-100.png" />
<Content Include="images\microsoft-sdk.png" />
<Content Include="images\smalllogo.scale-100.png" />
<Content Include="images\smallTile-sdk.png" />
<Content Include="images\splash-sdk.png" />
<Content Include="images\splashscreen.scale-100.png" />
<Content Include="images\squareTile-sdk.png" />
<Content Include="images\storeLogo-sdk.png" />
<Content Include="images\storelogo.scale-100.png" />
<Content Include="images\tile-sdk.png" />
<Content Include="images\windows-sdk.png" />
<Content Include="js\AdvancedCapture.js" />
<Content Include="js\default.js" />
<Content Include="css\default.css" />
<Content Include="sample-utils\sample-utils.css" />
<Content Include="sample-utils\sample-utils.js" />
<Content Include="sample-utils\scenario-select.html" />
<None Include="MediaCaptureJavaScript_TemporaryKey.pfx" />
</ItemGroup>
<ItemGroup>
<SDKReference Include="Microsoft.WinJS.2.0, Version=1.0" />
</ItemGroup>
<PropertyGroup Label="UserMacros">
<OpenCV_Bin>$(OPENCV_WINRT_INSTALL_DIR)\WS\8.1\$(PlatformTarget)\$(PlatformTarget)\vc12\bin\</OpenCV_Bin>
<OpenCV_Lib>$(OPENCV_WINRT_INSTALL_DIR)\WS\8.1\$(PlatformTarget)\$(PlatformTarget)\vc12\lib\</OpenCV_Lib>
<OpenCV_Include>$(OPENCV_WINRT_INSTALL_DIR)\WS\8.1\$(PlatformTarget)\include\</OpenCV_Include>
<!--debug suffix for OpenCV dlls and libs -->
<DebugSuffix Condition="'$(Configuration)'=='Debug'">d</DebugSuffix>
<DebugSuffix Condition="'$(Configuration)'!='Debug'">
</DebugSuffix>
</PropertyGroup>
<ItemGroup>
<!--Add required OpenCV dlls here-->
<Content Include="$(OpenCV_Bin)opencv_core300$(DebugSuffix).dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(OpenCV_Bin)opencv_imgproc300$(DebugSuffix).dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ImageManipulations\MediaExtensions\OcvTransform\OcvTransform.vcxproj" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).targets" />
<!-- To modify your build process, add your task inside one of the targets below then uncomment
that target and the DisableFastUpToDateCheck PropertyGroup.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
<PropertyGroup>
<DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
</PropertyGroup>
-->
</Project>

View File

@ -0,0 +1,84 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OcvTransform", "..\ImageManipulations\MediaExtensions\OcvTransform\OcvTransform.vcxproj", "{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}"
EndProject
Project("{262852C6-CD72-467D-83FE-5EEB1973A190}") = "MediaCaptureJavaScript", "MediaCaptureJavaScript.jsproj", "{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM = Debug|ARM
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Any CPU = Release|Any CPU
Release|ARM = Release|ARM
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|Any CPU.ActiveCfg = Debug|Win32
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|ARM.ActiveCfg = Debug|ARM
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|ARM.Build.0 = Debug|ARM
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|ARM.Deploy.0 = Debug|ARM
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|Win32.ActiveCfg = Debug|Win32
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|Win32.Build.0 = Debug|Win32
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|Win32.Deploy.0 = Debug|Win32
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|x64.ActiveCfg = Debug|x64
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|x64.Build.0 = Debug|x64
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|x64.Deploy.0 = Debug|x64
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|Any CPU.ActiveCfg = Release|Win32
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|ARM.ActiveCfg = Release|ARM
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|ARM.Build.0 = Release|ARM
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|ARM.Deploy.0 = Release|ARM
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|Win32.ActiveCfg = Release|Win32
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|Win32.Build.0 = Release|Win32
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|Win32.Deploy.0 = Release|Win32
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|x64.ActiveCfg = Release|x64
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|x64.Build.0 = Release|x64
{C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|x64.Deploy.0 = Release|x64
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Debug|Any CPU.ActiveCfg = Debug|Win32
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Debug|ARM.ActiveCfg = Debug|ARM
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Debug|ARM.Build.0 = Debug|ARM
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Debug|Win32.ActiveCfg = Debug|Win32
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Debug|Win32.Build.0 = Debug|Win32
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Debug|x64.ActiveCfg = Debug|x64
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Debug|x64.Build.0 = Debug|x64
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Release|Any CPU.ActiveCfg = Release|Win32
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Release|ARM.ActiveCfg = Release|ARM
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Release|ARM.Build.0 = Release|ARM
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Release|Win32.ActiveCfg = Release|Win32
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Release|Win32.Build.0 = Release|Win32
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Release|x64.ActiveCfg = Release|x64
{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Release|x64.Build.0 = Release|x64
{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}.Debug|ARM.ActiveCfg = Debug|ARM
{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}.Debug|ARM.Build.0 = Debug|ARM
{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}.Debug|ARM.Deploy.0 = Debug|ARM
{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}.Debug|Win32.ActiveCfg = Debug|x86
{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}.Debug|Win32.Build.0 = Debug|x86
{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}.Debug|Win32.Deploy.0 = Debug|x86
{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}.Debug|x64.ActiveCfg = Debug|x64
{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}.Debug|x64.Build.0 = Debug|x64
{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}.Debug|x64.Deploy.0 = Debug|x64
{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}.Release|Any CPU.Build.0 = Release|Any CPU
{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}.Release|Any CPU.Deploy.0 = Release|Any CPU
{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}.Release|ARM.ActiveCfg = Release|ARM
{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}.Release|ARM.Build.0 = Release|ARM
{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}.Release|ARM.Deploy.0 = Release|ARM
{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}.Release|Win32.ActiveCfg = Release|x86
{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}.Release|Win32.Build.0 = Release|x86
{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}.Release|Win32.Deploy.0 = Release|x86
{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}.Release|x64.ActiveCfg = Release|x64
{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}.Release|x64.Build.0 = Release|x64
{D70A3790-48CE-4E58-AF60-EBEFC22E9C7A}.Release|x64.Deploy.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,6 @@
/* styles */
#featureLabel
{
padding-top: 50px;
}

View File

@ -0,0 +1,31 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>OpenCV for Windows RT</title>
<!-- WinJS references -->
<link rel="stylesheet" href="//Microsoft.WinJS.2.0/css/ui-light.css" />
<script src="//Microsoft.WinJS.2.0/js/base.js"></script>
<script src="//Microsoft.WinJS.2.0/js/ui.js"></script>
<!-- SDK sample framework references -->
<link rel="stylesheet" href="/sample-utils/sample-utils.css" />
<link rel="stylesheet" href="/css/default.css" />
<script src="/sample-utils/sample-utils.js"></script>
<script src="/js/default.js"></script>
</head>
<body role="application">
<div id="rootGrid">
<div id="content">
<h4>
<img src="images/windows-sdk.png" />
<span>OpenCV for Windows RT</span>
</h4>
<h1 id="featureLabel"></h1>
<div id="contentHost"></div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<link rel="stylesheet" href="/css/default.css" />
<script src="/js/AdvancedCapture.js"></script>
</head>
<body>
<div data-win-control="SdkSample.ScenarioInput">
<p>
This scenario shows how to enumerate cameras in the system.
Choose a camera from the list to start previewing from that camera. You can add additional effect
using the dropdown provided.
</p>
<select id="cameraSelect" aria-labelledby="listLabel"></select>
<button id="btnStartDevice" disabled="disabled">Start Device</button>
<button id="btnStartPreview" disabled="disabled">Start Preview</button>
<select id="videoEffect" disabled="disabled">
<option>Preview</option>
<option>Grayscale</option>
<option>Canny</option>
<option>Sobel</option>
<option>Histogram</option>
</select>
</div>
<div data-win-control="SdkSample.ScenarioOutput">
<table>
<tr>
<td>Preview</td>
</tr>
<tr>
<td>
<video width="320" height="240" id="previewVideo" style="border: 1px solid black">
</video>
</td>
</tr>
</table>
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,161 @@
//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//// PARTICULAR PURPOSE.
////
//// Copyright (c) Microsoft Corporation. All rights reserved
(function () {
"use strict";
var cameraList = null;
var mediaCaptureMgr = null;
var captureInitSettings = null;
var page = WinJS.UI.Pages.define("/html/AdvancedCapture.html", {
ready: function (element, options) {
scenarioInitialize();
},
unload: function (element, options) {
// release resources
releaseMediaCapture();
}
});
function scenarioInitialize() {
// Initialize the UI elements
id("btnStartDevice").disabled = false;
id("btnStartDevice").addEventListener("click", startDevice, false);
id("btnStartPreview").disabled = true;
id("videoEffect").disabled = true;
id("btnStartPreview").addEventListener("click", startPreview, false);
id("cameraSelect").addEventListener("change", onDeviceChange, false);
id("videoEffect").addEventListener('change', addEffectToImageStream, false);
enumerateCameras();
}
function initCameraSettings() {
captureInitSettings = new Windows.Media.Capture.MediaCaptureInitializationSettings();
captureInitSettings.streamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.video
// If the user chose another capture device, use it by default
var selectedIndex = id("cameraSelect").selectedIndex;
var deviceInfo = cameraList[selectedIndex];
captureInitSettings.videoDeviceId = deviceInfo.id;
}
// this function takes care of releasing the resources associated with media capturing
function releaseMediaCapture() {
if (mediaCaptureMgr) {
mediaCaptureMgr.close();
mediaCaptureMgr = null;
}
}
//Initialize media capture with the current settings
function startDevice() {
displayStatus("Starting device");
releaseMediaCapture();
initCameraSettings();
mediaCaptureMgr = new Windows.Media.Capture.MediaCapture();
mediaCaptureMgr.initializeAsync(captureInitSettings).done(function (result) {
// Update the UI
id("btnStartPreview").disabled = false;
id("btnStartDevice").disabled = true;
displayStatus("Device started");
});
}
function startPreview() {
displayStatus("Starting preview");
id("btnStartPreview").disabled = true;
id("videoEffect").disabled = false;
var video = id("previewVideo");
video.src = URL.createObjectURL(mediaCaptureMgr, { oneTimeOnly: true });
video.play();
displayStatus("Preview started");
}
function addEffectToImageStream() {
var effectId = id("videoEffect").selectedIndex;
var props = new Windows.Foundation.Collections.PropertySet();
props.insert("{698649BE-8EAE-4551-A4CB-3EC98FBD3D86}", effectId);
mediaCaptureMgr.clearEffectsAsync(Windows.Media.Capture.MediaStreamType.videoPreview).then(function () {
return mediaCaptureMgr.addEffectAsync(Windows.Media.Capture.MediaStreamType.videoPreview, 'OcvTransform.OcvImageManipulations', props);
}).then(function () {
displayStatus('Effect has been successfully added');
}, errorHandler);
}
function enumerateCameras() {
displayStatus("Enumerating capture devices");
var cameraSelect = id("cameraSelect");
cameraList = null;
cameraList = new Array();
// Clear the previous list of capture devices if any
while (cameraSelect.length > 0) {
cameraSelect.remove(0);
}
// Enumerate cameras and add them to the list
var deviceInfo = Windows.Devices.Enumeration.DeviceInformation;
deviceInfo.findAllAsync(Windows.Devices.Enumeration.DeviceClass.videoCapture).done(function (cameras) {
if (cameras.length === 0) {
cameraSelect.disabled = true;
displayError("No camera was found");
id("btnStartDevice").disabled = true;
cameraSelect.add(new Option("No cameras available"));
} else {
cameras.forEach(function (camera) {
cameraList.push(camera);
cameraSelect.add(new Option(camera.name));
});
}
}, errorHandler);
}
function onDeviceChange() {
releaseMediaCapture();
id("btnStartDevice").disabled = false;
id("btnStartPreview").disabled = true;
id("videoEffect").disabled = true;
displayStatus("");
}
function suspendingHandler(suspendArg) {
displayStatus("Suspended");
releaseMediaCapture();
}
function resumingHandler(resumeArg) {
displayStatus("Resumed");
scenarioInitialize();
}
function errorHandler(err) {
displayError(err.message);
}
function failedEventHandler(e) {
displayError("Fatal error", e.message);
}
function displayStatus(statusText) {
SdkSample.displayStatus(statusText);
}
function displayError(error) {
SdkSample.displayError(error);
}
function id(elementId) {
return document.getElementById(elementId);
}
})();

View File

@ -0,0 +1,74 @@
//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//// PARTICULAR PURPOSE.
////
//// Copyright (c) Microsoft Corporation. All rights reserved
(function () {
"use strict";
var sampleTitle = "OpenCV Image Manipulations sample";
var scenarios = [
{ url: "/html/AdvancedCapture.html", title: "Enumerate cameras and add a video effect" },
];
function activated(eventObject) {
if (eventObject.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
// Use setPromise to indicate to the system that the splash screen must not be torn down
// until after processAll and navigate complete asynchronously.
eventObject.setPromise(WinJS.UI.processAll().then(function () {
// Navigate to either the first scenario or to the last running scenario
// before suspension or termination.
var url = WinJS.Application.sessionState.lastUrl || scenarios[0].url;
return WinJS.Navigation.navigate(url);
}));
}
}
WinJS.Navigation.addEventListener("navigated", function (eventObject) {
var url = eventObject.detail.location;
var host = document.getElementById("contentHost");
// Call unload method on current scenario, if there is one
host.winControl && host.winControl.unload && host.winControl.unload();
WinJS.Utilities.empty(host);
eventObject.detail.setPromise(WinJS.UI.Pages.render(url, host, eventObject.detail.state).then(function () {
WinJS.Application.sessionState.lastUrl = url;
}));
});
WinJS.Namespace.define("SdkSample", {
sampleTitle: sampleTitle,
scenarios: scenarios,
mediaCaptureMgr: null,
photoFile: "photo.jpg",
deviceList: null,
recordState: null,
captureInitSettings: null,
encodingProfile: null,
storageFile: null,
photoStorage: null,
cameraControlSliders: null,
displayStatus: function (statusText) {
WinJS.log && WinJS.log(statusText, "MediaCapture", "status");
},
displayError: function (error) {
WinJS.log && WinJS.log(error, "MediaCapture", "error");
},
id: function (elementId) {
return document.getElementById(elementId);
},
});
WinJS.Application.addEventListener("activated", activated, false);
WinJS.Application.start();
Windows.UI.WebUI.WebUIApplication.addEventListener("suspending", SdkSample.suspendingHandler, false);
Windows.UI.WebUI.WebUIApplication.addEventListener("resuming", SdkSample.resumingHandler, false);
})();

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest">
<Identity Name="d70a3790-48ce-4e58-af60-ebefc22e9c7a" Version="1.0.0.0" Publisher="CN=Sergei" />
<Properties>
<DisplayName>MediaCaptureJavaScript</DisplayName>
<PublisherDisplayName>Sergei</PublisherDisplayName>
<Logo>images\storelogo.png</Logo>
</Properties>
<Prerequisites>
<OSMinVersion>6.3.0</OSMinVersion>
<OSMaxVersionTested>6.3.0</OSMaxVersionTested>
</Prerequisites>
<Resources>
<Resource Language="x-generate" />
</Resources>
<Applications>
<Application Id="App" StartPage="default.html">
<m2:VisualElements DisplayName="MediaCaptureJavaScript" Description="MediaCaptureJavaScript" ForegroundText="light" BackgroundColor="#464646" Square150x150Logo="images\Logo.png" Square30x30Logo="images\SmallLogo.png">
<m2:SplashScreen Image="images\splashscreen.png" />
</m2:VisualElements>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
<DeviceCapability Name="webcam" />
</Capabilities>
<Extensions>
<Extension Category="windows.activatableClass.inProcessServer">
<InProcessServer>
<Path>OcvTransform.dll</Path>
<ActivatableClass ActivatableClassId="OcvTransform.OcvImageManipulations" ThreadingModel="both" />
</InProcessServer>
</Extension>
</Extensions>
</Package>

View File

@ -0,0 +1,213 @@
/* Copyright (c) Microsoft Corporation. All rights reserved. */
html
{
cursor: default;
}
#featureLabel
{
font: 20pt/24pt "Segoe UI Semilight";
margin:0;
padding:5px 0 10px 0;
font-weight: normal;
}
#inputLabel, #outputLabel
{
font: 11pt/15pt "Segoe UI";
margin:0;
padding:0;
font-weight: normal;
}
#listLabel, #descLabel
{
font: 11pt/15pt "Segoe UI Semilight";
font-weight:normal;
}
#rootGrid
{
width: 100%;
height: 100%;
display: -ms-grid;
-ms-grid-columns: 100px 1fr 100px;
-ms-grid-rows: 20px auto 1fr auto 20px;
}
#header
{
-ms-grid-column: 2;
-ms-grid-row: 2;
}
#content
{
padding-right:20px;
padding-bottom:20px;
overflow:auto;
display:-ms-grid;
-ms-grid-columns:1fr;
-ms-grid-rows: auto 1fr;
-ms-grid-column: 2;
-ms-grid-row: 3;
}
#footer
{
-ms-grid-column: 2;
-ms-grid-row: 4;
padding-bottom:10px;
}
#featureLabel
{
-ms-grid-row: 1;
}
#contentHost
{
display:-ms-grid;
-ms-grid-columns:1fr;
-ms-grid-rows: auto auto auto 1fr;
-ms-grid-row: 2;
}
#inputLabel
{
-ms-grid-row: 1;
}
#input
{
-ms-grid-row: 2;
display: -ms-grid;
-ms-grid-columns: auto auto;
-ms-grid-rows: auto;
margin-top:10px;
}
#outputLabel
{
-ms-grid-row: 3;
padding-top:10px;
padding-bottom:10px;
}
#output
{
height:100%;
-ms-grid-row: 4;
-ms-grid-row-align:stretch;
}
.clear
{
clear:both;
}
#footer span
{
font-size:12px;
}
#footer .company
{
float:left;
}
#footer .links
{
float:right;
}
#footer .links a
{
font-size:12px;
margin-left:8px;
text-decoration:none;
}
#footer .links .pipe
{
font-size:9px;
margin-left:8px;
}
#statusMessage
{
margin-bottom:5px;
}
#input .options
{
-ms-grid-row: 1;
-ms-grid-column: 1;
}
#input .details
{
-ms-grid-row: 1;
-ms-grid-column: 2;
cursor:text;
}
.imageHolder
{
max-width:382px;
}
.imageHolder.withText
{
float:left;
margin-right:10px;
}
#scenarios
{
margin-right:20px;
}
@media screen and (min-width: 800px) and (max-width: 1024px)
{
#rootGrid
{
-ms-grid-columns: 40px 1fr 40px;
}
}
@media screen and (max-width: 799px)
{
#rootGrid
{
-ms-grid-columns: 20px 1fr 20px;
}
#output
{
padding-bottom:20px;
}
#input
{
-ms-grid-columns: auto;
-ms-grid-rows: auto auto;
}
#input .options
{
-ms-grid-row: 1;
-ms-grid-column: 1;
margin-bottom:10px;
}
#input .details
{
-ms-grid-row: 2;
-ms-grid-column: 1;
}
}

View File

@ -0,0 +1,204 @@
//// Copyright (c) Microsoft Corporation. All rights reserved
// This file is a part of the SDK sample framework. For code demonstrating scenarios in this particular sample,
// please see the html, css and js folders.
(function () {
//
// Helper controls used in the sample pages
//
// The ScenarioInput control inserts the appropriate markup to get labels & controls
// hooked into the input section of a scenario page so that it's not repeated in
// every one.
var lastError = "";
var lastStatus = "";
var ScenarioInput = WinJS.Class.define(
function (element, options) {
element.winControl = this;
this.element = element;
new WinJS.Utilities.QueryCollection(element)
.setAttribute("role", "main")
.setAttribute("aria-labelledby", "inputLabel");
element.id = "input";
this.addInputLabel(element);
this.addDetailsElement(element);
this.addScenariosPicker(element);
}, {
addInputLabel: function (element) {
var label = document.createElement("h2");
label.textContent = "Input";
label.id = "inputLabel";
element.parentNode.insertBefore(label, element);
},
addScenariosPicker: function (parentElement) {
var scenarios = document.createElement("div");
scenarios.id = "scenarios";
var control = new ScenarioSelect(scenarios);
parentElement.insertBefore(scenarios, parentElement.childNodes[0]);
},
addDetailsElement: function (sourceElement) {
var detailsDiv = this._createDetailsDiv();
while (sourceElement.childNodes.length > 0) {
detailsDiv.appendChild(sourceElement.removeChild(sourceElement.childNodes[0]));
}
sourceElement.appendChild(detailsDiv);
},
_createDetailsDiv: function () {
var detailsDiv = document.createElement("div");
new WinJS.Utilities.QueryCollection(detailsDiv)
.addClass("details")
.setAttribute("role", "region")
.setAttribute("aria-labelledby", "descLabel")
.setAttribute("aria-live", "assertive");
var label = document.createElement("h3");
label.textContent = "Description";
label.id = "descLabel";
detailsDiv.appendChild(label);
return detailsDiv;
},
}
);
// The ScenarioOutput control inserts the appropriate markup to get labels & controls
// hooked into the output section of a scenario page so that it's not repeated in
// every one.
var ScenarioOutput = WinJS.Class.define(
function (element, options) {
element.winControl = this;
this.element = element;
new WinJS.Utilities.QueryCollection(element)
.setAttribute("role", "region")
.setAttribute("aria-labelledby", "outputLabel")
.setAttribute("aria-live", "assertive");
element.id = "output";
this._addOutputLabel(element);
this._addStatusOutput(element);
}, {
_addOutputLabel: function (element) {
var label = document.createElement("h2");
label.id = "outputLabel";
label.textContent = "Output";
element.parentNode.insertBefore(label, element);
},
_addStatusOutput: function (element) {
var statusDiv = document.createElement("div");
statusDiv.id = "statusMessage";
statusDiv.setAttribute("role", "textbox");
element.insertBefore(statusDiv, element.childNodes[0]);
}
}
);
// Sample infrastructure internals
var currentScenarioUrl = null;
WinJS.Navigation.addEventListener("navigating", function (evt) {
currentScenarioUrl = evt.detail.location;
});
WinJS.log = function (message, tag, type) {
var isError = (type === "error");
var isStatus = (type === "status");
if (isError || isStatus) {
var statusDiv = /* @type(HTMLElement) */ document.getElementById("statusMessage");
if (statusDiv) {
statusDiv.innerText = message;
if (isError) {
lastError = message;
statusDiv.style.color = "blue";
} else if (isStatus) {
lastStatus = message;
statusDiv.style.color = "green";
}
}
}
};
// Control that populates and runs the scenario selector
var ScenarioSelect = WinJS.UI.Pages.define("/sample-utils/scenario-select.html", {
ready: function (element, options) {
var that = this;
var selectElement = WinJS.Utilities.query("#scenarioSelect", element);
this._selectElement = selectElement[0];
SdkSample.scenarios.forEach(function (s, index) {
that._addScenario(index, s);
});
selectElement.listen("change", function (evt) {
var select = evt.target;
if (select.selectedIndex >= 0) {
var newUrl = select.options[select.selectedIndex].value;
WinJS.Navigation.navigate(newUrl);
}
});
selectElement[0].size = (SdkSample.scenarios.length > 5 ? 5 : SdkSample.scenarios.length);
if (SdkSample.scenarios.length === 1) {
// Avoid showing down arrow when there is only one scenario
selectElement[0].setAttribute("multiple", "multiple");
}
// Use setImmediate to ensure that the select element is set as active only after
// the scenario page has been constructed.
setImmediate(function () {
that._selectElement.setActive();
});
},
_addScenario: function (index, info) {
var option = document.createElement("option");
if (info.url === currentScenarioUrl) {
option.selected = "selected";
}
option.text = (index + 1) + ") " + info.title;
option.value = info.url;
this._selectElement.appendChild(option);
}
});
function activated(e) {
WinJS.Utilities.query("#featureLabel")[0].textContent = SdkSample.sampleTitle;
}
WinJS.Application.addEventListener("activated", activated, false);
// Export public methods & controls
WinJS.Namespace.define("SdkSample", {
ScenarioInput: ScenarioInput,
ScenarioOutput: ScenarioOutput
});
// SDK Sample Test helper
document.TestSdkSample = {
getLastError: function () {
return lastError;
},
getLastStatus: function () {
return lastStatus;
},
selectScenario: function (scenarioID) {
scenarioID = scenarioID >> 0;
var select = document.getElementById("scenarioSelect");
var newUrl = select.options[scenarioID - 1].value;
WinJS.Navigation.navigate(newUrl);
}
};
})();

View File

@ -0,0 +1,15 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. -->
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<div class="options">
<h3 id="listLabel">Select scenario:</h3>
<select id="scenarioSelect" aria-labelledby="listLabel">
<!-- scenario list is inserted here -->
</select>
</div>
</body>
</html>

View File

@ -0,0 +1,40 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OcvImageProcessing", "OcvImageProcessing\OcvImageProcessing.vcxproj", "{A5555EA2-F9E8-4078-90F5-D428F2C0D6D1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|ARM = Release|ARM
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A5555EA2-F9E8-4078-90F5-D428F2C0D6D1}.Debug|ARM.ActiveCfg = Debug|ARM
{A5555EA2-F9E8-4078-90F5-D428F2C0D6D1}.Debug|ARM.Build.0 = Debug|ARM
{A5555EA2-F9E8-4078-90F5-D428F2C0D6D1}.Debug|ARM.Deploy.0 = Debug|ARM
{A5555EA2-F9E8-4078-90F5-D428F2C0D6D1}.Debug|Win32.ActiveCfg = Debug|Win32
{A5555EA2-F9E8-4078-90F5-D428F2C0D6D1}.Debug|Win32.Build.0 = Debug|Win32
{A5555EA2-F9E8-4078-90F5-D428F2C0D6D1}.Debug|Win32.Deploy.0 = Debug|Win32
{A5555EA2-F9E8-4078-90F5-D428F2C0D6D1}.Debug|x64.ActiveCfg = Debug|x64
{A5555EA2-F9E8-4078-90F5-D428F2C0D6D1}.Debug|x64.Build.0 = Debug|x64
{A5555EA2-F9E8-4078-90F5-D428F2C0D6D1}.Debug|x64.Deploy.0 = Debug|x64
{A5555EA2-F9E8-4078-90F5-D428F2C0D6D1}.Release|ARM.ActiveCfg = Release|ARM
{A5555EA2-F9E8-4078-90F5-D428F2C0D6D1}.Release|ARM.Build.0 = Release|ARM
{A5555EA2-F9E8-4078-90F5-D428F2C0D6D1}.Release|ARM.Deploy.0 = Release|ARM
{A5555EA2-F9E8-4078-90F5-D428F2C0D6D1}.Release|Win32.ActiveCfg = Release|Win32
{A5555EA2-F9E8-4078-90F5-D428F2C0D6D1}.Release|Win32.Build.0 = Release|Win32
{A5555EA2-F9E8-4078-90F5-D428F2C0D6D1}.Release|Win32.Deploy.0 = Release|Win32
{A5555EA2-F9E8-4078-90F5-D428F2C0D6D1}.Release|x64.ActiveCfg = Release|x64
{A5555EA2-F9E8-4078-90F5-D428F2C0D6D1}.Release|x64.Build.0 = Release|x64
{A5555EA2-F9E8-4078-90F5-D428F2C0D6D1}.Release|x64.Deploy.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,20 @@
<Application
x:Class="OcvImageProcessing.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:OcvImageProcessing">
<Application.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="Common/StandardStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

View File

@ -0,0 +1,107 @@
//
// App.xaml.cpp
// Implementation of the App class.
//
#include "pch.h"
#include "MainPage.xaml.h"
using namespace OcvImageProcessing;
using namespace Platform;
using namespace Windows::ApplicationModel;
using namespace Windows::ApplicationModel::Activation;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Interop;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
// The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
App::App()
{
InitializeComponent();
Suspending += ref new SuspendingEventHandler(this, &App::OnSuspending);
}
/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used when the application is launched to open a specific file, to display
/// search results, and so forth.
/// </summary>
/// <param name="args">Details about the launch request and process.</param>
void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ args)
{
auto rootFrame = dynamic_cast<Frame^>(Window::Current->Content);
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == nullptr)
{
// Create a Frame to act as the navigation context and associate it with
// a SuspensionManager key
rootFrame = ref new Frame();
if (args->PreviousExecutionState == ApplicationExecutionState::Terminated)
{
// TODO: Restore the saved session state only when appropriate, scheduling the
// final launch steps after the restore is complete
}
if (rootFrame->Content == nullptr)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
if (!rootFrame->Navigate(TypeName(MainPage::typeid), args->Arguments))
{
throw ref new FailureException("Failed to create initial page");
}
}
// Place the frame in the current Window
Window::Current->Content = rootFrame;
// Ensure the current window is active
Window::Current->Activate();
}
else
{
if (rootFrame->Content == nullptr)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
if (!rootFrame->Navigate(TypeName(MainPage::typeid), args->Arguments))
{
throw ref new FailureException("Failed to create initial page");
}
}
// Ensure the current window is active
Window::Current->Activate();
}
}
/// <summary>
/// Invoked when application execution is being suspended. Application state is saved
/// without knowing whether the application will be terminated or resumed with the contents
/// of memory still intact.
/// </summary>
/// <param name="sender">The source of the suspend request.</param>
/// <param name="e">Details about the suspend request.</param>
void App::OnSuspending(Object^ sender, SuspendingEventArgs^ e)
{
(void) sender; // Unused parameter
(void) e; // Unused parameter
//TODO: Save application state and stop any background activity
}

View File

@ -0,0 +1,24 @@
//
// App.xaml.h
// Declaration of the App class.
//
#pragma once
#include "App.g.h"
namespace OcvImageProcessing
{
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
ref class App sealed
{
public:
App();
virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ args) override;
private:
void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ e);
};
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,23 @@
<Page
x:Class="OcvImageProcessing.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:OcvImageProcessing"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Image x:Name="PreviewWidget" HorizontalAlignment="Left" Height="512" Margin="10,10,0,0" VerticalAlignment="Top" Width="512"/>
<Button Content="Apply" HorizontalAlignment="Left" Margin="527,71,0,0" VerticalAlignment="Top" Width="293" Height="63" Click="Button_Click"/>
<ComboBox x:Name="FilterTypeWidget" HorizontalAlignment="Left" Margin="527,10,0,0" VerticalAlignment="Top" Width="293" Height="56" SelectedIndex="0">
<ComboBoxItem Content="Preview"/>
<ComboBoxItem Content="GrayScale"/>
<ComboBoxItem Content="Canny"/>
<ComboBoxItem Content="Blur"/>
<ComboBoxItem Content="Features"/>
<ComboBoxItem Content="Sepia"/>
</ComboBox>
</Grid>
</Page>

View File

@ -0,0 +1,268 @@
//
// MainPage.xaml.cpp
// Implementation of the MainPage class.
//
#include "pch.h"
#include "MainPage.xaml.h"
#include <ppltasks.h>
#include <wrl\client.h>
#include <Robuffer.h>
#include <vector>
#include <opencv2\imgproc\types_c.h>
#include <opencv2\imgcodecs.hpp>
#include <opencv2\core.hpp>
#include <windows.storage.h>
using namespace OcvImageProcessing;
using namespace Microsoft::WRL;
using namespace concurrency;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Storage::Streams;
using namespace Windows::Storage;
using namespace Windows::UI::Xaml::Media::Imaging;
using namespace Windows::Graphics::Imaging;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
Uri^ InputImageUri = ref new Uri(L"ms-appx:///Assets/Lena.png");
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
MainPage::MainPage()
{
InitializeComponent();
#ifdef __OPENCV_IMGCODECS_HPP__
// Image loading OpenCV way ... way more simple
cv::Mat image = cv::imread("Assets/Lena.png");
Lena = cv::Mat(image.rows, image.cols, CV_8UC4);
cvtColor(image, Lena, COLOR_BGR2BGRA);
UpdateImage(Lena);
#else
// Image loading WinRT way
RandomAccessStreamReference^ streamRef = RandomAccessStreamReference::CreateFromUri(InputImageUri);
task<IRandomAccessStreamWithContentType^> (streamRef->OpenReadAsync()).
then([](task<IRandomAccessStreamWithContentType^> thisTask)
{
IRandomAccessStreamWithContentType^ fileStream = thisTask.get();
return BitmapDecoder::CreateAsync(fileStream);
}).
then([](task<BitmapDecoder^> thisTask)
{
BitmapDecoder^ decoder = thisTask.get();
return decoder->GetFrameAsync(0);
}).
then([this](task<BitmapFrame^> thisTask)
{
BitmapFrame^ frame = thisTask.get();
// Save some information as fields
frameWidth = frame->PixelWidth;
frameHeight = frame->PixelHeight;
return frame->GetPixelDataAsync();
}).
then([this](task<PixelDataProvider^> thisTask)
{
PixelDataProvider^ pixelProvider = thisTask.get();
Platform::Array<byte>^ srcPixels = pixelProvider->DetachPixelData();
Lena = cv::Mat(frameHeight, frameWidth, CV_8UC4);
memcpy(Lena.data, srcPixels->Data, 4*frameWidth*frameHeight);
UpdateImage(Lena);
});
#endif
}
/// <summary>
/// Temporary file creation example. Will be created in WinRT application temporary directory
/// which usually is "C:\Users\{username}\AppData\Local\Packages\{package_id}\TempState\{random_name}.{suffix}"
/// </summary>
/// <param name="suffix">Temporary file suffix, e.g. "tmp"</param>
std::string OcvImageProcessing::MainPage::CreateTempFile(const std::string &suffix) {
return cv::tempfile(suffix.c_str());
}
/// <summary>
/// Creating/writing a file in the application local directory
/// </summary>
/// <param name="path">Image to save</param>
bool OcvImageProcessing::MainPage::SaveImage(cv::Mat image) {
StorageFolder^ localFolderRT = ApplicationData::Current->LocalFolder;
cv::String localFile = ConvertPath(ApplicationData::Current->LocalFolder->Path) + "\\Lena.png";
return cv::imwrite(localFile, image);
}
/// <summary>
/// Getting std::string from managed string via std::wstring.
/// Provides an example of three ways to do it.
/// Can't use this one: https://msdn.microsoft.com/en-us/library/bb384865.aspx, not available on WinRT.
/// </summary>
/// <param name="path">Path to be converted</param>
cv::String OcvImageProcessing::MainPage::ConvertPath(Platform::String^ path) {
std::wstring localPathW(path->Begin());
// Opt #1
//std::string localPath(localPathW.begin(), localPathW.end());
// Opt #2
//std::string localPath(StrToWStr(localPathW));
// Opt #3
size_t outSize = localPathW.length() + 1;
char* localPathC = new char[outSize];
size_t charsConverted = 0;
wcstombs_s(&charsConverted, localPathC, outSize, localPathW.c_str(), localPathW.length());
cv::String localPath(localPathC);
// Implicit conversion from std::string to cv::String
return localPath;
}
std::string OcvImageProcessing::MainPage::StrToWStr(const std::wstring &input) {
if (input.empty()) {
return std::string();
}
int size = WideCharToMultiByte(CP_UTF8, 0, &input[0], (int)input.size(), NULL, 0, NULL, NULL);
std::string result(size, 0);
WideCharToMultiByte(CP_UTF8, 0, &input[0], (int)input.size(), &result[0], size, NULL, NULL);
return result;
}
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached. The Parameter
/// property is typically used to configure the page.</param>
void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
{
(void) e; // Unused parameter
}
void OcvImageProcessing::MainPage::UpdateImage(const cv::Mat& image)
{
// Create the WriteableBitmap
WriteableBitmap^ bitmap = ref new WriteableBitmap(image.cols, image.rows);
// Get access to the pixels
IBuffer^ buffer = bitmap->PixelBuffer;
unsigned char* dstPixels;
// Obtain IBufferByteAccess
ComPtr<IBufferByteAccess> pBufferByteAccess;
ComPtr<IInspectable> pBuffer((IInspectable*)buffer);
pBuffer.As(&pBufferByteAccess);
// Get pointer to pixel bytes
pBufferByteAccess->Buffer(&dstPixels);
memcpy(dstPixels, image.data, image.step.buf[1]*image.cols*image.rows);
// Set the bitmap to the Image element
PreviewWidget->Source = bitmap;
}
cv::Mat OcvImageProcessing::MainPage::ApplyGrayFilter(const cv::Mat& image)
{
cv::Mat result;
cv::Mat intermediateMat;
cv::cvtColor(image, intermediateMat, COLOR_RGBA2GRAY);
cv::cvtColor(intermediateMat, result, COLOR_GRAY2BGRA);
return result;
}
cv::Mat OcvImageProcessing::MainPage::ApplyCannyFilter(const cv::Mat& image)
{
cv::Mat result;
cv::Mat intermediateMat;
cv::Canny(image, intermediateMat, 80, 90);
cv::cvtColor(intermediateMat, result, COLOR_GRAY2BGRA);
return result;
}
cv::Mat OcvImageProcessing::MainPage::ApplyBlurFilter(const cv::Mat& image)
{
cv::Mat result;
cv::blur(image, result, cv::Size(3,3));
return result;
}
cv::Mat OcvImageProcessing::MainPage::ApplyFindFeaturesFilter(const cv::Mat& image)
{
cv::Mat result;
cv::Mat intermediateMat;
cv::Ptr<cv::FastFeatureDetector> detector = cv::FastFeatureDetector::create(50);
std::vector<cv::KeyPoint> features;
image.copyTo(result);
cv::cvtColor(image, intermediateMat, COLOR_RGBA2GRAY);
detector->detect(intermediateMat, features);
for( unsigned int i = 0; i < std::min(features.size(), (size_t)50); i++ )
{
const cv::KeyPoint& kp = features[i];
cv::circle(result, cv::Point((int)kp.pt.x, (int)kp.pt.y), 10, cv::Scalar(255,0,0,255));
}
return result;
}
cv::Mat OcvImageProcessing::MainPage::ApplySepiaFilter(const cv::Mat& image)
{
const float SepiaKernelData[16] =
{
/* B */0.131f, 0.534f, 0.272f, 0.f,
/* G */0.168f, 0.686f, 0.349f, 0.f,
/* R */0.189f, 0.769f, 0.393f, 0.f,
/* A */0.000f, 0.000f, 0.000f, 1.f
};
const cv::Mat SepiaKernel(4, 4, CV_32FC1, (void*)SepiaKernelData);
cv::Mat result;
cv::transform(image, result, SepiaKernel);
return result;
}
void OcvImageProcessing::MainPage::Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
switch(FilterTypeWidget->SelectedIndex)
{
case PREVIEW:
UpdateImage(Lena);
break;
case GRAY:
UpdateImage(ApplyGrayFilter(Lena));
break;
case CANNY:
UpdateImage(ApplyCannyFilter(Lena));
break;
case BLUR:
UpdateImage(ApplyBlurFilter(Lena));
break;
case FEATURES:
UpdateImage(ApplyFindFeaturesFilter(Lena));
break;
case SEPIA:
UpdateImage(ApplySepiaFilter(Lena));
break;
default:
UpdateImage(Lena);
}
}

View File

@ -0,0 +1,51 @@
//
// MainPage.xaml.h
// Declaration of the MainPage class.
//
#pragma once
#include "MainPage.g.h"
#include <opencv2\core\core.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\features2d\features2d.hpp>
namespace OcvImageProcessing
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public ref class MainPage sealed
{
public:
MainPage();
protected:
virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
private:
static const int PREVIEW = 0;
static const int GRAY = 1;
static const int CANNY = 2;
static const int BLUR = 3;
static const int FEATURES = 4;
static const int SEPIA = 5;
void Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
cv::Mat ApplyGrayFilter(const cv::Mat& image);
cv::Mat ApplyCannyFilter(const cv::Mat& image);
cv::Mat ApplyBlurFilter(const cv::Mat& image);
cv::Mat ApplyFindFeaturesFilter(const cv::Mat& image);
cv::Mat ApplySepiaFilter(const cv::Mat& image);
void UpdateImage(const cv::Mat& image);
std::string CreateTempFile(const std::string &suffix);
bool SaveImage(cv::Mat image);
std::string StrToWStr(const std::wstring &wstr);
cv::String ConvertPath(Platform::String^ path);
cv::Mat Lena;
unsigned int frameWidth, frameHeight;
};
}

Some files were not shown because too many files have changed in this diff Show More