Add Image Sequencer 2.0 version
- Universal project - Includes sequence capture feature
|
@ -0,0 +1,54 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Express 2013 for Windows
|
||||
VisualStudioVersion = 12.0.30324.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ImageSequencer", "ImageSequencer", "{57BAF6C9-7CB4-4E48-9B90-39C67ED15815}"
|
||||
EndProject
|
||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "ImageSequencer.Shared", "ImageSequencer\ImageSequencer.Shared\ImageSequencer.Shared.shproj", "{5F8CC95D-790C-4D28-A7FA-8D9C08D6BB25}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageSequencer.WindowsPhone", "ImageSequencer\ImageSequencer.WindowsPhone\ImageSequencer.WindowsPhone.csproj", "{22C3F30A-9C25-4DCB-A3CE-9ACBA1BD2098}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
||||
ImageSequencer\ImageSequencer.Shared\ImageSequencer.Shared.projitems*{5f8cc95d-790c-4d28-a7fa-8d9c08d6bb25}*SharedItemsImports = 13
|
||||
ImageSequencer\ImageSequencer.Shared\ImageSequencer.Shared.projitems*{22c3f30a-9c25-4dcb-a3ce-9acba1bd2098}*SharedItemsImports = 4
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|ARM = Debug|ARM
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|ARM = Release|ARM
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{22C3F30A-9C25-4DCB-A3CE-9ACBA1BD2098}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{22C3F30A-9C25-4DCB-A3CE-9ACBA1BD2098}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{22C3F30A-9C25-4DCB-A3CE-9ACBA1BD2098}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{22C3F30A-9C25-4DCB-A3CE-9ACBA1BD2098}.Debug|ARM.Deploy.0 = Debug|ARM
|
||||
{22C3F30A-9C25-4DCB-A3CE-9ACBA1BD2098}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{22C3F30A-9C25-4DCB-A3CE-9ACBA1BD2098}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{22C3F30A-9C25-4DCB-A3CE-9ACBA1BD2098}.Debug|x86.Build.0 = Debug|x86
|
||||
{22C3F30A-9C25-4DCB-A3CE-9ACBA1BD2098}.Debug|x86.Deploy.0 = Debug|x86
|
||||
{22C3F30A-9C25-4DCB-A3CE-9ACBA1BD2098}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{22C3F30A-9C25-4DCB-A3CE-9ACBA1BD2098}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{22C3F30A-9C25-4DCB-A3CE-9ACBA1BD2098}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{22C3F30A-9C25-4DCB-A3CE-9ACBA1BD2098}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{22C3F30A-9C25-4DCB-A3CE-9ACBA1BD2098}.Release|ARM.Build.0 = Release|ARM
|
||||
{22C3F30A-9C25-4DCB-A3CE-9ACBA1BD2098}.Release|ARM.Deploy.0 = Release|ARM
|
||||
{22C3F30A-9C25-4DCB-A3CE-9ACBA1BD2098}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{22C3F30A-9C25-4DCB-A3CE-9ACBA1BD2098}.Release|x86.ActiveCfg = Release|x86
|
||||
{22C3F30A-9C25-4DCB-A3CE-9ACBA1BD2098}.Release|x86.Build.0 = Release|x86
|
||||
{22C3F30A-9C25-4DCB-A3CE-9ACBA1BD2098}.Release|x86.Deploy.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{5F8CC95D-790C-4D28-A7FA-8D9C08D6BB25} = {57BAF6C9-7CB4-4E48-9B90-39C67ED15815}
|
||||
{22C3F30A-9C25-4DCB-A3CE-9ACBA1BD2098} = {57BAF6C9-7CB4-4E48-9B90-39C67ED15815}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,52 @@
|
|||
<!--
|
||||
Copyright (c) 2014 Nokia Corporation. All rights reserved.
|
||||
|
||||
Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation.
|
||||
Other product and company names mentioned herein may be trademarks
|
||||
or trade names of their respective owners.
|
||||
|
||||
See the license text file for license information.
|
||||
-->
|
||||
|
||||
<Page
|
||||
x:Class="ImageSequencer.AboutPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:ImageSequencer"
|
||||
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">
|
||||
<Grid.Background>
|
||||
<ImageBrush ImageSource="/Assets/Background.png" Stretch="UniformToFill"/>
|
||||
</Grid.Background>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Grid.Row="0" Margin="24,17,0,28">
|
||||
<TextBlock x:Uid="ApplicationHeader" Style="{StaticResource TitleTextBlockStyle}" Typography.Capitals="SmallCaps">
|
||||
IMAGE SEQUENCER
|
||||
</TextBlock>
|
||||
<TextBlock x:Uid="AboutPageTitle" Margin="0,12,0,0" Style="{ThemeResource HeaderTextBlockStyle}">
|
||||
about
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
|
||||
<Grid Grid.Row="1" x:Name="ContentRoot" Margin="24,0,24,0">
|
||||
<StackPanel>
|
||||
<TextBlock Text="2.0.0.0"
|
||||
Style="{StaticResource BodyTextBlockStyle}" Margin="0,0,0,18"/>
|
||||
<TextBlock Style="{StaticResource BodyTextBlockStyle}" Margin="0,0,0,12">
|
||||
Image Sequencer is an example application demonstrating the use of sequence capture together with Nokia Imaging SDK’s Image Aligner and Gif Renderer APIs for creating cinemagraph-style animations in animated GIF format.
|
||||
</TextBlock>
|
||||
<TextBlock Style="{StaticResource BodyTextBlockStyle}" Margin="0,0,0,12">
|
||||
For more information and application source code visit project GitHub repository.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Page>
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* Copyright (c) 2013-2014 Microsoft Mobile.
|
||||
* See the license file delivered with this project for more information.
|
||||
*/
|
||||
|
||||
|
||||
using ImageSequencer.Common;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
namespace ImageSequencer
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// </summary>
|
||||
public sealed partial class AboutPage : Page
|
||||
{
|
||||
|
||||
private NavigationHelper _navigationHelper;
|
||||
|
||||
public AboutPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
|
||||
_navigationHelper = new NavigationHelper(this);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<Application
|
||||
x:Class="ImageSequencer.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:ImageSequencer">
|
||||
|
||||
</Application>
|
|
@ -0,0 +1,139 @@
|
|||
/**
|
||||
* Copyright (c) 2013-2014 Microsoft Mobile.
|
||||
* See the license file delivered with this project for more information.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.ApplicationModel;
|
||||
using Windows.ApplicationModel.Activation;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Media.Animation;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
|
||||
namespace ImageSequencer
|
||||
{
|
||||
|
||||
public sealed partial class App : Application
|
||||
{
|
||||
#if WINDOWS_PHONE_APP
|
||||
private TransitionCollection transitions;
|
||||
#endif
|
||||
|
||||
/// <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>
|
||||
public App()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.Suspending += this.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="e">Details about the launch request and process.</param>
|
||||
protected override void OnLaunched(LaunchActivatedEventArgs e)
|
||||
{
|
||||
#if DEBUG
|
||||
if (System.Diagnostics.Debugger.IsAttached)
|
||||
{
|
||||
this.DebugSettings.EnableFrameRateCounter = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
Frame rootFrame = Window.Current.Content as Frame;
|
||||
|
||||
// Do not repeat app initialization when the Window already has content,
|
||||
// just ensure that the window is active
|
||||
if (rootFrame == null)
|
||||
{
|
||||
// Create a Frame to act as the navigation context and navigate to the first page
|
||||
rootFrame = new Frame();
|
||||
|
||||
// TODO: change this value to a cache size that is appropriate for your application
|
||||
rootFrame.CacheSize = 1;
|
||||
|
||||
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
|
||||
{
|
||||
// TODO: Load state from previously suspended application
|
||||
}
|
||||
|
||||
// Place the frame in the current Window
|
||||
Window.Current.Content = rootFrame;
|
||||
}
|
||||
|
||||
if (rootFrame.Content == null)
|
||||
{
|
||||
#if WINDOWS_PHONE_APP
|
||||
// Removes the turnstile navigation for startup.
|
||||
if (rootFrame.ContentTransitions != null)
|
||||
{
|
||||
this.transitions = new TransitionCollection();
|
||||
foreach (var c in rootFrame.ContentTransitions)
|
||||
{
|
||||
this.transitions.Add(c);
|
||||
}
|
||||
}
|
||||
|
||||
rootFrame.ContentTransitions = null;
|
||||
rootFrame.Navigated += this.RootFrame_FirstNavigated;
|
||||
#endif
|
||||
|
||||
// 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(typeof(SequencesPage), e.Arguments))
|
||||
{
|
||||
throw new Exception("Failed to create initial page");
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the current window is active
|
||||
Window.Current.Activate();
|
||||
}
|
||||
|
||||
#if WINDOWS_PHONE_APP
|
||||
/// <summary>
|
||||
/// Restores the content transitions after the app has launched.
|
||||
/// </summary>
|
||||
/// <param name="sender">The object where the handler is attached.</param>
|
||||
/// <param name="e">Details about the navigation event.</param>
|
||||
private void RootFrame_FirstNavigated(object sender, NavigationEventArgs e)
|
||||
{
|
||||
var rootFrame = sender as Frame;
|
||||
rootFrame.ContentTransitions = this.transitions ?? new TransitionCollection() { new NavigationThemeTransition() };
|
||||
rootFrame.Navigated -= this.RootFrame_FirstNavigated;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <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>
|
||||
private void OnSuspending(object sender, SuspendingEventArgs e)
|
||||
{
|
||||
var deferral = e.SuspendingOperation.GetDeferral();
|
||||
|
||||
// TODO: Save application state and stop any background activity
|
||||
deferral.Complete();
|
||||
}
|
||||
}
|
||||
}
|
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/Thumbs.db
Normal file
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/appbar.align.disabled.png
Normal file
После Ширина: | Высота: | Размер: 951 B |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/appbar.align.enabled.png
Normal file
После Ширина: | Высота: | Размер: 1.8 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/appbar.frame.disabled.png
Normal file
После Ширина: | Высота: | Размер: 239 B |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/appbar.frame.enabled.png
Normal file
После Ширина: | Высота: | Размер: 1.1 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/appbar.sequence.capture.png
Normal file
После Ширина: | Высота: | Размер: 932 B |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.1.0.jpg
Normal file
После Ширина: | Высота: | Размер: 102 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.1.1.jpg
Normal file
После Ширина: | Высота: | Размер: 102 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.1.10.jpg
Normal file
После Ширина: | Высота: | Размер: 103 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.1.11.jpg
Normal file
После Ширина: | Высота: | Размер: 107 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.1.12.jpg
Normal file
После Ширина: | Высота: | Размер: 103 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.1.13.jpg
Normal file
После Ширина: | Высота: | Размер: 96 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.1.14.jpg
Normal file
После Ширина: | Высота: | Размер: 102 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.1.15.jpg
Normal file
После Ширина: | Высота: | Размер: 102 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.1.16.jpg
Normal file
После Ширина: | Высота: | Размер: 104 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.1.17.jpg
Normal file
После Ширина: | Высота: | Размер: 99 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.1.18.jpg
Normal file
После Ширина: | Высота: | Размер: 103 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.1.19.jpg
Normal file
После Ширина: | Высота: | Размер: 101 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.1.2.jpg
Normal file
После Ширина: | Высота: | Размер: 107 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.1.20.jpg
Normal file
После Ширина: | Высота: | Размер: 103 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.1.21.jpg
Normal file
После Ширина: | Высота: | Размер: 103 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.1.22.jpg
Normal file
После Ширина: | Высота: | Размер: 100 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.1.3.jpg
Normal file
После Ширина: | Высота: | Размер: 108 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.1.4.jpg
Normal file
После Ширина: | Высота: | Размер: 93 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.1.5.jpg
Normal file
После Ширина: | Высота: | Размер: 100 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.1.6.jpg
Normal file
После Ширина: | Высота: | Размер: 99 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.1.7.jpg
Normal file
После Ширина: | Высота: | Размер: 102 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.1.8.jpg
Normal file
После Ширина: | Высота: | Размер: 101 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.1.9.jpg
Normal file
После Ширина: | Высота: | Размер: 104 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.2.0.jpg
Normal file
После Ширина: | Высота: | Размер: 94 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.2.1.jpg
Normal file
После Ширина: | Высота: | Размер: 106 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.2.10.jpg
Normal file
После Ширина: | Высота: | Размер: 112 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.2.11.jpg
Normal file
После Ширина: | Высота: | Размер: 99 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.2.12.jpg
Normal file
После Ширина: | Высота: | Размер: 104 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.2.13.jpg
Normal file
После Ширина: | Высота: | Размер: 115 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.2.14.jpg
Normal file
После Ширина: | Высота: | Размер: 98 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.2.15.jpg
Normal file
После Ширина: | Высота: | Размер: 106 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.2.16.jpg
Normal file
После Ширина: | Высота: | Размер: 107 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.2.17.jpg
Normal file
После Ширина: | Высота: | Размер: 108 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.2.18.jpg
Normal file
После Ширина: | Высота: | Размер: 101 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.2.19.jpg
Normal file
После Ширина: | Высота: | Размер: 111 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.2.2.jpg
Normal file
После Ширина: | Высота: | Размер: 109 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.2.3.jpg
Normal file
После Ширина: | Высота: | Размер: 90 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.2.4.jpg
Normal file
После Ширина: | Высота: | Размер: 104 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.2.5.jpg
Normal file
После Ширина: | Высота: | Размер: 104 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.2.6.jpg
Normal file
После Ширина: | Высота: | Размер: 107 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.2.7.jpg
Normal file
После Ширина: | Высота: | Размер: 96 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.2.8.jpg
Normal file
После Ширина: | Высота: | Размер: 109 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Shared/Assets/sequence.2.9.jpg
Normal file
После Ширина: | Высота: | Размер: 110 KiB |
|
@ -0,0 +1,433 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Windows.System;
|
||||
using Windows.UI.Core;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
namespace ImageSequencer.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// NavigationHelper aids in navigation between pages. It provides commands used to
|
||||
/// navigate back and forward as well as registers for standard mouse and keyboard
|
||||
/// shortcuts used to go back and forward in Windows and the hardware back button in
|
||||
/// Windows Phone. In addition it integrates SuspensionManger to handle process lifetime
|
||||
/// management and state management when navigating between pages.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// To make use of NavigationHelper, follow these two steps or
|
||||
/// start with a BasicPage or any other Page item template other than BlankPage.
|
||||
///
|
||||
/// 1) Create an instance of the NavigationHelper somewhere such as in the
|
||||
/// constructor for the page and register a callback for the LoadState and
|
||||
/// SaveState events.
|
||||
/// <code>
|
||||
/// public MyPage()
|
||||
/// {
|
||||
/// this.InitializeComponent();
|
||||
/// var navigationHelper = new NavigationHelper(this);
|
||||
/// this.navigationHelper.LoadState += navigationHelper_LoadState;
|
||||
/// this.navigationHelper.SaveState += navigationHelper_SaveState;
|
||||
/// }
|
||||
///
|
||||
/// private async void navigationHelper_LoadState(object sender, LoadStateEventArgs e)
|
||||
/// { }
|
||||
/// private async void navigationHelper_SaveState(object sender, LoadStateEventArgs e)
|
||||
/// { }
|
||||
/// </code>
|
||||
///
|
||||
/// 2) Register the page to call into the NavigationHelper whenever the page participates
|
||||
/// in navigation by overriding the <see cref="Windows.UI.Xaml.Controls.Page.OnNavigatedTo"/>
|
||||
/// and <see cref="Windows.UI.Xaml.Controls.Page.OnNavigatedFrom"/> events.
|
||||
/// <code>
|
||||
/// protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
/// {
|
||||
/// navigationHelper.OnNavigatedTo(e);
|
||||
/// }
|
||||
///
|
||||
/// protected override void OnNavigatedFrom(NavigationEventArgs e)
|
||||
/// {
|
||||
/// navigationHelper.OnNavigatedFrom(e);
|
||||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
[Windows.Foundation.Metadata.WebHostHidden]
|
||||
public class NavigationHelper : DependencyObject
|
||||
{
|
||||
private Page Page { get; set; }
|
||||
private Frame Frame { get { return this.Page.Frame; } }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NavigationHelper"/> class.
|
||||
/// </summary>
|
||||
/// <param name="page">A reference to the current page used for navigation.
|
||||
/// This reference allows for frame manipulation and to ensure that keyboard
|
||||
/// navigation requests only occur when the page is occupying the entire window.</param>
|
||||
public NavigationHelper(Page page)
|
||||
{
|
||||
this.Page = page;
|
||||
|
||||
// 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 hardware navigation requests
|
||||
this.Page.Loaded += (sender, e) =>
|
||||
{
|
||||
#if WINDOWS_PHONE_APP
|
||||
Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;
|
||||
#else
|
||||
// Keyboard and mouse navigation only apply when occupying the entire window
|
||||
if (this.Page.ActualHeight == Window.Current.Bounds.Height &&
|
||||
this.Page.ActualWidth == Window.Current.Bounds.Width)
|
||||
{
|
||||
// Listen to the window directly so focus isn't required
|
||||
Window.Current.CoreWindow.Dispatcher.AcceleratorKeyActivated +=
|
||||
CoreDispatcher_AcceleratorKeyActivated;
|
||||
Window.Current.CoreWindow.PointerPressed +=
|
||||
this.CoreWindow_PointerPressed;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
// Undo the same changes when the page is no longer visible
|
||||
this.Page.Unloaded += (sender, e) =>
|
||||
{
|
||||
#if WINDOWS_PHONE_APP
|
||||
Windows.Phone.UI.Input.HardwareButtons.BackPressed -= HardwareButtons_BackPressed;
|
||||
#else
|
||||
Window.Current.CoreWindow.Dispatcher.AcceleratorKeyActivated -=
|
||||
CoreDispatcher_AcceleratorKeyActivated;
|
||||
Window.Current.CoreWindow.PointerPressed -=
|
||||
this.CoreWindow_PointerPressed;
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
#region Navigation support
|
||||
|
||||
RelayCommand _goBackCommand;
|
||||
RelayCommand _goForwardCommand;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="RelayCommand"/> used to bind to the back Button's Command property
|
||||
/// for navigating to the most recent item in back navigation history, if a Frame
|
||||
/// manages its own navigation history.
|
||||
///
|
||||
/// The <see cref="RelayCommand"/> is set up to use the virtual method <see cref="GoBack"/>
|
||||
/// as the Execute Action and <see cref="CanGoBack"/> for CanExecute.
|
||||
/// </summary>
|
||||
public RelayCommand GoBackCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_goBackCommand == null)
|
||||
{
|
||||
_goBackCommand = new RelayCommand(
|
||||
() => this.GoBack(),
|
||||
() => this.CanGoBack());
|
||||
}
|
||||
return _goBackCommand;
|
||||
}
|
||||
set
|
||||
{
|
||||
_goBackCommand = value;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// <see cref="RelayCommand"/> used for navigating to the most recent item in
|
||||
/// the forward navigation history, if a Frame manages its own navigation history.
|
||||
///
|
||||
/// The <see cref="RelayCommand"/> is set up to use the virtual method <see cref="GoForward"/>
|
||||
/// as the Execute Action and <see cref="CanGoForward"/> for CanExecute.
|
||||
/// </summary>
|
||||
public RelayCommand GoForwardCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_goForwardCommand == null)
|
||||
{
|
||||
_goForwardCommand = new RelayCommand(
|
||||
() => this.GoForward(),
|
||||
() => this.CanGoForward());
|
||||
}
|
||||
return _goForwardCommand;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Virtual method used by the <see cref="GoBackCommand"/> property
|
||||
/// to determine if the <see cref="Frame"/> can go back.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// true if the <see cref="Frame"/> has at least one entry
|
||||
/// in the back navigation history.
|
||||
/// </returns>
|
||||
public virtual bool CanGoBack()
|
||||
{
|
||||
return this.Frame != null && this.Frame.CanGoBack;
|
||||
}
|
||||
/// <summary>
|
||||
/// Virtual method used by the <see cref="GoForwardCommand"/> property
|
||||
/// to determine if the <see cref="Frame"/> can go forward.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// true if the <see cref="Frame"/> has at least one entry
|
||||
/// in the forward navigation history.
|
||||
/// </returns>
|
||||
public virtual bool CanGoForward()
|
||||
{
|
||||
return this.Frame != null && this.Frame.CanGoForward;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Virtual method used by the <see cref="GoBackCommand"/> property
|
||||
/// to invoke the <see cref="Windows.UI.Xaml.Controls.Frame.GoBack"/> method.
|
||||
/// </summary>
|
||||
public virtual void GoBack()
|
||||
{
|
||||
if (this.Frame != null && this.Frame.CanGoBack) this.Frame.GoBack();
|
||||
}
|
||||
/// <summary>
|
||||
/// Virtual method used by the <see cref="GoForwardCommand"/> property
|
||||
/// to invoke the <see cref="Windows.UI.Xaml.Controls.Frame.GoForward"/> method.
|
||||
/// </summary>
|
||||
public virtual void GoForward()
|
||||
{
|
||||
if (this.Frame != null && this.Frame.CanGoForward) this.Frame.GoForward();
|
||||
}
|
||||
|
||||
#if WINDOWS_PHONE_APP
|
||||
/// <summary>
|
||||
/// Invoked when the hardware back button is pressed. For Windows Phone only.
|
||||
/// </summary>
|
||||
/// <param name="sender">Instance that triggered the event.</param>
|
||||
/// <param name="e">Event data describing the conditions that led to the event.</param>
|
||||
private void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
|
||||
{
|
||||
e.Handled = true;
|
||||
this.GoBackCommand.Execute(null);
|
||||
}
|
||||
#else
|
||||
/// <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="e">Event data describing the conditions that led to the event.</param>
|
||||
private void CoreDispatcher_AcceleratorKeyActivated(CoreDispatcher sender,
|
||||
AcceleratorKeyEventArgs e)
|
||||
{
|
||||
var virtualKey = e.VirtualKey;
|
||||
|
||||
// Only investigate further when Left, Right, or the dedicated Previous or Next keys
|
||||
// are pressed
|
||||
if ((e.EventType == CoreAcceleratorKeyEventType.SystemKeyDown ||
|
||||
e.EventType == CoreAcceleratorKeyEventType.KeyDown) &&
|
||||
(virtualKey == VirtualKey.Left || virtualKey == VirtualKey.Right ||
|
||||
(int)virtualKey == 166 || (int)virtualKey == 167))
|
||||
{
|
||||
var coreWindow = Window.Current.CoreWindow;
|
||||
var downState = 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
|
||||
e.Handled = true;
|
||||
this.GoBackCommand.Execute(null);
|
||||
}
|
||||
else if (((int)virtualKey == 167 && noModifiers) ||
|
||||
(virtualKey == VirtualKey.Right && onlyAlt))
|
||||
{
|
||||
// When the next key or Alt+Right are pressed navigate forward
|
||||
e.Handled = true;
|
||||
this.GoForwardCommand.Execute(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <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="e">Event data describing the conditions that led to the event.</param>
|
||||
private void CoreWindow_PointerPressed(CoreWindow sender,
|
||||
PointerEventArgs e)
|
||||
{
|
||||
var properties = e.CurrentPoint.Properties;
|
||||
|
||||
// Ignore button chords with the left, right, and middle buttons
|
||||
if (properties.IsLeftButtonPressed || properties.IsRightButtonPressed ||
|
||||
properties.IsMiddleButtonPressed) return;
|
||||
|
||||
// If back or foward are pressed (but not both) navigate appropriately
|
||||
bool backPressed = properties.IsXButton1Pressed;
|
||||
bool forwardPressed = properties.IsXButton2Pressed;
|
||||
if (backPressed ^ forwardPressed)
|
||||
{
|
||||
e.Handled = true;
|
||||
if (backPressed) this.GoBackCommand.Execute(null);
|
||||
if (forwardPressed) this.GoForwardCommand.Execute(null);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
|
||||
#region Process lifetime management
|
||||
|
||||
private String _pageKey;
|
||||
|
||||
/// <summary>
|
||||
/// Register this event on the current page to populate the page
|
||||
/// with content passed during navigation as well as any saved
|
||||
/// state provided when recreating a page from a prior session.
|
||||
/// </summary>
|
||||
public event LoadStateEventHandler LoadState;
|
||||
/// <summary>
|
||||
/// Register this event on the current page to preserve
|
||||
/// state associated with the current page in case the
|
||||
/// application is suspended or the page is discarded from
|
||||
/// the navigaqtion cache.
|
||||
/// </summary>
|
||||
public event SaveStateEventHandler SaveState;
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when this page is about to be displayed in a Frame.
|
||||
/// This method calls <see cref="LoadState"/>, where all page specific
|
||||
/// navigation and process lifetime management logic should be placed.
|
||||
/// </summary>
|
||||
/// <param name="e">Event data that describes how this page was reached. The Parameter
|
||||
/// property provides the group to be displayed.</param>
|
||||
public void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
var frameState = SuspensionManager.SessionStateForFrame(this.Frame);
|
||||
this._pageKey = "Page-" + this.Frame.BackStackDepth;
|
||||
|
||||
if (e.NavigationMode == NavigationMode.New)
|
||||
{
|
||||
// Clear existing state for forward navigation when adding a new page to the
|
||||
// navigation stack
|
||||
var nextPageKey = this._pageKey;
|
||||
int nextPageIndex = this.Frame.BackStackDepth;
|
||||
while (frameState.Remove(nextPageKey))
|
||||
{
|
||||
nextPageIndex++;
|
||||
nextPageKey = "Page-" + nextPageIndex;
|
||||
}
|
||||
|
||||
// Pass the navigation parameter to the new page
|
||||
if (this.LoadState != null)
|
||||
{
|
||||
this.LoadState(this, new LoadStateEventArgs(e.Parameter, null));
|
||||
}
|
||||
}
|
||||
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
|
||||
if (this.LoadState != null)
|
||||
{
|
||||
this.LoadState(this, new LoadStateEventArgs(e.Parameter, (Dictionary<String, Object>)frameState[this._pageKey]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when this page will no longer be displayed in a Frame.
|
||||
/// This method calls <see cref="SaveState"/>, where all page specific
|
||||
/// navigation and process lifetime management logic should be placed.
|
||||
/// </summary>
|
||||
/// <param name="e">Event data that describes how this page was reached. The Parameter
|
||||
/// property provides the group to be displayed.</param>
|
||||
public void OnNavigatedFrom(NavigationEventArgs e)
|
||||
{
|
||||
var frameState = SuspensionManager.SessionStateForFrame(this.Frame);
|
||||
var pageState = new Dictionary<String, Object>();
|
||||
if (this.SaveState != null)
|
||||
{
|
||||
this.SaveState(this, new SaveStateEventArgs(pageState));
|
||||
}
|
||||
frameState[_pageKey] = pageState;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the method that will handle the <see cref="NavigationHelper.LoadState"/>event
|
||||
/// </summary>
|
||||
public delegate void LoadStateEventHandler(object sender, LoadStateEventArgs e);
|
||||
/// <summary>
|
||||
/// Represents the method that will handle the <see cref="NavigationHelper.SaveState"/>event
|
||||
/// </summary>
|
||||
public delegate void SaveStateEventHandler(object sender, SaveStateEventArgs e);
|
||||
|
||||
/// <summary>
|
||||
/// Class used to hold the event data required when a page attempts to load state.
|
||||
/// </summary>
|
||||
public class LoadStateEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// The parameter value passed to <see cref="Frame.Navigate(Type, Object)"/>
|
||||
/// when this page was initially requested.
|
||||
/// </summary>
|
||||
public Object NavigationParameter { get; private set; }
|
||||
/// <summary>
|
||||
/// A dictionary of state preserved by this page during an earlier
|
||||
/// session. This will be null the first time a page is visited.
|
||||
/// </summary>
|
||||
public Dictionary<string, Object> PageState { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LoadStateEventArgs"/> class.
|
||||
/// </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 dictionary of state preserved by this page during an earlier
|
||||
/// session. This will be null the first time a page is visited.
|
||||
/// </param>
|
||||
public LoadStateEventArgs(Object navigationParameter, Dictionary<string, Object> pageState)
|
||||
: base()
|
||||
{
|
||||
this.NavigationParameter = navigationParameter;
|
||||
this.PageState = pageState;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Class used to hold the event data required when a page attempts to save state.
|
||||
/// </summary>
|
||||
public class SaveStateEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty dictionary to be populated with serializable state.
|
||||
/// </summary>
|
||||
public Dictionary<string, Object> PageState { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SaveStateEventArgs"/> class.
|
||||
/// </summary>
|
||||
/// <param name="pageState">An empty dictionary to be populated with serializable state.</param>
|
||||
public SaveStateEventArgs(Dictionary<string, Object> pageState)
|
||||
: base()
|
||||
{
|
||||
this.PageState = pageState;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Windows.Foundation.Collections;
|
||||
|
||||
namespace ImageSequencer.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Implementation of IObservableMap that supports reentrancy for use as a default view
|
||||
/// model.
|
||||
/// </summary>
|
||||
public class ObservableDictionary : IObservableMap<string, object>
|
||||
{
|
||||
private class ObservableDictionaryChangedEventArgs : IMapChangedEventArgs<string>
|
||||
{
|
||||
public ObservableDictionaryChangedEventArgs(CollectionChange change, string key)
|
||||
{
|
||||
this.CollectionChange = change;
|
||||
this.Key = key;
|
||||
}
|
||||
|
||||
public CollectionChange CollectionChange { get; private set; }
|
||||
public string Key { get; private set; }
|
||||
}
|
||||
|
||||
private Dictionary<string, object> _dictionary = new Dictionary<string, object>();
|
||||
public event MapChangedEventHandler<string, object> MapChanged;
|
||||
|
||||
private void InvokeMapChanged(CollectionChange change, string key)
|
||||
{
|
||||
var eventHandler = MapChanged;
|
||||
if (eventHandler != null)
|
||||
{
|
||||
eventHandler(this, new ObservableDictionaryChangedEventArgs(change, key));
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(string key, object value)
|
||||
{
|
||||
this._dictionary.Add(key, value);
|
||||
this.InvokeMapChanged(CollectionChange.ItemInserted, key);
|
||||
}
|
||||
|
||||
public void Add(KeyValuePair<string, object> item)
|
||||
{
|
||||
this.Add(item.Key, item.Value);
|
||||
}
|
||||
|
||||
public bool Remove(string key)
|
||||
{
|
||||
if (this._dictionary.Remove(key))
|
||||
{
|
||||
this.InvokeMapChanged(CollectionChange.ItemRemoved, key);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Remove(KeyValuePair<string, object> item)
|
||||
{
|
||||
object currentValue;
|
||||
if (this._dictionary.TryGetValue(item.Key, out currentValue) &&
|
||||
Object.Equals(item.Value, currentValue) && this._dictionary.Remove(item.Key))
|
||||
{
|
||||
this.InvokeMapChanged(CollectionChange.ItemRemoved, item.Key);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public object this[string key]
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._dictionary[key];
|
||||
}
|
||||
set
|
||||
{
|
||||
this._dictionary[key] = value;
|
||||
this.InvokeMapChanged(CollectionChange.ItemChanged, key);
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
var priorKeys = this._dictionary.Keys.ToArray();
|
||||
this._dictionary.Clear();
|
||||
foreach (var key in priorKeys)
|
||||
{
|
||||
this.InvokeMapChanged(CollectionChange.ItemRemoved, key);
|
||||
}
|
||||
}
|
||||
|
||||
public ICollection<string> Keys
|
||||
{
|
||||
get { return this._dictionary.Keys; }
|
||||
}
|
||||
|
||||
public bool ContainsKey(string key)
|
||||
{
|
||||
return this._dictionary.ContainsKey(key);
|
||||
}
|
||||
|
||||
public bool TryGetValue(string key, out object value)
|
||||
{
|
||||
return this._dictionary.TryGetValue(key, out value);
|
||||
}
|
||||
|
||||
public ICollection<object> Values
|
||||
{
|
||||
get { return this._dictionary.Values; }
|
||||
}
|
||||
|
||||
public bool Contains(KeyValuePair<string, object> item)
|
||||
{
|
||||
return this._dictionary.Contains(item);
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return this._dictionary.Count; }
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
|
||||
{
|
||||
return this._dictionary.GetEnumerator();
|
||||
}
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
||||
{
|
||||
return this._dictionary.GetEnumerator();
|
||||
}
|
||||
|
||||
public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
|
||||
{
|
||||
int arraySize = array.Length;
|
||||
foreach (var pair in this._dictionary)
|
||||
{
|
||||
if (arrayIndex >= arraySize) break;
|
||||
array[arrayIndex++] = pair;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
The Common directory contains classes that simplify application development.
|
||||
|
||||
Classes in the Common directory form part of your project and may be further enhanced to meet your
|
||||
needs. Care should be taken when altering existing methods and properties as incompatible changes
|
||||
will require corresponding changes to code included in a variety of Visual Studio templates. For
|
||||
example, additional pages added to your project are written assuming that the original methods and
|
||||
properties in Common classes are still present and that the names of the types have not changed.
|
|
@ -0,0 +1,86 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace ImageSequencer.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// A command whose sole purpose is to relay its functionality
|
||||
/// to other objects by invoking delegates.
|
||||
/// The default return value for the CanExecute method is 'true'.
|
||||
/// <see cref="RaiseCanExecuteChanged"/> needs to be called whenever
|
||||
/// <see cref="CanExecute"/> is expected to return a different value.
|
||||
/// </summary>
|
||||
public class RelayCommand : ICommand
|
||||
{
|
||||
private readonly Action _execute;
|
||||
private readonly Func<bool> _canExecute;
|
||||
|
||||
/// <summary>
|
||||
/// Raised when RaiseCanExecuteChanged is called.
|
||||
/// </summary>
|
||||
public event EventHandler CanExecuteChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new command that can always execute.
|
||||
/// </summary>
|
||||
/// <param name="execute">The execution logic.</param>
|
||||
public RelayCommand(Action execute)
|
||||
: this(execute, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new command.
|
||||
/// </summary>
|
||||
/// <param name="execute">The execution logic.</param>
|
||||
/// <param name="canExecute">The execution status logic.</param>
|
||||
public RelayCommand(Action execute, Func<bool> canExecute)
|
||||
{
|
||||
if (execute == null)
|
||||
throw new ArgumentNullException("execute");
|
||||
_execute = execute;
|
||||
_canExecute = canExecute;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this <see cref="RelayCommand"/> can execute in its current state.
|
||||
/// </summary>
|
||||
/// <param name="parameter">
|
||||
/// Data used by the command. If the command does not require data to be passed, this object can be set to null.
|
||||
/// </param>
|
||||
/// <returns>true if this command can be executed; otherwise, false.</returns>
|
||||
public bool CanExecute(object parameter)
|
||||
{
|
||||
return _canExecute == null ? true : _canExecute();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes the <see cref="RelayCommand"/> on the current command target.
|
||||
/// </summary>
|
||||
/// <param name="parameter">
|
||||
/// Data used by the command. If the command does not require data to be passed, this object can be set to null.
|
||||
/// </param>
|
||||
public void Execute(object parameter)
|
||||
{
|
||||
_execute();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method used to raise the <see cref="CanExecuteChanged"/> event
|
||||
/// to indicate that the return value of the <see cref="CanExecute"/>
|
||||
/// method has changed.
|
||||
/// </summary>
|
||||
public void RaiseCanExecuteChanged()
|
||||
{
|
||||
var handler = CanExecuteChanged;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,269 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel;
|
||||
using Windows.Storage;
|
||||
using Windows.Storage.Streams;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
namespace ImageSequencer.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 discarded when an application crashes or is
|
||||
/// upgraded.
|
||||
/// </summary>
|
||||
internal sealed class SuspensionManager
|
||||
{
|
||||
private static Dictionary<string, object> _sessionState = new Dictionary<string, object>();
|
||||
private static List<Type> _knownTypes = new List<Type>();
|
||||
private const string sessionStateFilename = "_sessionState.xml";
|
||||
|
||||
/// <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"/>, so values must be serializable by
|
||||
/// <see cref="DataContractSerializer"/> and should be as compact as possible. Strings
|
||||
/// and other self-contained data types are strongly recommended.
|
||||
/// </summary>
|
||||
public static Dictionary<string, object> SessionState
|
||||
{
|
||||
get { return _sessionState; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List of custom types provided to the <see cref="DataContractSerializer"/> when
|
||||
/// reading and writing session state. Initially empty, additional types may be
|
||||
/// added to customize the serialization process.
|
||||
/// </summary>
|
||||
public static List<Type> KnownTypes
|
||||
{
|
||||
get { return _knownTypes; }
|
||||
}
|
||||
|
||||
/// <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>
|
||||
public static async Task SaveAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Save the navigation state for all registered frames
|
||||
foreach (var weakFrameReference in _registeredFrames)
|
||||
{
|
||||
Frame frame;
|
||||
if (weakFrameReference.TryGetTarget(out frame))
|
||||
{
|
||||
SaveFrameNavigationState(frame);
|
||||
}
|
||||
}
|
||||
|
||||
// Serialize the session state synchronously to avoid asynchronous access to shared
|
||||
// state
|
||||
MemoryStream sessionData = new MemoryStream();
|
||||
DataContractSerializer serializer = new DataContractSerializer(typeof(Dictionary<string, object>), _knownTypes);
|
||||
serializer.WriteObject(sessionData, _sessionState);
|
||||
|
||||
// Get an output stream for the SessionState file and write the state asynchronously
|
||||
StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(sessionStateFilename, CreationCollisionOption.ReplaceExisting);
|
||||
using (Stream fileStream = await file.OpenStreamForWriteAsync())
|
||||
{
|
||||
sessionData.Seek(0, SeekOrigin.Begin);
|
||||
await sessionData.CopyToAsync(fileStream);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new SuspensionManagerException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <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="sessionBaseKey">An optional key that identifies the type of session.
|
||||
/// This can be used to distinguish between multiple application launch scenarios.</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>
|
||||
public static async Task RestoreAsync(String sessionBaseKey = null)
|
||||
{
|
||||
_sessionState = new Dictionary<String, Object>();
|
||||
|
||||
try
|
||||
{
|
||||
// Get the input stream for the SessionState file
|
||||
StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync(sessionStateFilename);
|
||||
using (IInputStream inStream = await file.OpenSequentialReadAsync())
|
||||
{
|
||||
// Deserialize the Session State
|
||||
DataContractSerializer serializer = new DataContractSerializer(typeof(Dictionary<string, object>), _knownTypes);
|
||||
_sessionState = (Dictionary<string, object>)serializer.ReadObject(inStream.AsStreamForRead());
|
||||
}
|
||||
|
||||
// Restore any registered frames to their saved state
|
||||
foreach (var weakFrameReference in _registeredFrames)
|
||||
{
|
||||
Frame frame;
|
||||
if (weakFrameReference.TryGetTarget(out frame) && (string)frame.GetValue(FrameSessionBaseKeyProperty) == sessionBaseKey)
|
||||
{
|
||||
frame.ClearValue(FrameSessionStateProperty);
|
||||
RestoreFrameNavigationState(frame);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new SuspensionManagerException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static DependencyProperty FrameSessionStateKeyProperty =
|
||||
DependencyProperty.RegisterAttached("_FrameSessionStateKey", typeof(String), typeof(SuspensionManager), null);
|
||||
private static DependencyProperty FrameSessionBaseKeyProperty =
|
||||
DependencyProperty.RegisterAttached("_FrameSessionBaseKeyParams", typeof(String), typeof(SuspensionManager), null);
|
||||
private static DependencyProperty FrameSessionStateProperty =
|
||||
DependencyProperty.RegisterAttached("_FrameSessionState", typeof(Dictionary<String, Object>), typeof(SuspensionManager), null);
|
||||
private static List<WeakReference<Frame>> _registeredFrames = new List<WeakReference<Frame>>();
|
||||
|
||||
/// <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"/> 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>
|
||||
/// <param name="sessionBaseKey">An optional key that identifies the type of session.
|
||||
/// This can be used to distinguish between multiple application launch scenarios.</param>
|
||||
public static void RegisterFrame(Frame frame, String sessionStateKey, String sessionBaseKey = null)
|
||||
{
|
||||
if (frame.GetValue(FrameSessionStateKeyProperty) != null)
|
||||
{
|
||||
throw new InvalidOperationException("Frames can only be registered to one session state key");
|
||||
}
|
||||
|
||||
if (frame.GetValue(FrameSessionStateProperty) != null)
|
||||
{
|
||||
throw new InvalidOperationException("Frames must be either be registered before accessing frame session state, or not registered at all");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(sessionBaseKey))
|
||||
{
|
||||
frame.SetValue(FrameSessionBaseKeyProperty, sessionBaseKey);
|
||||
sessionStateKey = sessionBaseKey + "_" + sessionStateKey;
|
||||
}
|
||||
|
||||
// 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.Add(new WeakReference<Frame>(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>
|
||||
public static void 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)
|
||||
SessionState.Remove((String)frame.GetValue(FrameSessionStateKeyProperty));
|
||||
_registeredFrames.RemoveAll((weakFrameReference) =>
|
||||
{
|
||||
Frame testFrame;
|
||||
return !weakFrameReference.TryGetTarget(out testFrame) || testFrame == frame;
|
||||
});
|
||||
}
|
||||
|
||||
/// <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="NavigationHelper"/> 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>
|
||||
public static Dictionary<String, Object> SessionStateForFrame(Frame frame)
|
||||
{
|
||||
var frameState = (Dictionary<String, Object>)frame.GetValue(FrameSessionStateProperty);
|
||||
|
||||
if (frameState == null)
|
||||
{
|
||||
var frameSessionKey = (String)frame.GetValue(FrameSessionStateKeyProperty);
|
||||
if (frameSessionKey != null)
|
||||
{
|
||||
// Registered frames reflect the corresponding session state
|
||||
if (!_sessionState.ContainsKey(frameSessionKey))
|
||||
{
|
||||
_sessionState[frameSessionKey] = new Dictionary<String, Object>();
|
||||
}
|
||||
frameState = (Dictionary<String, Object>)_sessionState[frameSessionKey];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Frames that aren't registered have transient state
|
||||
frameState = new Dictionary<String, Object>();
|
||||
}
|
||||
frame.SetValue(FrameSessionStateProperty, frameState);
|
||||
}
|
||||
return frameState;
|
||||
}
|
||||
|
||||
private static void RestoreFrameNavigationState(Frame frame)
|
||||
{
|
||||
var frameState = SessionStateForFrame(frame);
|
||||
if (frameState.ContainsKey("Navigation"))
|
||||
{
|
||||
frame.SetNavigationState((String)frameState["Navigation"]);
|
||||
}
|
||||
}
|
||||
|
||||
private static void SaveFrameNavigationState(Frame frame)
|
||||
{
|
||||
var frameState = SessionStateForFrame(frame);
|
||||
frameState["Navigation"] = frame.GetNavigationState();
|
||||
}
|
||||
}
|
||||
public class SuspensionManagerException : Exception
|
||||
{
|
||||
public SuspensionManagerException()
|
||||
{
|
||||
}
|
||||
|
||||
public SuspensionManagerException(Exception e)
|
||||
: base("SuspensionManager failed", e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
using Nokia.Graphics.Imaging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using System.IO;
|
||||
using Nokia.InteropServices.WindowsRuntime;
|
||||
using System.Threading;
|
||||
using Windows.Storage;
|
||||
using Windows.Foundation;
|
||||
using Windows.UI.Xaml.Media.Imaging;
|
||||
using Windows.UI.Xaml.Shapes;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI;
|
||||
|
||||
namespace ImageSequencer
|
||||
{
|
||||
class GifExporter
|
||||
{
|
||||
|
||||
public static async Task Export(IReadOnlyList<IImageProvider> images, Rect? animatedArea)
|
||||
{
|
||||
// List of aligned images may contain Null items if the particular image couldn't be aligned
|
||||
List<IImageProvider> sanitizedImages = new List<IImageProvider>();
|
||||
foreach (IImageProvider image in images) {
|
||||
if (image != null) {
|
||||
sanitizedImages.Add(image);
|
||||
}
|
||||
}
|
||||
|
||||
ImageProviderInfo info = await sanitizedImages[0].GetInfoAsync();
|
||||
int w = (int)info.ImageSize.Width;
|
||||
int h = (int)info.ImageSize.Height;
|
||||
|
||||
IReadOnlyList<IImageProvider> gifRendererSources;
|
||||
if (animatedArea.HasValue)
|
||||
{
|
||||
// Ensure the animated area dimensions are smaller than the image dimensions
|
||||
double rectW = animatedArea.Value.Width;
|
||||
double rectH = animatedArea.Value.Height;
|
||||
if ((animatedArea.Value.Width + animatedArea.Value.Left) >= w)
|
||||
{
|
||||
rectW = w - animatedArea.Value.Left - 1;
|
||||
}
|
||||
if ((animatedArea.Value.Top + animatedArea.Value.Height) >= h)
|
||||
{
|
||||
rectH = h - animatedArea.Value.Top - 1;
|
||||
}
|
||||
|
||||
Rect rect = new Rect(animatedArea.Value.Left, animatedArea.Value.Top, rectW, rectH);
|
||||
gifRendererSources = CreateFramedAnimation(sanitizedImages, rect, w, h);
|
||||
}
|
||||
else
|
||||
{
|
||||
gifRendererSources = sanitizedImages;
|
||||
}
|
||||
|
||||
using (GifRenderer gifRenderer = new GifRenderer())
|
||||
{
|
||||
gifRenderer.Duration = 100;
|
||||
gifRenderer.NumberOfAnimationLoops = 10000;
|
||||
gifRenderer.Sources = gifRendererSources;
|
||||
|
||||
var buffer = await gifRenderer.RenderAsync();
|
||||
|
||||
var filename = "Sequence" + (await GetFileNameRunningNumber()) + ".gif";
|
||||
var storageFile = await KnownFolders.SavedPictures.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
|
||||
using (var stream = await storageFile.OpenAsync(FileAccessMode.ReadWrite))
|
||||
{
|
||||
await stream.WriteAsync(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static IReadOnlyList<IImageProvider> CreateFramedAnimation(IReadOnlyList<IImageProvider> images, Rect animationBounds, int w, int h)
|
||||
{
|
||||
List<IImageProvider> framedAnimation = new List<IImageProvider>();
|
||||
|
||||
foreach (IImageProvider frame in images)
|
||||
{
|
||||
FilterEffect cropFilterEffect = new FilterEffect(frame);
|
||||
cropFilterEffect.Filters = new List<IFilter>() { new CropFilter(animationBounds) };
|
||||
|
||||
FilterEffect blendFilterEffect = new FilterEffect(images[0]);
|
||||
BlendFilter blendFilter = new BlendFilter();
|
||||
blendFilter.ForegroundSource = cropFilterEffect;
|
||||
blendFilter.Level = 1.0;
|
||||
blendFilter.BlendFunction = BlendFunction.Normal;
|
||||
blendFilter.TargetArea = new Rect(
|
||||
animationBounds.Left / w,
|
||||
animationBounds.Top / h,
|
||||
animationBounds.Width / w,
|
||||
animationBounds.Height / h
|
||||
);
|
||||
blendFilterEffect.Filters = new List<IFilter>() { blendFilter };
|
||||
|
||||
framedAnimation.Add(blendFilterEffect);
|
||||
}
|
||||
|
||||
return framedAnimation;
|
||||
}
|
||||
|
||||
private static async Task<int> GetFileNameRunningNumber()
|
||||
{
|
||||
var files = await KnownFolders.SavedPictures.GetFilesAsync();
|
||||
int max = 0;
|
||||
foreach (StorageFile storageFile in files)
|
||||
{
|
||||
var pattern = "Sequence\\d+\\.gif";
|
||||
if (System.Text.RegularExpressions.Regex.IsMatch(storageFile.Name, pattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase))
|
||||
{
|
||||
max = Math.Max(max, Convert.ToInt32(storageFile.Name.Split('.')[0].Substring(8)));
|
||||
}
|
||||
}
|
||||
|
||||
return max + 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<Page
|
||||
x:Class="ImageSequencer.GifPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:ImageSequencer"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:animgif="using:TriGemini.Controls"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid Margin="24,17,0,8">
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Grid.Row="0">
|
||||
<TextBlock Text="IMAGE SEQUENCER" Style="{ThemeResource TitleTextBlockStyle}"
|
||||
Typography.Capitals="SmallCaps"/>
|
||||
<TextBlock x:Name="FileNameTextBlock" Style="{ThemeResource HeaderTextBlockStyle}"/>
|
||||
</StackPanel>
|
||||
|
||||
<Image Grid.Row="1" x:Name="GifImage" Margin="-24,0,0,0"></Image>
|
||||
|
||||
</Grid>
|
||||
|
||||
<Page.BottomAppBar>
|
||||
<CommandBar>
|
||||
<AppBarButton x:Name="DeleteButton" IsEnabled="False" Icon="Delete" Label="Delete" Click="DeleteButton_Click"/>
|
||||
<CommandBar.SecondaryCommands>
|
||||
<AppBarButton x:Name="AboutButton" Label="About" Icon="Help" Click="About_Click"/>
|
||||
</CommandBar.SecondaryCommands>
|
||||
</CommandBar>
|
||||
</Page.BottomAppBar>
|
||||
</Page>
|
|
@ -0,0 +1,142 @@
|
|||
/**
|
||||
* Copyright (c) 2013-2014 Microsoft Mobile.
|
||||
* See the license file delivered with this project for more information.
|
||||
*/
|
||||
|
||||
using ImageSequencer.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel.Core;
|
||||
using Windows.Graphics.Imaging;
|
||||
using Windows.Storage;
|
||||
using Windows.UI.Core;
|
||||
using Windows.UI.ViewManagement;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Media.Imaging;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
namespace ImageSequencer
|
||||
{
|
||||
|
||||
public sealed partial class GifPage : Page
|
||||
{
|
||||
private NavigationHelper _navigationHelper;
|
||||
private List<WriteableBitmap> _frames;
|
||||
private int _currentFrameIndex = 0;
|
||||
private String filename;
|
||||
private DispatcherTimer timer;
|
||||
|
||||
public GifPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
_navigationHelper = new NavigationHelper(this);
|
||||
timer = new DispatcherTimer();
|
||||
timer.Interval = new TimeSpan(0, 0, 0, 0, 100);
|
||||
timer.Tick += Timer_Tick;
|
||||
}
|
||||
|
||||
protected override async void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
_frames = new List<WriteableBitmap>();
|
||||
filename = e.Parameter as String;
|
||||
FileNameTextBlock.Text = filename;
|
||||
ProgressBarHelper.ShowProgressBar("Loading GIF");
|
||||
await LoadImage(filename);
|
||||
}
|
||||
|
||||
protected override void OnNavigatedFrom(NavigationEventArgs e)
|
||||
{
|
||||
timer.Stop();
|
||||
ProgressBarHelper.HideProgressBar();
|
||||
base.OnNavigatedFrom(e);
|
||||
}
|
||||
|
||||
private void StartAnimation()
|
||||
{
|
||||
DeleteButton.IsEnabled = true;
|
||||
timer.Start();
|
||||
ProgressBarHelper.HideProgressBar();
|
||||
}
|
||||
|
||||
private void Timer_Tick(object sender, object e)
|
||||
{
|
||||
GifImage.Source = _frames[_currentFrameIndex];
|
||||
|
||||
_currentFrameIndex++;
|
||||
if (_currentFrameIndex >= _frames.Count())
|
||||
{
|
||||
_currentFrameIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task LoadImage(String filename)
|
||||
{
|
||||
var storageFile = await KnownFolders.SavedPictures.GetFileAsync(filename);
|
||||
|
||||
using (var res = await storageFile.OpenAsync(FileAccessMode.Read))
|
||||
{
|
||||
var bitmapDecoder = await BitmapDecoder.CreateAsync(BitmapDecoder.GifDecoderId, res);
|
||||
|
||||
byte[] firstFrame = null;
|
||||
|
||||
for (uint frameIndex = 0; frameIndex < bitmapDecoder.FrameCount; frameIndex++)
|
||||
{
|
||||
var frame = await bitmapDecoder.GetFrameAsync(frameIndex);
|
||||
|
||||
var writeableBitmap = new WriteableBitmap((int)bitmapDecoder.OrientedPixelWidth, (int)bitmapDecoder.OrientedPixelHeight);
|
||||
|
||||
var pixelData = await frame.GetPixelDataAsync(
|
||||
BitmapPixelFormat.Bgra8,
|
||||
BitmapAlphaMode.Straight,
|
||||
new BitmapTransform(),
|
||||
ExifOrientationMode.RespectExifOrientation,
|
||||
ColorManagementMode.DoNotColorManage);
|
||||
var bytes = pixelData.DetachPixelData();
|
||||
|
||||
if (firstFrame == null)
|
||||
{
|
||||
firstFrame = bytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Blend the frame on top of the first frame
|
||||
for (int i = 0; i < bytes.Count(); i += 4)
|
||||
{
|
||||
int alpha = bytes[i + 3];
|
||||
|
||||
if (alpha == 0 && firstFrame != null)
|
||||
{
|
||||
Array.Copy(firstFrame, i, bytes, i, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
using (var stream = writeableBitmap.PixelBuffer.AsStream())
|
||||
{
|
||||
stream.Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
_frames.Add(writeableBitmap);
|
||||
}
|
||||
}
|
||||
|
||||
StartAnimation();
|
||||
}
|
||||
|
||||
public async void DeleteButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var storageFile = await KnownFolders.SavedPictures.GetFileAsync(filename);
|
||||
await storageFile.DeleteAsync();
|
||||
_navigationHelper.GoBack();
|
||||
}
|
||||
|
||||
public void About_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Frame.Navigate(typeof(AboutPage));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||
<HasSharedItems>true</HasSharedItems>
|
||||
<SharedGUID>5f8cc95d-790c-4d28-a7fa-8d9c08d6bb25</SharedGUID>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration">
|
||||
<Import_RootNamespace>ImageSequencer</Import_RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="$(MSBuildThisFileDirectory)App.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)AboutPage.xaml.cs">
|
||||
<DependentUpon>AboutPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)App.xaml.cs">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Common\NavigationHelper.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Common\ObservableDictionary.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Common\RelayCommand.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Common\SuspensionManager.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)GifExporter.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)GifPage.xaml.cs">
|
||||
<DependentUpon>GifPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ProgressBarHelper.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)SequenceCapturePage.xaml.cs">
|
||||
<DependentUpon>SequenceCapturePage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)SequencePreviewPage.xaml.cs">
|
||||
<DependentUpon>SequencePreviewPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)SequencesPage.xaml.cs">
|
||||
<DependentUpon>SequencesPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)VideoPreviewCapturePage.xaml.cs">
|
||||
<DependentUpon>VideoPreviewCapturePage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="$(MSBuildThisFileDirectory)AboutPage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="$(MSBuildThisFileDirectory)GifPage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="$(MSBuildThisFileDirectory)SequenceCapturePage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="$(MSBuildThisFileDirectory)SequencePreviewPage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="$(MSBuildThisFileDirectory)SequencesPage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="$(MSBuildThisFileDirectory)VideoPreviewCapturePage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\appbar.align.disabled.png" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\appbar.align.enabled.png" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\appbar.frame.disabled.png" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\appbar.frame.enabled.png" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\appbar.sequence.capture.png" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.1.0.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.1.1.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.1.10.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.1.11.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.1.12.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.1.13.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.1.14.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.1.15.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.1.16.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.1.17.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.1.18.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.1.19.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.1.2.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.1.20.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.1.21.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.1.22.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.1.3.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.1.4.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.1.5.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.1.6.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.1.7.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.1.8.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.1.9.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.2.0.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.2.1.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.2.10.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.2.11.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.2.12.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.2.13.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.2.14.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.2.15.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.2.16.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.2.17.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.2.18.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.2.2.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.2.3.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.2.4.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.2.5.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.2.6.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.2.7.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.2.8.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\sequence.2.9.jpg" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Common\ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>5f8cc95d-790c-4d28-a7fa-8d9c08d6bb25</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
|
||||
<PropertyGroup />
|
||||
<Import Project="ImageSequencer.Shared.projitems" Label="Shared" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
|
||||
</Project>
|
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* Copyright (c) 2013-2014 Microsoft Mobile.
|
||||
* See the license file delivered with this project for more information.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Windows.ApplicationModel.Core;
|
||||
using Windows.UI.Core;
|
||||
using Windows.UI.ViewManagement;
|
||||
|
||||
namespace ImageSequencer
|
||||
{
|
||||
class ProgressBarHelper
|
||||
{
|
||||
#pragma warning disable 1998
|
||||
public static async void ShowProgressBar(String label)
|
||||
{
|
||||
#if WINDOWS_PHONE_APP
|
||||
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
|
||||
async () =>
|
||||
{
|
||||
StatusBarProgressIndicator progressbar = StatusBar.GetForCurrentView().ProgressIndicator;
|
||||
progressbar.Text = label;
|
||||
await progressbar.ShowAsync();
|
||||
}
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
#pragma warning disable 1998
|
||||
public static async void HideProgressBar()
|
||||
{
|
||||
#if WINDOWS_PHONE_APP
|
||||
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
|
||||
async () =>
|
||||
{
|
||||
StatusBarProgressIndicator progressbar = StatusBar.GetForCurrentView().ProgressIndicator;
|
||||
await progressbar.HideAsync();
|
||||
}
|
||||
);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<Page
|
||||
x:Class="ImageSequencer.SequenceCapturePage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:ImageSequencer"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid>
|
||||
<CaptureElement Tapped="CaptureElement_Tapped" x:Name="captureElement"></CaptureElement>
|
||||
</Grid>
|
||||
|
||||
<Page.BottomAppBar>
|
||||
<CommandBar x:Name="CommandBar">
|
||||
<AppBarButton x:Name="CaptureButton" Label="Capture" Click="CaptureButton_Click">
|
||||
<AppBarButton.Icon>
|
||||
<BitmapIcon UriSource="/Assets/appbar.sequence.capture.png" />
|
||||
</AppBarButton.Icon>
|
||||
</AppBarButton>
|
||||
<CommandBar.SecondaryCommands>
|
||||
<AppBarButton x:Name="AboutButton" Label="About" Icon="Help" Click="About_Click"/>
|
||||
</CommandBar.SecondaryCommands>
|
||||
</CommandBar>
|
||||
</Page.BottomAppBar>
|
||||
|
||||
</Page>
|
|
@ -0,0 +1,182 @@
|
|||
/**
|
||||
* Copyright (c) 2013-2014 Microsoft Mobile.
|
||||
* See the license file delivered with this project for more information.
|
||||
*/
|
||||
|
||||
using ImageSequencer.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel.Core;
|
||||
using Windows.Devices.Enumeration;
|
||||
using Windows.Graphics.Display;
|
||||
using Windows.Media.Capture;
|
||||
using Windows.Media.MediaProperties;
|
||||
using Windows.Storage;
|
||||
using Windows.Storage.Streams;
|
||||
using Windows.UI.Core;
|
||||
using Windows.UI.ViewManagement;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
namespace ImageSequencer
|
||||
{
|
||||
|
||||
public sealed partial class SequenceCapturePage : Page
|
||||
{
|
||||
|
||||
private List<IRandomAccessStream> _capturedSequence;
|
||||
private MediaCapture _mediaCapture;
|
||||
private LowLagPhotoSequenceCapture _lowLagPhotoSequenceCapture;
|
||||
private Task _saveTask;
|
||||
private Boolean _recording = false;
|
||||
private List<StorageFile> _files = new List<StorageFile>();
|
||||
private int _fileIndex = 1;
|
||||
private NavigationHelper _navigationHelper;
|
||||
private const int AMOUNT_OF_FRAMES_IN_SEQUENCE = 20;
|
||||
|
||||
public SequenceCapturePage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
|
||||
_navigationHelper = new NavigationHelper(this);
|
||||
}
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
DisplayInformation.AutoRotationPreferences = DisplayOrientations.Landscape;
|
||||
|
||||
InitializeMediaCapture();
|
||||
|
||||
#if WINDOWS_PHONE_APP
|
||||
Windows.Phone.UI.Input.HardwareButtons.CameraPressed += HardwareButtons_CameraPressed;
|
||||
#endif
|
||||
}
|
||||
|
||||
protected override void OnNavigatedFrom(NavigationEventArgs e)
|
||||
{
|
||||
DisplayInformation.AutoRotationPreferences = DisplayOrientations.None;
|
||||
|
||||
base.OnNavigatedFrom(e);
|
||||
_mediaCapture.Dispose();
|
||||
#if WINDOWS_PHONE_APP
|
||||
Windows.Phone.UI.Input.HardwareButtons.CameraPressed -= HardwareButtons_CameraPressed;
|
||||
#endif
|
||||
}
|
||||
|
||||
private async void InitializeMediaCapture()
|
||||
{
|
||||
_capturedSequence = new List<IRandomAccessStream>();
|
||||
|
||||
_mediaCapture = new MediaCapture();
|
||||
|
||||
var devices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
|
||||
var backCamera = devices.FirstOrDefault(x => x.EnclosureLocation != null && x.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Back);
|
||||
|
||||
await _mediaCapture.InitializeAsync(new MediaCaptureInitializationSettings
|
||||
{
|
||||
StreamingCaptureMode = StreamingCaptureMode.Video,
|
||||
PhotoCaptureSource = PhotoCaptureSource.Auto,
|
||||
AudioDeviceId = string.Empty,
|
||||
VideoDeviceId = backCamera.Id
|
||||
});
|
||||
|
||||
captureElement.Source = _mediaCapture;
|
||||
await _mediaCapture.StartPreviewAsync();
|
||||
|
||||
var format = ImageEncodingProperties.CreateJpeg();
|
||||
format.Width = 640;
|
||||
format.Height = 480;
|
||||
|
||||
_lowLagPhotoSequenceCapture = await _mediaCapture.PrepareLowLagPhotoSequenceCaptureAsync(format);
|
||||
_lowLagPhotoSequenceCapture.PhotoCaptured += OnPhotoCaptured;
|
||||
}
|
||||
|
||||
public void OnPhotoCaptured(LowLagPhotoSequenceCapture s, PhotoCapturedEventArgs e)
|
||||
{
|
||||
if (_fileIndex < AMOUNT_OF_FRAMES_IN_SEQUENCE)
|
||||
{
|
||||
if (_saveTask == null)
|
||||
{
|
||||
_saveTask = Save(e.Frame, _fileIndex++);
|
||||
}
|
||||
else
|
||||
{
|
||||
_saveTask = _saveTask.ContinueWith(t => Save(e.Frame, _fileIndex++));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
StopSequenceCapture();
|
||||
}
|
||||
}
|
||||
|
||||
private async void ShowPreviewPage()
|
||||
{
|
||||
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
|
||||
() =>
|
||||
{
|
||||
Frame.Navigate(typeof(SequencePreviewPage), _files);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private async Task Save(IRandomAccessStream frame, int i)
|
||||
{
|
||||
var filename = "ImageSequencer." + i + ".jpg";
|
||||
var folder = Windows.Storage.ApplicationData.Current.TemporaryFolder;
|
||||
var storageFile = await folder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
|
||||
var stream = await storageFile.OpenAsync(FileAccessMode.ReadWrite);
|
||||
await RandomAccessStream.CopyAndCloseAsync(frame, stream);
|
||||
_files.Add(storageFile);
|
||||
}
|
||||
|
||||
public void CaptureElement_Tapped(object sender, RoutedEventArgs e)
|
||||
{
|
||||
StartStopCapture();
|
||||
}
|
||||
|
||||
public void CaptureButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
StartStopCapture();
|
||||
}
|
||||
|
||||
#if WINDOWS_PHONE_APP
|
||||
void HardwareButtons_CameraPressed(object sender, Windows.Phone.UI.Input.CameraEventArgs e)
|
||||
{
|
||||
StartStopCapture();
|
||||
}
|
||||
#endif
|
||||
|
||||
private async void StartStopCapture()
|
||||
{
|
||||
if (!_recording)
|
||||
{
|
||||
_recording = true;
|
||||
ProgressBarHelper.ShowProgressBar("Capturing");
|
||||
await _lowLagPhotoSequenceCapture.StartAsync();
|
||||
CaptureButton.Icon = new SymbolIcon(Symbol.Stop);
|
||||
}
|
||||
else
|
||||
{
|
||||
StopSequenceCapture();
|
||||
}
|
||||
}
|
||||
|
||||
public async void StopSequenceCapture()
|
||||
{
|
||||
_recording = false;
|
||||
await _lowLagPhotoSequenceCapture.FinishAsync();
|
||||
ProgressBarHelper.HideProgressBar();
|
||||
ShowPreviewPage();
|
||||
}
|
||||
|
||||
public void About_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Frame.Navigate(typeof(AboutPage));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
<Page
|
||||
x:Class="ImageSequencer.SequencePreviewPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:ImageSequencer"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid x:Name="RootGrid">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel x:Name="Header" Grid.Row="0" Margin="24">
|
||||
<TextBlock Text="IMAGE SEQUENCER" Style="{ThemeResource TitleTextBlockStyle}"
|
||||
Typography.Capitals="SmallCaps"/>
|
||||
<TextBlock Text="preview" Style="{ThemeResource HeaderTextBlockStyle}"/>
|
||||
</StackPanel>
|
||||
|
||||
<Canvas x:Name="Canvas" Grid.Row="1" ManipulationDelta="ImageElement_ManipulationDelta" ManipulationStarted="ImageElement_ManipulationStarted">
|
||||
<Image x:Name="ImageElementBackground"/>
|
||||
<Image x:Name="ImageElement"/>
|
||||
<Border x:Name="AnimatedAreaIndicator" BorderBrush="White" BorderThickness="2" Visibility="Collapsed"/>
|
||||
</Canvas>
|
||||
</Grid>
|
||||
|
||||
<Page.BottomAppBar>
|
||||
<CommandBar>
|
||||
<AppBarButton x:Name="playButton" IsEnabled="False" Icon="Pause" Label="Pause" Click="Play_Click"/>
|
||||
<AppBarButton x:Name="alignButton" IsEnabled="False" Label="Align" Click="AlignButton_Click">
|
||||
<AppBarButton.Icon>
|
||||
<BitmapIcon UriSource="/Assets/appbar.align.disabled.png" />
|
||||
</AppBarButton.Icon>
|
||||
</AppBarButton>
|
||||
<AppBarButton x:Name="frameButton" IsEnabled="False" Label="Frame" Click="FrameButton_Click">
|
||||
<AppBarButton.Icon>
|
||||
<BitmapIcon UriSource="/Assets/appbar.frame.disabled.png" />
|
||||
</AppBarButton.Icon>
|
||||
</AppBarButton>
|
||||
<AppBarButton x:Name="saveButton" IsEnabled="False" Click="SaveButton_Click" Icon="Save" Label="Save"/>
|
||||
<CommandBar.SecondaryCommands>
|
||||
<AppBarButton x:Name="AboutButton" Label="About" Icon="Help" Click="About_Click"/>
|
||||
</CommandBar.SecondaryCommands>
|
||||
</CommandBar>
|
||||
</Page.BottomAppBar>
|
||||
</Page>
|
|
@ -0,0 +1,452 @@
|
|||
/**
|
||||
* Copyright (c) 2013-2014 Microsoft Mobile.
|
||||
* See the license file delivered with this project for more information.
|
||||
*/
|
||||
|
||||
using ImageSequencer.Common;
|
||||
using Nokia.Graphics.Imaging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel.Core;
|
||||
using Windows.Foundation;
|
||||
using Windows.Storage;
|
||||
using Windows.UI.Core;
|
||||
using Windows.UI.ViewManagement;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Media.Imaging;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
namespace ImageSequencer
|
||||
{
|
||||
|
||||
public sealed partial class SequencePreviewPage : Page
|
||||
{
|
||||
|
||||
private IReadOnlyList<IImageProvider> _unalignedImageProviders;
|
||||
private IReadOnlyList<IImageProvider> _alignedImageProviders;
|
||||
private IReadOnlyList<IImageProvider> _onScreenImageProviders;
|
||||
|
||||
private int _unalignedImageWidth;
|
||||
private int _unalignedImageHeight;
|
||||
private int _alignedImageWidth;
|
||||
private int _alignedImageHeight;
|
||||
|
||||
private WriteableBitmap _foregroundBitmap;
|
||||
private WriteableBitmap _backgroundBitmap;
|
||||
|
||||
private RectangleGeometry _animatedArea;
|
||||
private bool _frameEnabled;
|
||||
private Point _dragStart;
|
||||
|
||||
private int _animationIndex = 0;
|
||||
private DispatcherTimer _animationTimer;
|
||||
private volatile Task _renderTask;
|
||||
|
||||
private NavigationHelper _navigationHelper;
|
||||
|
||||
public SequencePreviewPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
|
||||
_animationTimer = new DispatcherTimer();
|
||||
_animationTimer.Tick += AnimationTimer_Tick;
|
||||
_animationTimer.Interval = new TimeSpan(0, 0, 0, 0, 100);
|
||||
|
||||
_navigationHelper = new NavigationHelper(this);
|
||||
|
||||
// Hide page header on landscape orientation
|
||||
Window.Current.SizeChanged += ((s, e) => { Header.Visibility = (e.Size.Width > e.Size.Height) ? Visibility.Collapsed : Visibility.Visible; });
|
||||
Header.Visibility = Window.Current.Bounds.Width > Window.Current.Bounds.Height ? Visibility.Collapsed : Visibility.Visible;
|
||||
}
|
||||
|
||||
private void AdjustPreviewImageSizeAccordingToLayout()
|
||||
{
|
||||
int imageWidth = _onScreenImageProviders == _unalignedImageProviders ? _unalignedImageWidth : _alignedImageWidth;
|
||||
int imageHeight = _onScreenImageProviders == _unalignedImageProviders ? _unalignedImageHeight : _alignedImageHeight;
|
||||
|
||||
double aspectRatio = ((double)imageWidth) / imageHeight;
|
||||
|
||||
double w = RootGrid.ActualWidth;
|
||||
double h = w / aspectRatio;
|
||||
|
||||
if (h > RootGrid.ActualHeight)
|
||||
{
|
||||
w /= h / RootGrid.ActualHeight;
|
||||
h = RootGrid.ActualHeight;
|
||||
}
|
||||
|
||||
double scale = w / ImageElementBackground.Width;
|
||||
|
||||
ImageElement.Width = w;
|
||||
ImageElement.Height = h;
|
||||
ImageElementBackground.Width = w;
|
||||
ImageElementBackground.Height = h;
|
||||
|
||||
if (_animatedArea == null && imageWidth != 0 && imageHeight != 0)
|
||||
{
|
||||
_animatedArea = new RectangleGeometry();
|
||||
AnimatedAreaIndicator.Width = w;
|
||||
AnimatedAreaIndicator.Height = h;
|
||||
Canvas.SetLeft(AnimatedAreaIndicator, 0);
|
||||
Canvas.SetTop(AnimatedAreaIndicator, 0);
|
||||
_animatedArea.Rect = new Rect(0, 0, w, h);
|
||||
}
|
||||
else if (_animatedArea != null)
|
||||
{
|
||||
if (scale > 0)
|
||||
{
|
||||
Rect newAnimatedArea = new Rect(
|
||||
_animatedArea.Rect.Left * scale,
|
||||
_animatedArea.Rect.Top * scale,
|
||||
_animatedArea.Rect.Width * scale,
|
||||
_animatedArea.Rect.Height * scale);
|
||||
if (newAnimatedArea.Height + newAnimatedArea.Top >= h)
|
||||
{
|
||||
newAnimatedArea.Height = h - newAnimatedArea.Top;
|
||||
}
|
||||
|
||||
AnimatedAreaIndicator.Width = newAnimatedArea.Width;
|
||||
AnimatedAreaIndicator.Height = newAnimatedArea.Height;
|
||||
Canvas.SetLeft(AnimatedAreaIndicator, newAnimatedArea.Left);
|
||||
Canvas.SetTop(AnimatedAreaIndicator, newAnimatedArea.Top);
|
||||
_animatedArea.Rect = newAnimatedArea;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AdjustPreviewImageSizeAccordingToOrientation(object sender, SizeChangedEventArgs e)
|
||||
{
|
||||
AdjustPreviewImageSizeAccordingToLayout();
|
||||
}
|
||||
|
||||
protected override async void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
ProgressBarHelper.ShowProgressBar("Processing sequence");
|
||||
|
||||
// The image sources are provided as parameter
|
||||
List<IImageProvider> imageProviders = new List<IImageProvider>();
|
||||
|
||||
if (e.Parameter is List<StorageFile>) // Using list of files as source for sequence
|
||||
{
|
||||
var files = e.Parameter as List<StorageFile>;
|
||||
foreach (StorageFile storageFile in files)
|
||||
{
|
||||
imageProviders.Add(new StorageFileImageSource(storageFile));
|
||||
}
|
||||
}
|
||||
else if (e.Parameter is int) // Using bundled resources as source for sequence, list of files is created here
|
||||
{
|
||||
int sequenceId = (int)e.Parameter;
|
||||
int imageIndex = 0;
|
||||
List<StorageFile> files = new List<StorageFile>();
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var imageUri = new Uri("ms-appx:///Assets/sequence." + sequenceId + "." + imageIndex + ".jpg");
|
||||
StorageFile file = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(imageUri);
|
||||
var stream = await file.OpenReadAsync(); // only for checking if file exists
|
||||
stream.Dispose();
|
||||
imageProviders.Add(new StorageFileImageSource(file));
|
||||
imageIndex++;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Expected FileNotFoundException
|
||||
}
|
||||
}
|
||||
|
||||
await PrepareImageSequence(imageProviders);
|
||||
|
||||
Canvas.ManipulationMode = ManipulationModes.TranslateX | ManipulationModes.TranslateY;
|
||||
Canvas.ManipulationStarted += ImageElement_ManipulationStarted;
|
||||
Canvas.ManipulationDelta += ImageElement_ManipulationDelta;
|
||||
|
||||
SetControlsEnabled(true);
|
||||
|
||||
AdjustPreviewImageSizeAccordingToLayout();
|
||||
RootGrid.SizeChanged += AdjustPreviewImageSizeAccordingToOrientation;
|
||||
|
||||
_animationTimer.Start();
|
||||
|
||||
ProgressBarHelper.HideProgressBar();
|
||||
}
|
||||
|
||||
protected override void OnNavigatedFrom(NavigationEventArgs e)
|
||||
{
|
||||
_animationTimer.Stop();
|
||||
}
|
||||
|
||||
public async Task PrepareImageSequence(List<IImageProvider> imageProviders)
|
||||
{
|
||||
_unalignedImageProviders = imageProviders;
|
||||
_onScreenImageProviders = _unalignedImageProviders;
|
||||
|
||||
ImageProviderInfo info = await _unalignedImageProviders[0].GetInfoAsync();
|
||||
_unalignedImageWidth = (int)info.ImageSize.Width;
|
||||
_unalignedImageHeight = (int)info.ImageSize.Height;
|
||||
|
||||
using (ImageAligner imageAligner = new ImageAligner())
|
||||
{
|
||||
imageAligner.Sources = _unalignedImageProviders;
|
||||
imageAligner.ReferenceSource = _unalignedImageProviders[0];
|
||||
|
||||
try
|
||||
{
|
||||
_alignedImageProviders = await imageAligner.AlignAsync();
|
||||
info = await _alignedImageProviders[0].GetInfoAsync();
|
||||
_alignedImageWidth = (int)info.ImageSize.Width;
|
||||
_alignedImageHeight = (int)info.ImageSize.Height;
|
||||
await EnableAlign();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// If align fails, fail silently but don't enable the align button on UI
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AnimationTimer_Tick(object sender, object e)
|
||||
{
|
||||
Render(_onScreenImageProviders, _animationIndex);
|
||||
|
||||
if (_animationIndex == (_onScreenImageProviders.Count() - 1))
|
||||
{
|
||||
_animationIndex = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_animationIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
private void Render(IReadOnlyList<IImageProvider> imageProviders, int animationIndex, bool renderBackground = false)
|
||||
{
|
||||
if (_renderTask == null || _renderTask.IsCompleted)
|
||||
{
|
||||
_renderTask = DoRender(imageProviders, animationIndex, renderBackground);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DoRender(IReadOnlyList<IImageProvider> imageProviders, int animationIndex, bool renderBackground = false)
|
||||
{
|
||||
if (_onScreenImageProviders[animationIndex] != null)
|
||||
{
|
||||
int imageWidth = imageProviders == _unalignedImageProviders ? _unalignedImageWidth : _alignedImageWidth;
|
||||
int imageHeight = imageProviders == _unalignedImageProviders ? _unalignedImageHeight : _alignedImageHeight;
|
||||
|
||||
if (_foregroundBitmap == null || _foregroundBitmap.PixelWidth != imageWidth || _foregroundBitmap.PixelHeight != imageHeight)
|
||||
_foregroundBitmap = new WriteableBitmap(imageWidth, imageHeight);
|
||||
|
||||
using (WriteableBitmapRenderer writeableBitmapRenderer = new WriteableBitmapRenderer(imageProviders[animationIndex], _foregroundBitmap))
|
||||
{
|
||||
_foregroundBitmap = await writeableBitmapRenderer.RenderAsync();
|
||||
}
|
||||
|
||||
if (renderBackground)
|
||||
{
|
||||
if (_backgroundBitmap == null || _backgroundBitmap.PixelWidth != imageWidth || _backgroundBitmap.PixelHeight != imageHeight)
|
||||
_backgroundBitmap = new WriteableBitmap(imageWidth, imageHeight);
|
||||
|
||||
using (WriteableBitmapRenderer writeableBitmapRenderer = new WriteableBitmapRenderer(imageProviders[0], _backgroundBitmap))
|
||||
{
|
||||
_backgroundBitmap = await writeableBitmapRenderer.RenderAsync();
|
||||
}
|
||||
}
|
||||
|
||||
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
|
||||
() =>
|
||||
{
|
||||
_foregroundBitmap.Invalidate();
|
||||
ImageElement.Source = _foregroundBitmap;
|
||||
if (renderBackground)
|
||||
{
|
||||
_backgroundBitmap.Invalidate();
|
||||
ImageElementBackground.Source = _backgroundBitmap;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private async Task EnableAlign()
|
||||
{
|
||||
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
|
||||
() =>
|
||||
{
|
||||
alignButton.IsEnabled = true;
|
||||
});
|
||||
}
|
||||
|
||||
private void ImageElement_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
|
||||
{
|
||||
if (_frameEnabled)
|
||||
{
|
||||
|
||||
double x0 = Math.Min(e.Position.X, _dragStart.X);
|
||||
double x1 = Math.Max(e.Position.X, _dragStart.X);
|
||||
double y0 = Math.Min(e.Position.Y, _dragStart.Y);
|
||||
double y1 = Math.Max(e.Position.Y, _dragStart.Y);
|
||||
|
||||
x0 = Math.Max(x0, 0);
|
||||
x1 = Math.Min(x1, ImageElementBackground.ActualWidth);
|
||||
y0 = Math.Max(y0, 0);
|
||||
y1 = Math.Min(y1, ImageElementBackground.ActualHeight);
|
||||
|
||||
double width = x1 - x0;
|
||||
double height = y1 - y0;
|
||||
|
||||
Rect rect = new Rect(x0, y0, width, height);
|
||||
Canvas.SetLeft(AnimatedAreaIndicator, rect.X);
|
||||
Canvas.SetTop(AnimatedAreaIndicator, rect.Y);
|
||||
AnimatedAreaIndicator.Width = rect.Width;
|
||||
AnimatedAreaIndicator.Height = rect.Height;
|
||||
|
||||
_animatedArea.Rect = rect;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void ImageElement_ManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
|
||||
{
|
||||
_dragStart = new Point(e.Position.X, e.Position.Y);
|
||||
}
|
||||
|
||||
public void Play_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (_animationTimer.IsEnabled)
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
Play();
|
||||
}
|
||||
}
|
||||
|
||||
private void Stop()
|
||||
{
|
||||
_animationTimer.Stop();
|
||||
playButton.Icon = new SymbolIcon(Symbol.Play);
|
||||
}
|
||||
|
||||
private void Play()
|
||||
{
|
||||
_animationTimer.Start();
|
||||
playButton.Icon = new SymbolIcon(Symbol.Pause);
|
||||
}
|
||||
|
||||
private void AlignButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
bool isAligned = _onScreenImageProviders == _alignedImageProviders;
|
||||
|
||||
if (!isAligned)
|
||||
{
|
||||
_onScreenImageProviders = _alignedImageProviders;
|
||||
BitmapIcon icon = new BitmapIcon();
|
||||
icon.UriSource = new Uri("ms-appx:/Assets/appbar.align.enabled.png");
|
||||
alignButton.Icon = icon;
|
||||
}
|
||||
else
|
||||
{
|
||||
_onScreenImageProviders = _unalignedImageProviders;
|
||||
BitmapIcon icon = new BitmapIcon();
|
||||
icon.UriSource = new Uri("ms-appx:/Assets/appbar.align.disabled.png");
|
||||
alignButton.Icon = icon;
|
||||
}
|
||||
|
||||
Render(_onScreenImageProviders, _animationIndex, true);
|
||||
AdjustPreviewImageSizeAccordingToLayout();
|
||||
|
||||
saveButton.IsEnabled = true;
|
||||
}
|
||||
|
||||
private void FrameButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_frameEnabled = !_frameEnabled;
|
||||
AnimatedAreaIndicator.Visibility = _frameEnabled ? Visibility.Visible : Visibility.Collapsed;
|
||||
|
||||
if (!_frameEnabled)
|
||||
{
|
||||
ImageElement.Clip = null;
|
||||
BitmapIcon icon = new BitmapIcon();
|
||||
icon.UriSource = new Uri("ms-appx:/Assets/appbar.frame.disabled.png");
|
||||
frameButton.Icon = icon;
|
||||
}
|
||||
else
|
||||
{
|
||||
ImageElement.Clip = _animatedArea;
|
||||
BitmapIcon icon = new BitmapIcon();
|
||||
icon.UriSource = new Uri("ms-appx:/Assets/appbar.frame.enabled.png");
|
||||
frameButton.Icon = icon;
|
||||
}
|
||||
|
||||
Render(_onScreenImageProviders, _animationIndex, true);
|
||||
|
||||
saveButton.IsEnabled = true;
|
||||
}
|
||||
|
||||
private async void SaveButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Stop();
|
||||
await _renderTask;
|
||||
|
||||
SetControlsEnabled(false);
|
||||
|
||||
ProgressBarHelper.ShowProgressBar("Saving");
|
||||
|
||||
await Save();
|
||||
|
||||
ProgressBarHelper.HideProgressBar();
|
||||
|
||||
if (Frame.BackStackDepth == 2)
|
||||
{
|
||||
Frame.BackStack.RemoveAt(1);
|
||||
}
|
||||
|
||||
_navigationHelper.GoBack();
|
||||
}
|
||||
|
||||
private async Task Save()
|
||||
{
|
||||
if (_frameEnabled)
|
||||
{
|
||||
double _imageWidth = (_onScreenImageProviders == _unalignedImageProviders) ? _unalignedImageWidth : _alignedImageWidth;
|
||||
double _imageHeight = (_onScreenImageProviders == _unalignedImageProviders) ? _unalignedImageHeight : _alignedImageHeight;
|
||||
|
||||
// Scale animated area coordinates from display coordinates to the match the original bitmap size
|
||||
double xScale = _imageWidth / ImageElementBackground.ActualWidth;
|
||||
double yScale = _imageHeight / ImageElementBackground.ActualHeight;
|
||||
Rect frame = new Rect(
|
||||
_animatedArea.Rect.Left * xScale,
|
||||
_animatedArea.Rect.Top * yScale,
|
||||
_animatedArea.Rect.Width * xScale,
|
||||
_animatedArea.Rect.Height * yScale);
|
||||
await GifExporter.Export(_onScreenImageProviders, frame);
|
||||
}
|
||||
else
|
||||
{
|
||||
await GifExporter.Export(_onScreenImageProviders, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetControlsEnabled(bool value)
|
||||
{
|
||||
playButton.IsEnabled = value;
|
||||
saveButton.IsEnabled = value;
|
||||
alignButton.IsEnabled = value && (_alignedImageProviders != null);
|
||||
frameButton.IsEnabled = value;
|
||||
}
|
||||
|
||||
public void About_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Frame.Navigate(typeof(AboutPage));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
<Page
|
||||
x:Class="ImageSequencer.SequencesPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:ImageSequencer"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
|
||||
<Grid Margin="24,17,0,8">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Grid.Row="0" Margin="0, 0, 0, 24">
|
||||
<TextBlock Text="IMAGE SEQUENCER" Style="{ThemeResource TitleTextBlockStyle}"
|
||||
Typography.Capitals="SmallCaps"/>
|
||||
</StackPanel>
|
||||
|
||||
<ScrollViewer Grid.Row="1">
|
||||
<StackPanel>
|
||||
<TextBlock Text="example sequences" Style="{ThemeResource SubheaderTextBlockStyle}"></TextBlock>
|
||||
<ItemsControl ItemsSource="{Binding Sequences}" Visibility="Visible">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<WrapGrid Orientation="Horizontal" ItemWidth="180" ItemHeight="160"></WrapGrid>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Button BorderThickness="0" Click="Example_Click" Padding="8">
|
||||
<Button.Content>
|
||||
<Image Source="{Binding}" CacheMode="BitmapCache"/>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
|
||||
<TextBlock Text="saved animated gifs" Style="{ThemeResource SubheaderTextBlockStyle}"></TextBlock>
|
||||
|
||||
<ItemsControl ItemsSource="{Binding Gifs}" Visibility="Visible">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<WrapGrid Orientation="Horizontal" ItemWidth="180" ItemHeight="190"></WrapGrid>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Button BorderThickness="0" Click="Thumbnail_Click" Padding="8">
|
||||
<Button.Content>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="130"/>
|
||||
<RowDefinition Height="25"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Image Grid.Row="0" Source="{Binding BitmapImage}" CacheMode="BitmapCache"/>
|
||||
<TextBlock Grid.Row="1" VerticalAlignment="Bottom" Text="{Binding FileName}" Margin="0,6,0,0"></TextBlock>
|
||||
</Grid>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
<TextBlock x:Name="noGifFilesTextBlock" Grid.Row="2" Text="No GIF files" Style="{ThemeResource BaseTextBlockStyle}" Margin="8,12,0,0" Visibility="Collapsed"/>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
|
||||
<Page.BottomAppBar>
|
||||
<CommandBar>
|
||||
<AppBarButton Icon="Camera" Label="Capture" Click="Capture_Click"/>
|
||||
<CommandBar.SecondaryCommands>
|
||||
<AppBarButton x:Name="AboutButton" Label="About" Icon="Help" Click="About_Click"/>
|
||||
</CommandBar.SecondaryCommands>
|
||||
</CommandBar>
|
||||
</Page.BottomAppBar>
|
||||
|
||||
</Page>
|
|
@ -0,0 +1,108 @@
|
|||
/**
|
||||
* Copyright (c) 2013-2014 Microsoft Mobile.
|
||||
* See the license file delivered with this project for more information.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Windows.Media.Capture;
|
||||
using Windows.Storage;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Media.Imaging;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
namespace ImageSequencer
|
||||
{
|
||||
|
||||
public sealed partial class SequencesPage : Page
|
||||
{
|
||||
|
||||
public ObservableCollection<String> Sequences { get; private set; }
|
||||
public ObservableCollection<GifThumbnail> Gifs { get; private set; }
|
||||
|
||||
public SequencesPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
Gifs = new System.Collections.ObjectModel.ObservableCollection<GifThumbnail>();
|
||||
}
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
FindAnimGIFsFromPicturesLibraryAsync();
|
||||
|
||||
Sequences = new ObservableCollection<String>()
|
||||
{
|
||||
"ms-appx:///Assets/sequence.1.0.jpg",
|
||||
"ms-appx:///Assets/sequence.2.0.jpg"
|
||||
};
|
||||
|
||||
DataContext = this;
|
||||
}
|
||||
|
||||
private async void FindAnimGIFsFromPicturesLibraryAsync()
|
||||
{
|
||||
Gifs.Clear();
|
||||
|
||||
var files = await KnownFolders.SavedPictures.GetFilesAsync();
|
||||
foreach (StorageFile storageFile in files)
|
||||
{
|
||||
if (System.Text.RegularExpressions.Regex.IsMatch(
|
||||
storageFile.Name,
|
||||
"Sequence\\d+\\.gif",
|
||||
System.Text.RegularExpressions.RegexOptions.IgnoreCase))
|
||||
{
|
||||
var stream = await storageFile.OpenReadAsync();
|
||||
BitmapImage bitmapImage = new BitmapImage();
|
||||
bitmapImage.SetSource(stream);
|
||||
GifThumbnail gifThumbnail = new GifThumbnail();
|
||||
gifThumbnail.BitmapImage = bitmapImage;
|
||||
gifThumbnail.FileName = storageFile.Name;
|
||||
Gifs.Add(gifThumbnail);
|
||||
}
|
||||
}
|
||||
|
||||
noGifFilesTextBlock.Visibility = (Gifs.Count() == 0) ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public class GifThumbnail
|
||||
{
|
||||
public BitmapImage BitmapImage { get; set; }
|
||||
public String FileName { get; set; }
|
||||
}
|
||||
|
||||
public void Example_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
int sequenceId = Sequences.IndexOf((String)(((Button)sender).DataContext)) + 1;
|
||||
Frame.Navigate(typeof(SequencePreviewPage), sequenceId);
|
||||
}
|
||||
|
||||
public void Thumbnail_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
GifThumbnail thumbnail = (sender as Button).DataContext as GifThumbnail;
|
||||
Frame.Navigate(typeof(GifPage), thumbnail.FileName);
|
||||
}
|
||||
|
||||
public async void Capture_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
MediaCapture mediaCapture = new MediaCapture();
|
||||
await mediaCapture.InitializeAsync();
|
||||
if (mediaCapture.VideoDeviceController.LowLagPhotoSequence.Supported)
|
||||
{
|
||||
mediaCapture.Dispose();
|
||||
Frame.Navigate(typeof(SequenceCapturePage));
|
||||
}
|
||||
else
|
||||
{
|
||||
mediaCapture.Dispose();
|
||||
Frame.Navigate(typeof(VideoPreviewCapturePage));
|
||||
}
|
||||
}
|
||||
|
||||
public void About_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Frame.Navigate(typeof(AboutPage));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<Page
|
||||
x:Class="ImageSequencer.VideoPreviewCapturePage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:ImageSequencer"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
<Image Tapped="CaptureElement_Tapped" x:Name="captureElement"></Image>
|
||||
</Grid>
|
||||
|
||||
<Page.BottomAppBar>
|
||||
<CommandBar x:Name="CommandBar">
|
||||
<AppBarButton x:Name="CaptureButton" Label="Capture" Click="CaptureButton_Click">
|
||||
<AppBarButton.Icon>
|
||||
<BitmapIcon UriSource="/Assets/appbar.sequence.capture.png" />
|
||||
</AppBarButton.Icon>
|
||||
</AppBarButton>
|
||||
<CommandBar.SecondaryCommands>
|
||||
<AppBarButton x:Name="AboutButton" Label="About" Icon="Help" Click="About_Click"/>
|
||||
</CommandBar.SecondaryCommands>
|
||||
</CommandBar>
|
||||
</Page.BottomAppBar>
|
||||
|
||||
</Page>
|
|
@ -0,0 +1,244 @@
|
|||
/**
|
||||
* Copyright (c) 2013-2014 Microsoft Mobile.
|
||||
* See the license file delivered with this project for more information.
|
||||
*/
|
||||
|
||||
using ImageSequencer.Common;
|
||||
using Nokia.Graphics.Imaging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel.Core;
|
||||
using Windows.Graphics.Display;
|
||||
using Windows.Storage;
|
||||
using Windows.Storage.Streams;
|
||||
using Windows.UI.Core;
|
||||
using Windows.UI.ViewManagement;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Media.Imaging;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
namespace ImageSequencer
|
||||
{
|
||||
|
||||
public sealed partial class VideoPreviewCapturePage : Page
|
||||
{
|
||||
|
||||
private List<StorageFile> _files;
|
||||
private CameraPreviewImageSource _cameraPreviewImageSource;
|
||||
private WriteableBitmapRenderer _writeableBitmapRenderer;
|
||||
private JpegRenderer _jpegRenderer;
|
||||
private WriteableBitmap _writeableBitmap;
|
||||
private NavigationHelper _navigationHelper;
|
||||
private Task _renderTask;
|
||||
private bool _stop;
|
||||
private bool _capturing;
|
||||
private bool _rendering;
|
||||
private bool _initialized;
|
||||
private int _sequenceIndex;
|
||||
|
||||
public VideoPreviewCapturePage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
|
||||
_navigationHelper = new NavigationHelper(this);
|
||||
}
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
DisplayInformation.AutoRotationPreferences = DisplayOrientations.Landscape;
|
||||
_rendering = false;
|
||||
_stop = false;
|
||||
_files = new List<StorageFile>();
|
||||
_sequenceIndex = 1;
|
||||
InitializeAsync();
|
||||
|
||||
#if WINDOWS_PHONE_APP
|
||||
Windows.Phone.UI.Input.HardwareButtons.CameraPressed += HardwareButtons_CameraPressed;
|
||||
#endif
|
||||
}
|
||||
|
||||
protected override void OnNavigatedFrom(NavigationEventArgs e)
|
||||
{
|
||||
DisplayInformation.AutoRotationPreferences = DisplayOrientations.None;
|
||||
|
||||
base.OnNavigatedFrom(e);
|
||||
|
||||
#if WINDOWS_PHONE_APP
|
||||
Windows.Phone.UI.Input.HardwareButtons.CameraPressed -= HardwareButtons_CameraPressed;
|
||||
#endif
|
||||
}
|
||||
|
||||
public async void InitializeAsync()
|
||||
{
|
||||
// Create a camera preview image source (from Imaging SDK)
|
||||
_cameraPreviewImageSource = new CameraPreviewImageSource();
|
||||
await _cameraPreviewImageSource.InitializeAsync(string.Empty);
|
||||
var properties = await _cameraPreviewImageSource.StartPreviewAsync();
|
||||
|
||||
// Create a preview bitmap with the correct aspect ratio
|
||||
var width = 640.0;
|
||||
var height = (width / properties.Width) * properties.Height;
|
||||
_writeableBitmap = new WriteableBitmap((int)width, (int)height);
|
||||
|
||||
captureElement.Source = _writeableBitmap;
|
||||
|
||||
_writeableBitmapRenderer = new WriteableBitmapRenderer();
|
||||
_jpegRenderer = new JpegRenderer();
|
||||
|
||||
// Attach preview frame delegate
|
||||
_cameraPreviewImageSource.PreviewFrameAvailable += OnPreviewFrameAvailable;
|
||||
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
private void OnPreviewFrameAvailable(IImageSize args)
|
||||
{
|
||||
_renderTask = Render();
|
||||
}
|
||||
|
||||
private async Task Render()
|
||||
{
|
||||
if (!_rendering && !_stop)
|
||||
{
|
||||
_rendering = true;
|
||||
|
||||
// Render camera preview frame to screen
|
||||
_writeableBitmapRenderer.Source = _cameraPreviewImageSource;
|
||||
_writeableBitmapRenderer.WriteableBitmap = _writeableBitmap;
|
||||
await _writeableBitmapRenderer.RenderAsync();
|
||||
|
||||
await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
|
||||
CoreDispatcherPriority.High, () =>
|
||||
{
|
||||
_writeableBitmap.Invalidate();
|
||||
});
|
||||
|
||||
// Write camera preview frame to file if capturing
|
||||
if (_capturing)
|
||||
{
|
||||
if (_sequenceIndex < 20)
|
||||
{
|
||||
_jpegRenderer.Source = _cameraPreviewImageSource;
|
||||
IBuffer jpg = await _jpegRenderer.RenderAsync();
|
||||
await Save(jpg, _sequenceIndex++);
|
||||
}
|
||||
else
|
||||
{
|
||||
StartStopCapture();
|
||||
}
|
||||
}
|
||||
|
||||
_rendering = false;
|
||||
}
|
||||
|
||||
if (_stop)
|
||||
{
|
||||
_capturing = false;
|
||||
_cameraPreviewImageSource.Dispose();
|
||||
_writeableBitmapRenderer.Dispose();
|
||||
_jpegRenderer.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Save(IBuffer frame, int i)
|
||||
{
|
||||
var filename = "ImageSequencer." + i + ".jpg";
|
||||
var folder = Windows.Storage.ApplicationData.Current.TemporaryFolder;
|
||||
var storageFile = await folder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
|
||||
await Windows.Storage.FileIO.WriteBufferAsync(storageFile, frame);
|
||||
_files.Add(storageFile);
|
||||
}
|
||||
|
||||
private async void Current_VisibilityChanged(object sender, Windows.UI.Core.VisibilityChangedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (e.Visible)
|
||||
{
|
||||
await ResumePreviewAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
await PausePreviewAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task PausePreviewAsync()
|
||||
{
|
||||
if (_initialized)
|
||||
{
|
||||
await _cameraPreviewImageSource.StopPreviewAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ResumePreviewAsync()
|
||||
{
|
||||
if (_initialized)
|
||||
{
|
||||
await _cameraPreviewImageSource.InitializeAsync(string.Empty);
|
||||
await _cameraPreviewImageSource.StartPreviewAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public void CaptureElement_Tapped(object sender, RoutedEventArgs e)
|
||||
{
|
||||
StartStopCapture();
|
||||
}
|
||||
|
||||
#if WINDOWS_PHONE_APP
|
||||
void HardwareButtons_CameraPressed(object sender, Windows.Phone.UI.Input.CameraEventArgs e)
|
||||
{
|
||||
StartStopCapture();
|
||||
}
|
||||
#endif
|
||||
|
||||
private void StartStopCapture()
|
||||
{
|
||||
if (!_capturing)
|
||||
{
|
||||
_capturing = true;
|
||||
ProgressBarHelper.ShowProgressBar("Capturing");
|
||||
CaptureButton.Icon = new SymbolIcon(Symbol.Stop);
|
||||
}
|
||||
else
|
||||
{
|
||||
StopCapture();
|
||||
}
|
||||
}
|
||||
|
||||
public void StopCapture()
|
||||
{
|
||||
_stop = true;
|
||||
ProgressBarHelper.HideProgressBar();
|
||||
ShowPreview();
|
||||
}
|
||||
|
||||
private async void ShowPreview()
|
||||
{
|
||||
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
|
||||
() =>
|
||||
{
|
||||
Frame.Navigate(typeof(SequencePreviewPage), _files);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public void CaptureButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
StartStopCapture();
|
||||
}
|
||||
|
||||
public void About_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Frame.Navigate(typeof(AboutPage));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Windows/Assets/Logo.scale-100.png
Normal file
После Ширина: | Высота: | Размер: 6.5 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Windows/Assets/SmallLogo.scale-100.png
Normal file
После Ширина: | Высота: | Размер: 1004 B |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Windows/Assets/SplashScreen.scale-100.png
Normal file
После Ширина: | Высота: | Размер: 16 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Windows/Assets/StoreLogo.scale-100.png
Normal file
После Ширина: | Высота: | Размер: 1.6 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Windows/Assets/Thumbs.db
Normal file
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Windows/Help/Nokia Imaging SDK.chm
Normal file
|
@ -0,0 +1,151 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{F178CAC4-C7BE-4BC1-90BD-81F50E427C11}</ProjectGuid>
|
||||
<OutputType>AppContainerExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>ImageSequencer</RootNamespace>
|
||||
<AssemblyName>ImageSequencer.Windows</AssemblyName>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<TargetPlatformVersion>8.1</TargetPlatformVersion>
|
||||
<MinimumVisualStudioVersion>12</MinimumVisualStudioVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<SynthesizeLinkMetadata>true</SynthesizeLinkMetadata>
|
||||
<ProjectTypeGuids>{BC8A1FFA-BEE3-4634-8014-F334798102B3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<PackageCertificateKeyFile>ImageSequencer.Windows_TemporaryKey.pfx</PackageCertificateKeyFile>
|
||||
<NuGetPackageImportStamp>9288e9bc</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_APP</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_APP</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\ARM\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_APP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>ARM</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
|
||||
<OutputPath>bin\ARM\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_APP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>ARM</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_APP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_APP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_APP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_APP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="MainPage.xaml.cs">
|
||||
<DependentUpon>MainPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="Package.appxmanifest">
|
||||
<SubType>Designer</SubType>
|
||||
</AppxManifest>
|
||||
<None Include="Help\Nokia Imaging SDK.chm" />
|
||||
<None Include="ImageSequencer.Windows_TemporaryKey.pfx" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Assets\Logo.scale-100.png" />
|
||||
<Content Include="Assets\SmallLogo.scale-100.png" />
|
||||
<Content Include="Assets\SplashScreen.scale-100.png" />
|
||||
<Content Include="Assets\StoreLogo.scale-100.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="MainPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '12.0' ">
|
||||
<VisualStudioVersion>12.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\ImageSequencer.Shared\ImageSequencer.Shared.projitems" Label="Shared" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
||||
<Import Project="..\..\packages\NokiaImagingSDK.1.2.151\build\win81\NokiaImagingSDK.targets" Condition="Exists('..\..\packages\NokiaImagingSDK.1.2.151\build\win81\NokiaImagingSDK.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\packages\NokiaImagingSDK.1.2.151\build\win81\NokiaImagingSDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\NokiaImagingSDK.1.2.151\build\win81\NokiaImagingSDK.targets'))" />
|
||||
</Target>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.Windows/ImageSequencer.Windows_TemporaryKey.pfx
Normal file
|
@ -0,0 +1,13 @@
|
|||
<Page
|
||||
x:Class="ImageSequencer.MainPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:ImageSequencer"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
|
||||
</Grid>
|
||||
</Page>
|
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
|
||||
|
||||
namespace ImageSequencer
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// </summary>
|
||||
public sealed partial class MainPage : Page
|
||||
{
|
||||
public MainPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?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="f3b8cd98-c89a-49ce-bb87-02b89969c60a" Publisher="CN=pekka" Version="1.0.0.0" />
|
||||
<Properties>
|
||||
<DisplayName>ImageSequencer.Windows</DisplayName>
|
||||
<PublisherDisplayName>pekka</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="ImageSequencer.Windows.App">
|
||||
<m2:VisualElements DisplayName="ImageSequencer.Windows" Square150x150Logo="Assets\Logo.png" Square30x30Logo="Assets\SmallLogo.png" Description="ImageSequencer.Windows" ForegroundText="light" BackgroundColor="#464646">
|
||||
<m2:SplashScreen Image="Assets\SplashScreen.png" />
|
||||
</m2:VisualElements>
|
||||
</Application>
|
||||
</Applications>
|
||||
<Capabilities>
|
||||
<Capability Name="internetClient" />
|
||||
<Capability Name="picturesLibrary" />
|
||||
<DeviceCapability Name="webcam" />
|
||||
</Capabilities>
|
||||
</Package>
|
|
@ -0,0 +1,29 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("ImageSequencer.Windows")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("ImageSequencer.Windows")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2014")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: ComVisible(false)]
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="NokiaImagingSDK" version="1.2.151" targetFramework="win81" />
|
||||
</packages>
|
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.WindowsPhone/Assets/Logo.scale-240.png
Normal file
После Ширина: | Высота: | Размер: 17 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.WindowsPhone/Assets/SmallLogo.scale-240.png
Normal file
После Ширина: | Высота: | Размер: 4.3 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.WindowsPhone/Assets/SplashScreen.scale-240.png
Normal file
После Ширина: | Высота: | Размер: 50 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.WindowsPhone/Assets/Square71x71Logo.scale-240.png
Normal file
После Ширина: | Высота: | Размер: 6.9 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.WindowsPhone/Assets/StoreLogo.scale-240.png
Normal file
После Ширина: | Высота: | Размер: 5.2 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.WindowsPhone/Assets/Thumbs.db
Normal file
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.WindowsPhone/Assets/WideLogo.scale-240.png
Normal file
После Ширина: | Высота: | Размер: 18 KiB |
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.WindowsPhone/Help/Nokia Imaging SDK.chm
Normal file
|
@ -0,0 +1,136 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{22C3F30A-9C25-4DCB-A3CE-9ACBA1BD2098}</ProjectGuid>
|
||||
<OutputType>AppContainerExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>ImageSequencer</RootNamespace>
|
||||
<AssemblyName>ImageSequencer.WindowsPhone</AssemblyName>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<TargetPlatformVersion>8.1</TargetPlatformVersion>
|
||||
<MinimumVisualStudioVersion>12</MinimumVisualStudioVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{76F1466A-8B6D-4E39-A767-685A06062A39};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<SynthesizeLinkMetadata>true</SynthesizeLinkMetadata>
|
||||
<NuGetPackageImportStamp>381aca59</NuGetPackageImportStamp>
|
||||
<AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision>
|
||||
<AppxBundlePlatforms>arm</AppxBundlePlatforms>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_PHONE_APP</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_PHONE_APP</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\ARM\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_PHONE_APP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>ARM</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
|
||||
<OutputPath>bin\ARM\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_PHONE_APP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>ARM</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_PHONE_APP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_PHONE_APP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="MainPage.xaml.cs">
|
||||
<DependentUpon>MainPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="Package.appxmanifest">
|
||||
<SubType>Designer</SubType>
|
||||
</AppxManifest>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Assets\Logo.scale-240.png" />
|
||||
<Content Include="Assets\SmallLogo.scale-240.png" />
|
||||
<Content Include="Assets\SplashScreen.scale-240.png" />
|
||||
<Content Include="Assets\Square71x71Logo.scale-240.png" />
|
||||
<Content Include="Assets\StoreLogo.scale-240.png" />
|
||||
<Content Include="Assets\WideLogo.scale-240.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="MainPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Help\Nokia Imaging SDK.chm" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '12.0' ">
|
||||
<VisualStudioVersion>12.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(TargetPlatformIdentifier)' == '' ">
|
||||
<TargetPlatformIdentifier>WindowsPhoneApp</TargetPlatformIdentifier>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\ImageSequencer.Shared\ImageSequencer.Shared.projitems" Label="Shared" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
||||
<Import Project="..\..\packages\NokiaImagingSDK.1.2.151\build\wpa81\NokiaImagingSDK.targets" Condition="Exists('..\..\packages\NokiaImagingSDK.1.2.151\build\wpa81\NokiaImagingSDK.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\packages\NokiaImagingSDK.1.2.151\build\wpa81\NokiaImagingSDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\NokiaImagingSDK.1.2.151\build\wpa81\NokiaImagingSDK.targets'))" />
|
||||
</Target>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
|
||||
<DeviceId>30F105C9-681E-420b-A277-7C086EAD8A4E</DeviceId>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
|
||||
<DeviceId>30F105C9-681E-420b-A277-7C086EAD8A4E</DeviceId>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
|
||||
<DeviceId>30F105C9-681E-420B-A277-7C086EAD8A4E</DeviceId>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DeviceId>30F105C9-681E-420b-A277-7C086EAD8A4E</DeviceId>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AppxPackageIsForStore>False</AppxPackageIsForStore>
|
||||
<AppxShowAllApps>False</AppxShowAllApps>
|
||||
<AppxBuildConfigurationSelection>arm</AppxBuildConfigurationSelection>
|
||||
</PropertyGroup>
|
||||
</Project>
|
Двоичные данные
ImageSequencerWindows/ImageSequencer/ImageSequencer.WindowsPhone/ImageSequencer.WindowsPhone_TemporaryKey.pfx
Normal file
|
@ -0,0 +1,14 @@
|
|||
<Page
|
||||
x:Class="ImageSequencer.MainPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:ImageSequencer"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
|
||||
<Grid>
|
||||
<TextBlock Text="Hello"></TextBlock>
|
||||
</Grid>
|
||||
</Page>
|
|
@ -0,0 +1,48 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
|
||||
|
||||
namespace ImageSequencer
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// </summary>
|
||||
public sealed partial class MainPage : Page
|
||||
{
|
||||
public MainPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
|
||||
this.NavigationCacheMode = NavigationCacheMode.Required;
|
||||
}
|
||||
|
||||
/// <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.
|
||||
/// This parameter is typically used to configure the page.</param>
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
// TODO: Prepare page for display here.
|
||||
|
||||
// TODO: If your application contains multiple pages, ensure that you are
|
||||
// handling the hardware Back button by registering for the
|
||||
// Windows.Phone.UI.Input.HardwareButtons.BackPressed event.
|
||||
// If you are using the NavigationHelper provided by some templates,
|
||||
// this event is handled for you.
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<?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" xmlns:m3="http://schemas.microsoft.com/appx/2014/manifest" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest">
|
||||
<Identity Name="7cc8df2a-c77b-4c52-8c33-005cf7973d2c" Publisher="CN=pekka" Version="2.0.0.0" />
|
||||
<mp:PhoneIdentity PhoneProductId="7cc8df2a-c77b-4c52-8c33-005cf7973d2c" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
|
||||
<Properties>
|
||||
<DisplayName>ImageSequencer.WindowsPhone</DisplayName>
|
||||
<PublisherDisplayName>pekka</PublisherDisplayName>
|
||||
<Logo>Assets\StoreLogo.png</Logo>
|
||||
</Properties>
|
||||
<Prerequisites>
|
||||
<OSMinVersion>6.3.1</OSMinVersion>
|
||||
<OSMaxVersionTested>6.3.1</OSMaxVersionTested>
|
||||
</Prerequisites>
|
||||
<Resources>
|
||||
<Resource Language="x-generate" />
|
||||
</Resources>
|
||||
<Applications>
|
||||
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="ImageSequencer.WindowsPhone.App">
|
||||
<m3:VisualElements DisplayName="ImageSequencer" Square150x150Logo="Assets\Logo.png" Square44x44Logo="Assets\SmallLogo.png" Description="ImageSequencer" ForegroundText="light" BackgroundColor="transparent">
|
||||
<m3:DefaultTile Wide310x150Logo="Assets\WideLogo.png" Square71x71Logo="Assets\Square71x71Logo.png">
|
||||
</m3:DefaultTile>
|
||||
<m3:SplashScreen Image="Assets\SplashScreen.png" />
|
||||
<m3:ApplicationView MinWidth="width320" />
|
||||
<!--Used in XAML Designer. DO NOT REMOVE-->
|
||||
</m3:VisualElements>
|
||||
</Application>
|
||||
</Applications>
|
||||
<Capabilities>
|
||||
<Capability Name="internetClientServer" />
|
||||
<Capability Name="picturesLibrary" />
|
||||
<DeviceCapability Name="webcam" />
|
||||
</Capabilities>
|
||||
</Package>
|