Windows 10 1511 Release - May 2016 Update

This commit is contained in:
Raymond Chen 2016-05-18 17:00:01 -07:00
Родитель beb665ec36 6b625670fa
Коммит 9e7fa281b4
182 изменённых файлов: 6955 добавлений и 2723 удалений

2
.gitignore поставляемый
Просмотреть файл

@ -74,6 +74,8 @@ ipch/
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess

Просмотреть файл

@ -392,6 +392,14 @@ For additional Windows samples, see [Windows on GitHub](http://microsoft.github.
</tr>
</table>
### Holographic
<table>
<tr>
<td><a href="Samples/HolographicSpatialMapping">Holographic spatial mapping</a></td>
</tr>
</table>
### Identity, security, and encryption
<table>

Просмотреть файл

@ -20,7 +20,7 @@
switch (pageSections) {
case "1":
// Animate the whole page together
enterPage = WinJS.UI.Animation.enterPage([scenarioHeader, input, output], null);
enterPage = WinJS.UI.Animation.enterPage([[scenarioHeader, input, output]], null);
break;
case "2":
// Stagger the header and body

Просмотреть файл

@ -172,8 +172,6 @@ namespace BackgroundAudioTask
BackgroundMediaPlayer.MessageReceivedFromForeground -= BackgroundMediaPlayer_MessageReceivedFromForeground;
smtc.ButtonPressed -= smtc_ButtonPressed;
smtc.PropertyChanged -= smtc_PropertyChanged;
BackgroundMediaPlayer.Shutdown(); // shutdown media pipeline
}
catch (Exception ex)
{

Просмотреть файл

@ -34,7 +34,7 @@ Array<Scenario>^ MainPage::scenariosInner = ref new Array<Scenario>
{
// The format here is the following:
// { "Description for the sample", "Fully quaified name for the class that implements the scenario" }
{ "Background task", "SDKTemplate.SampleBackgroundTask" },
{ "Background task", "SDKTemplate.SampleBackgroundTask" },
{ "Background task with a condition", "SDKTemplate.SampleBackgroundTaskWithCondition" },
{ "Servicing complete task", "SDKTemplate.ServicingCompleteTask" },
{ "Background task with time trigger", "SDKTemplate.TimeTriggeredTask" },
@ -102,7 +102,7 @@ BackgroundTaskRegistration^ BackgroundTaskSample::RegisterBackgroundTask(String^
auto task = builder->Register();
UpdateBackgroundTaskStatus(name, true);
UpdateBackgroundTaskRegistrationStatus(name, true);
//
// Remove previous completion status from local settings.
@ -142,17 +142,17 @@ void BackgroundTaskSample::UnregisterBackgroundTasks(String^ name)
{
auto cur = iter->Current->Value;
if(cur->Name == name)
if (cur->Name == name)
{
cur->Unregister(true);
UpdateBackgroundTaskStatus(name, false);
UpdateBackgroundTaskRegistrationStatus(name, false);
}
hascur = iter->MoveNext();
}
}
void BackgroundTaskSample::UpdateBackgroundTaskStatus(String^ name, bool registered)
void BackgroundTaskSample::UpdateBackgroundTaskRegistrationStatus(String^ name, bool registered)
{
if (name == SampleBackgroundTaskName)
{

Просмотреть файл

@ -61,7 +61,7 @@ namespace SDKTemplate
static BackgroundTaskRegistration^ RegisterBackgroundTask(String^ taskEntryPoint, String^ name, IBackgroundTrigger^ trigger, IBackgroundCondition^ condition);
static bool TaskRequiresBackgroundAccess(String^ name);
static void UnregisterBackgroundTasks(String^ name);
static void UpdateBackgroundTaskStatus(String^ name, bool registered);
static void UpdateBackgroundTaskRegistrationStatus(String^ name, bool registered);
static String^ SampleBackgroundTaskProgress;
static bool SampleBackgroundTaskRegistered;

Просмотреть файл

@ -44,20 +44,15 @@ void SampleBackgroundTask::OnNavigatedTo(NavigationEventArgs^ e)
//
// Attach progress and completed handlers to any existing tasks.
//
auto iter = BackgroundTaskRegistration::AllTasks->First();
auto hascur = iter->HasCurrent;
while (hascur)
for (auto pair : BackgroundTaskRegistration::AllTasks)
{
auto cur = iter->Current->Value;
if (cur->Name == SampleBackgroundTaskName)
auto task = pair->Value;
if (task->Name == SampleBackgroundTaskName)
{
BackgroundTaskSample::UpdateBackgroundTaskStatus(cur->Name, true);
AttachProgressAndCompletedHandlers(cur);
BackgroundTaskSample::UpdateBackgroundTaskRegistrationStatus(task->Name, true);
AttachProgressAndCompletedHandlers(task);
break;
}
hascur = iter->MoveNext();
}
UpdateUI();
@ -69,19 +64,8 @@ void SampleBackgroundTask::OnNavigatedTo(NavigationEventArgs^ e)
/// <param name="task">The task to attach progress and completed handlers to.</param>
void SampleBackgroundTask::AttachProgressAndCompletedHandlers(IBackgroundTaskRegistration^ task)
{
auto progress = [this](BackgroundTaskRegistration^ task, BackgroundTaskProgressEventArgs^ args)
{
auto progress = "Progress: " + args->Progress + "%";
BackgroundTaskSample::SampleBackgroundTaskProgress = progress;
UpdateUI();
};
task->Progress += ref new BackgroundTaskProgressEventHandler(progress);
auto completed = [this](BackgroundTaskRegistration^ task, BackgroundTaskCompletedEventArgs^ args)
{
UpdateUI();
};
task->Completed += ref new BackgroundTaskCompletedEventHandler(completed);
task->Progress += ref new BackgroundTaskProgressEventHandler(this, &SampleBackgroundTask::OnProgress);
task->Completed += ref new BackgroundTaskCompletedEventHandler(this, &SampleBackgroundTask::OnCompleted);
}
/// <summary>
@ -110,6 +94,31 @@ void SampleBackgroundTask::UnregisterBackgroundTask(Platform::Object^ sender, Wi
UpdateUI();
}
/// <summary>
/// Handle background task progress.
/// </summary>
/// <param name="task">The task that is reporting progress.</param>
/// <param name="args">Arguments of the progress report.</param>
void SampleBackgroundTask::OnProgress(BackgroundTaskRegistration^ task, BackgroundTaskProgressEventArgs^ args)
{
Dispatcher->RunAsync(CoreDispatcherPriority::Normal, ref new DispatchedHandler([this, args]()
{
auto progress = "Progress: " + args->Progress + "%";
BackgroundTaskSample::SampleBackgroundTaskProgress = progress;
UpdateUI();
}));
}
/// <summary>
/// Handle background task completion.
/// </summary>
/// <param name="task">The task that is reporting completion.</param>
/// <param name="args">Arguments of the completion report.</param>
void SampleBackgroundTask::OnCompleted(BackgroundTaskRegistration^ task, BackgroundTaskCompletedEventArgs^ args)
{
UpdateUI();
}
/// <summary>
/// Update the scenario UI.
/// </summary>

Просмотреть файл

@ -38,6 +38,8 @@ namespace SDKTemplate
void AttachProgressAndCompletedHandlers(Windows::ApplicationModel::Background::IBackgroundTaskRegistration^ task);
void RegisterBackgroundTask(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void UnregisterBackgroundTask(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void OnProgress(Windows::ApplicationModel::Background::BackgroundTaskRegistration^ task, Windows::ApplicationModel::Background::BackgroundTaskProgressEventArgs^ args);
void OnCompleted(Windows::ApplicationModel::Background::BackgroundTaskRegistration^ task, Windows::ApplicationModel::Background::BackgroundTaskCompletedEventArgs^ args);
void UpdateUI();
};
}

Просмотреть файл

@ -44,20 +44,15 @@ void SampleBackgroundTaskWithCondition::OnNavigatedTo(NavigationEventArgs^ e)
//
// Attach progress and completed handlers to any existing tasks.
//
auto iter = BackgroundTaskRegistration::AllTasks->First();
auto hascur = iter->HasCurrent;
while (hascur)
for (auto pair : BackgroundTaskRegistration::AllTasks)
{
auto cur = iter->Current->Value;
if (cur->Name == SampleBackgroundTaskWithConditionName)
auto task = pair->Value;
if (task->Name == SampleBackgroundTaskWithConditionName)
{
BackgroundTaskSample::UpdateBackgroundTaskStatus(cur->Name, true);
AttachProgressAndCompletedHandlers(cur);
BackgroundTaskSample::UpdateBackgroundTaskRegistrationStatus(task->Name, true);
AttachProgressAndCompletedHandlers(task);
break;
}
hascur = iter->MoveNext();
}
UpdateUI();
@ -69,19 +64,8 @@ void SampleBackgroundTaskWithCondition::OnNavigatedTo(NavigationEventArgs^ e)
/// <param name="task">The task to attach progress and completed handlers to.</param>
void SampleBackgroundTaskWithCondition::AttachProgressAndCompletedHandlers(IBackgroundTaskRegistration^ task)
{
auto progress = [this](BackgroundTaskRegistration^ task, BackgroundTaskProgressEventArgs^ args)
{
auto progress = "Progress: " + args->Progress + "%";
BackgroundTaskSample::SampleBackgroundTaskWithConditionProgress = progress;
UpdateUI();
};
task->Progress += ref new BackgroundTaskProgressEventHandler(progress);
auto completed = [this](BackgroundTaskRegistration^ task, BackgroundTaskCompletedEventArgs^ args)
{
UpdateUI();
};
task->Completed += ref new BackgroundTaskCompletedEventHandler(completed);
task->Progress += ref new BackgroundTaskProgressEventHandler(this, &SampleBackgroundTaskWithCondition::OnProgress);
task->Completed += ref new BackgroundTaskCompletedEventHandler(this, &SampleBackgroundTaskWithCondition::OnCompleted);
}
/// <summary>
@ -110,6 +94,31 @@ void SampleBackgroundTaskWithCondition::UnregisterBackgroundTask(Platform::Objec
UpdateUI();
}
/// <summary>
/// Handle background task progress.
/// </summary>
/// <param name="task">The task that is reporting progress.</param>
/// <param name="args">Arguments of the progress report.</param>
void SampleBackgroundTaskWithCondition::OnProgress(BackgroundTaskRegistration^ task, BackgroundTaskProgressEventArgs^ args)
{
Dispatcher->RunAsync(CoreDispatcherPriority::Normal, ref new DispatchedHandler([this, args]()
{
auto progress = "Progress: " + args->Progress + "%";
BackgroundTaskSample::SampleBackgroundTaskWithConditionProgress = progress;
UpdateUI();
}));
}
/// <summary>
/// Handle background task completion.
/// </summary>
/// <param name="task">The task that is reporting completion.</param>
/// <param name="args">Arguments of the completion report.</param>
void SampleBackgroundTaskWithCondition::OnCompleted(BackgroundTaskRegistration^ task, BackgroundTaskCompletedEventArgs^ args)
{
UpdateUI();
}
/// <summary>
/// Update the scenario UI.
/// </summary>

Просмотреть файл

@ -38,6 +38,8 @@ namespace SDKTemplate
void AttachProgressAndCompletedHandlers(Windows::ApplicationModel::Background::IBackgroundTaskRegistration^ task);
void RegisterBackgroundTask(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void UnregisterBackgroundTask(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void OnProgress(Windows::ApplicationModel::Background::BackgroundTaskRegistration^ task, Windows::ApplicationModel::Background::BackgroundTaskProgressEventArgs^ args);
void OnCompleted(Windows::ApplicationModel::Background::BackgroundTaskRegistration^ task, Windows::ApplicationModel::Background::BackgroundTaskCompletedEventArgs^ args);
void UpdateUI();
};
}

Просмотреть файл

@ -44,20 +44,15 @@ void ServicingCompleteTask::OnNavigatedTo(NavigationEventArgs^ e)
//
// Attach progress and completed handlers to any existing tasks.
//
auto iter = BackgroundTaskRegistration::AllTasks->First();
auto hascur = iter->HasCurrent;
while (hascur)
for (auto pair : BackgroundTaskRegistration::AllTasks)
{
auto cur = iter->Current->Value;
if (cur->Name == ServicingCompleteTaskName)
auto task = pair->Value;
if (task->Name == ServicingCompleteTaskName)
{
BackgroundTaskSample::UpdateBackgroundTaskStatus(cur->Name, true);
AttachProgressAndCompletedHandlers(cur);
BackgroundTaskSample::UpdateBackgroundTaskRegistrationStatus(task->Name, true);
AttachProgressAndCompletedHandlers(task);
break;
}
hascur = iter->MoveNext();
}
UpdateUI();
@ -69,19 +64,8 @@ void ServicingCompleteTask::OnNavigatedTo(NavigationEventArgs^ e)
/// <param name="task">The task to attach progress and completed handlers to.</param>
void ServicingCompleteTask::AttachProgressAndCompletedHandlers(IBackgroundTaskRegistration^ task)
{
auto progress = [this](BackgroundTaskRegistration^ task, BackgroundTaskProgressEventArgs^ args)
{
auto progress = "Progress: " + args->Progress + "%";
BackgroundTaskSample::ServicingCompleteTaskProgress = progress;
UpdateUI();
};
task->Progress += ref new BackgroundTaskProgressEventHandler(progress);
auto completed = [this](BackgroundTaskRegistration^ task, BackgroundTaskCompletedEventArgs^ args)
{
UpdateUI();
};
task->Completed += ref new BackgroundTaskCompletedEventHandler(completed);
task->Progress += ref new BackgroundTaskProgressEventHandler(this, &ServicingCompleteTask::OnProgress);
task->Completed += ref new BackgroundTaskCompletedEventHandler(this, &ServicingCompleteTask::OnCompleted);
}
/// <summary>
@ -111,6 +95,31 @@ void ServicingCompleteTask::UnregisterBackgroundTask(Platform::Object^ sender, W
UpdateUI();
}
/// <summary>
/// Handle background task progress.
/// </summary>
/// <param name="task">The task that is reporting progress.</param>
/// <param name="args">Arguments of the progress report.</param>
void ServicingCompleteTask::OnProgress(BackgroundTaskRegistration^ task, BackgroundTaskProgressEventArgs^ args)
{
Dispatcher->RunAsync(CoreDispatcherPriority::Normal, ref new DispatchedHandler([this, args]()
{
auto progress = "Progress: " + args->Progress + "%";
BackgroundTaskSample::ServicingCompleteTaskProgress = progress;
UpdateUI();
}));
}
/// <summary>
/// Handle background task completion.
/// </summary>
/// <param name="task">The task that is reporting completion.</param>
/// <param name="args">Arguments of the completion report.</param>
void ServicingCompleteTask::OnCompleted(BackgroundTaskRegistration^ task, BackgroundTaskCompletedEventArgs^ args)
{
UpdateUI();
}
/// <summary>
/// Update the scenario UI.
/// </summary>

Просмотреть файл

@ -38,6 +38,8 @@ namespace SDKTemplate
void AttachProgressAndCompletedHandlers(Windows::ApplicationModel::Background::IBackgroundTaskRegistration^ task);
void RegisterBackgroundTask(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void UnregisterBackgroundTask(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void OnProgress(Windows::ApplicationModel::Background::BackgroundTaskRegistration^ task, Windows::ApplicationModel::Background::BackgroundTaskProgressEventArgs^ args);
void OnCompleted(Windows::ApplicationModel::Background::BackgroundTaskRegistration^ task, Windows::ApplicationModel::Background::BackgroundTaskCompletedEventArgs^ args);
void UpdateUI();
};
}

Просмотреть файл

@ -44,20 +44,15 @@ void TimeTriggeredTask::OnNavigatedTo(NavigationEventArgs^ e)
//
// Attach progress and completed handlers to any existing tasks.
//
auto iter = BackgroundTaskRegistration::AllTasks->First();
auto hascur = iter->HasCurrent;
while (hascur)
for (auto pair : BackgroundTaskRegistration::AllTasks)
{
auto cur = iter->Current->Value;
if (cur->Name == TimeTriggeredTaskName)
auto task = pair->Value;
if (task->Name == TimeTriggeredTaskName)
{
BackgroundTaskSample::UpdateBackgroundTaskStatus(cur->Name, true);
AttachProgressAndCompletedHandlers(cur);
BackgroundTaskSample::UpdateBackgroundTaskRegistrationStatus(task->Name, true);
AttachProgressAndCompletedHandlers(task);
break;
}
hascur = iter->MoveNext();
}
UpdateUI();
@ -69,19 +64,8 @@ void TimeTriggeredTask::OnNavigatedTo(NavigationEventArgs^ e)
/// <param name="task">The task to attach progress and completed handlers to.</param>
void TimeTriggeredTask::AttachProgressAndCompletedHandlers(IBackgroundTaskRegistration^ task)
{
auto progress = [this](BackgroundTaskRegistration^ task, BackgroundTaskProgressEventArgs^ args)
{
auto progress = "Progress: " + args->Progress + "%";
BackgroundTaskSample::TimeTriggeredTaskProgress = progress;
UpdateUI();
};
task->Progress += ref new BackgroundTaskProgressEventHandler(progress);
auto completed = [this](BackgroundTaskRegistration^ task, BackgroundTaskCompletedEventArgs^ args)
{
UpdateUI();
};
task->Completed += ref new BackgroundTaskCompletedEventHandler(completed);
task->Progress += ref new BackgroundTaskProgressEventHandler(this, &TimeTriggeredTask::OnProgress);
task->Completed += ref new BackgroundTaskCompletedEventHandler(this, &TimeTriggeredTask::OnCompleted);
}
/// <summary>
@ -110,6 +94,31 @@ void TimeTriggeredTask::UnregisterBackgroundTask(Platform::Object^ sender, Windo
UpdateUI();
}
/// <summary>
/// Handle background task progress.
/// </summary>
/// <param name="task">The task that is reporting progress.</param>
/// <param name="args">Arguments of the progress report.</param>
void TimeTriggeredTask::OnProgress(BackgroundTaskRegistration^ task, BackgroundTaskProgressEventArgs^ args)
{
Dispatcher->RunAsync(CoreDispatcherPriority::Normal, ref new DispatchedHandler([this, args]()
{
auto progress = "Progress: " + args->Progress + "%";
BackgroundTaskSample::TimeTriggeredTaskProgress = progress;
UpdateUI();
}));
}
/// <summary>
/// Handle background task completion.
/// </summary>
/// <param name="task">The task that is reporting completion.</param>
/// <param name="args">Arguments of the completion report.</param>
void TimeTriggeredTask::OnCompleted(BackgroundTaskRegistration^ task, BackgroundTaskCompletedEventArgs^ args)
{
UpdateUI();
}
/// <summary>
/// Update the scenario UI.
/// </summary>

Просмотреть файл

@ -38,6 +38,8 @@ namespace SDKTemplate
void AttachProgressAndCompletedHandlers(Windows::ApplicationModel::Background::IBackgroundTaskRegistration^ task);
void RegisterBackgroundTask(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void UnregisterBackgroundTask(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void OnProgress(Windows::ApplicationModel::Background::BackgroundTaskRegistration^ task, Windows::ApplicationModel::Background::BackgroundTaskProgressEventArgs^ args);
void OnCompleted(Windows::ApplicationModel::Background::BackgroundTaskRegistration^ task, Windows::ApplicationModel::Background::BackgroundTaskCompletedEventArgs^ args);
void UpdateUI();
};
}

Просмотреть файл

@ -44,20 +44,15 @@ void ApplicationTriggerTask::OnNavigatedTo(NavigationEventArgs^ e)
//
// Attach progress and completed handlers to any existing tasks.
//
auto iter = BackgroundTaskRegistration::AllTasks->First();
auto hascur = iter->HasCurrent;
while (hascur)
for (auto pair : BackgroundTaskRegistration::AllTasks)
{
auto cur = iter->Current->Value;
if (cur->Name == ApplicationTriggerTaskName)
auto task = pair->Value;
if (task->Name == ApplicationTriggerTaskName)
{
BackgroundTaskSample::UpdateBackgroundTaskStatus(cur->Name, true);
AttachProgressAndCompletedHandlers(cur);
BackgroundTaskSample::UpdateBackgroundTaskRegistrationStatus(task->Name, true);
AttachProgressAndCompletedHandlers(task);
break;
}
hascur = iter->MoveNext();
}
trigger = ref new ApplicationTrigger();
@ -70,19 +65,8 @@ void ApplicationTriggerTask::OnNavigatedTo(NavigationEventArgs^ e)
/// <param name="task">The task to attach progress and completed handlers to.</param>
void ApplicationTriggerTask::AttachProgressAndCompletedHandlers(IBackgroundTaskRegistration^ task)
{
auto progress = [this](BackgroundTaskRegistration^ task, BackgroundTaskProgressEventArgs^ args)
{
auto progress = "Progress: " + args->Progress + "%";
BackgroundTaskSample::ApplicationTriggerTaskProgress = progress;
UpdateUI();
};
task->Progress += ref new BackgroundTaskProgressEventHandler(progress);
auto completed = [this](BackgroundTaskRegistration^ task, BackgroundTaskCompletedEventArgs^ args)
{
UpdateUI();
};
task->Completed += ref new BackgroundTaskCompletedEventHandler(completed);
task->Progress += ref new BackgroundTaskProgressEventHandler(this, &ApplicationTriggerTask::OnProgress);
task->Completed += ref new BackgroundTaskCompletedEventHandler(this, &ApplicationTriggerTask::OnCompleted);
}
/// <summary>
@ -135,6 +119,31 @@ void ApplicationTriggerTask::SignalBackgroundTask(Platform::Object^ sender, Wind
UpdateUI();
}
/// <summary>
/// Handle background task progress.
/// </summary>
/// <param name="task">The task that is reporting progress.</param>
/// <param name="args">Arguments of the progress report.</param>
void ApplicationTriggerTask::OnProgress(BackgroundTaskRegistration^ task, BackgroundTaskProgressEventArgs^ args)
{
Dispatcher->RunAsync(CoreDispatcherPriority::Normal, ref new DispatchedHandler([this, args]()
{
auto progress = "Progress: " + args->Progress + "%";
BackgroundTaskSample::ApplicationTriggerTaskProgress = progress;
UpdateUI();
}));
}
/// <summary>
/// Handle background task completion.
/// </summary>
/// <param name="task">The task that is reporting completion.</param>
/// <param name="args">Arguments of the completion report.</param>
void ApplicationTriggerTask::OnCompleted(BackgroundTaskRegistration^ task, BackgroundTaskCompletedEventArgs^ args)
{
UpdateUI();
}
/// <summary>
/// Update the scenario UI.
/// </summary>

Просмотреть файл

@ -41,6 +41,8 @@ namespace SDKTemplate
void RegisterBackgroundTask(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void UnregisterBackgroundTask(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void SignalBackgroundTask(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void OnProgress(Windows::ApplicationModel::Background::BackgroundTaskRegistration^ task, Windows::ApplicationModel::Background::BackgroundTaskProgressEventArgs^ args);
void OnCompleted(Windows::ApplicationModel::Background::BackgroundTaskRegistration^ task, Windows::ApplicationModel::Background::BackgroundTaskCompletedEventArgs^ args);
void UpdateUI();
};
}

Просмотреть файл

@ -13,17 +13,10 @@
#include "SampleBackgroundTask.h"
using namespace Tasks;
using namespace Windows::ApplicationModel::Background;
using namespace Windows::Foundation;
using namespace Windows::Storage;
SampleBackgroundTask::SampleBackgroundTask() :
CancelReason(BackgroundTaskCancellationReason::Abort), CancelRequested(false), TaskDeferral(nullptr), PeriodicTimer(nullptr), Progress(0), TaskInstance(nullptr)
{
}
SampleBackgroundTask::~SampleBackgroundTask()
{
}
using namespace Windows::System::Threading;
void SampleBackgroundTask::Run(IBackgroundTaskInstance^ taskInstance)
{
@ -60,11 +53,12 @@ void SampleBackgroundTask::Run(IBackgroundTaskInstance^ taskInstance)
PeriodicTimer->Cancel();
//
// Write to LocalSettings to indicate that this background task ran.
// Record that this background task ran.
//
auto settings = ApplicationData::Current->LocalSettings;
auto taskStatus = (Progress < 100) ? "Canceled with reason: " + CancelReason.ToString() : "Completed";
auto key = TaskInstance->Task->Name;
settings->Values->Insert(key, (Progress < 100) ? "Canceled with reason: " + CancelReason.ToString() : "Completed");
auto settings = ApplicationData::Current->LocalSettings;
settings->Values->Insert(key, taskStatus);
//
// Indicate that the background task has completed.

Просмотреть файл

@ -10,32 +10,22 @@
#pragma once
#include "pch.h"
#include <agile.h>
using namespace Windows::ApplicationModel::Background;
using namespace Windows::System::Threading;
namespace Tasks
{
[Windows::Foundation::Metadata::WebHostHidden]
public ref class SampleBackgroundTask sealed : public IBackgroundTask
public ref class SampleBackgroundTask sealed : public Windows::ApplicationModel::Background::IBackgroundTask
{
public:
SampleBackgroundTask();
virtual void Run(IBackgroundTaskInstance^ taskInstance);
void OnCanceled(IBackgroundTaskInstance^ taskInstance, BackgroundTaskCancellationReason reason);
virtual void Run(Windows::ApplicationModel::Background::IBackgroundTaskInstance^ taskInstance);
void OnCanceled(Windows::ApplicationModel::Background::IBackgroundTaskInstance^ taskInstance, Windows::ApplicationModel::Background::BackgroundTaskCancellationReason reason);
private:
~SampleBackgroundTask();
BackgroundTaskCancellationReason CancelReason;
volatile bool CancelRequested;
Platform::Agile<Windows::ApplicationModel::Background::BackgroundTaskDeferral> TaskDeferral;
ThreadPoolTimer^ PeriodicTimer;
unsigned int Progress;
IBackgroundTaskInstance^ TaskInstance;
Windows::ApplicationModel::Background::BackgroundTaskCancellationReason CancelReason = Windows::ApplicationModel::Background::BackgroundTaskCancellationReason::Abort;
volatile bool CancelRequested = false;
Platform::Agile<Windows::ApplicationModel::Background::BackgroundTaskDeferral> TaskDeferral = nullptr;
Windows::System::Threading::ThreadPoolTimer^ PeriodicTimer = nullptr;
unsigned int Progress = 0;
Windows::ApplicationModel::Background::IBackgroundTaskInstance^ TaskInstance = nullptr;
};
}

Просмотреть файл

@ -74,11 +74,12 @@ namespace SDKTemplate
/// <param name="name">A name for the background task.</param>
/// <param name="trigger">The trigger for the background task.</param>
/// <param name="condition">An optional conditional event that must be true for the task to fire.</param>
public static async Task<BackgroundTaskRegistration> RegisterBackgroundTask(String taskEntryPoint, String name, IBackgroundTrigger trigger, IBackgroundCondition condition)
public static BackgroundTaskRegistration RegisterBackgroundTask(String taskEntryPoint, String name, IBackgroundTrigger trigger, IBackgroundCondition condition)
{
if (TaskRequiresBackgroundAccess(name))
{
await BackgroundExecutionManager.RequestAccessAsync();
// If the user denies access, the task will not run.
var requestTask = BackgroundExecutionManager.RequestAccessAsync();
}
var builder = new BackgroundTaskBuilder();
@ -100,10 +101,10 @@ namespace SDKTemplate
BackgroundTaskRegistration task = builder.Register();
UpdateBackgroundTaskStatus(name, true);
UpdateBackgroundTaskRegistrationStatus(name, true);
//
// Remove previous completion status from local settings.
// Remove previous completion status.
//
var settings = ApplicationData.Current.LocalSettings;
settings.Values.Remove(name);
@ -129,7 +130,7 @@ namespace SDKTemplate
}
}
UpdateBackgroundTaskStatus(name, false);
UpdateBackgroundTaskRegistrationStatus(name, false);
}
/// <summary>
@ -137,7 +138,7 @@ namespace SDKTemplate
/// </summary>
/// <param name="name">Name of background task to store registration status for.</param>
/// <param name="registered">TRUE if registered, FALSE if unregistered.</param>
public static void UpdateBackgroundTaskStatus(String name, bool registered)
public static void UpdateBackgroundTaskRegistrationStatus(String name, bool registered)
{
switch (name)
{
@ -188,10 +189,11 @@ namespace SDKTemplate
var status = registered ? "Registered" : "Unregistered";
object taskStatus;
var settings = ApplicationData.Current.LocalSettings;
if (settings.Values.ContainsKey(name))
if (settings.Values.TryGetValue(name, out taskStatus))
{
status += " - " + settings.Values[name].ToString();
status += " - " + taskStatus.ToString();
}
return status;

Просмотреть файл

@ -48,7 +48,7 @@ namespace SDKTemplate
if (task.Value.Name == BackgroundTaskSample.SampleBackgroundTaskName)
{
AttachProgressAndCompletedHandlers(task.Value);
BackgroundTaskSample.UpdateBackgroundTaskStatus(BackgroundTaskSample.SampleBackgroundTaskName, true);
BackgroundTaskSample.UpdateBackgroundTaskRegistrationStatus(BackgroundTaskSample.SampleBackgroundTaskName, true);
break;
}
}
@ -61,14 +61,13 @@ namespace SDKTemplate
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void RegisterBackgroundTask(object sender, RoutedEventArgs e)
private void RegisterBackgroundTask(object sender, RoutedEventArgs e)
{
var task = BackgroundTaskSample.RegisterBackgroundTask(BackgroundTaskSample.SampleBackgroundTaskEntryPoint,
BackgroundTaskSample.SampleBackgroundTaskName,
new SystemTrigger(SystemTriggerType.TimeZoneChange, false),
null);
await task;
AttachProgressAndCompletedHandlers(task.Result);
AttachProgressAndCompletedHandlers(task);
UpdateUI();
}
@ -100,9 +99,12 @@ namespace SDKTemplate
/// <param name="e">Arguments of the progress report.</param>
private void OnProgress(IBackgroundTaskRegistration task, BackgroundTaskProgressEventArgs args)
{
var progress = "Progress: " + args.Progress + "%";
BackgroundTaskSample.SampleBackgroundTaskProgress = progress;
UpdateUI();
var ignored = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
var progress = "Progress: " + args.Progress + "%";
BackgroundTaskSample.SampleBackgroundTaskProgress = progress;
UpdateUI();
});
}
/// <summary>

Просмотреть файл

@ -49,7 +49,7 @@ namespace SDKTemplate
if (task.Value.Name == BackgroundTaskSample.SampleBackgroundTaskWithConditionName)
{
AttachProgressAndCompletedHandlers(task.Value);
BackgroundTaskSample.UpdateBackgroundTaskStatus(BackgroundTaskSample.SampleBackgroundTaskWithConditionName, true);
BackgroundTaskSample.UpdateBackgroundTaskRegistrationStatus(BackgroundTaskSample.SampleBackgroundTaskWithConditionName, true);
break;
}
}
@ -62,14 +62,13 @@ namespace SDKTemplate
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void RegisterBackgroundTask(object sender, RoutedEventArgs e)
private void RegisterBackgroundTask(object sender, RoutedEventArgs e)
{
var task = BackgroundTaskSample.RegisterBackgroundTask(BackgroundTaskSample.SampleBackgroundTaskEntryPoint,
BackgroundTaskSample.SampleBackgroundTaskWithConditionName,
new SystemTrigger(SystemTriggerType.TimeZoneChange, false),
new SystemCondition(SystemConditionType.InternetAvailable));
await task;
AttachProgressAndCompletedHandlers(task.Result);
AttachProgressAndCompletedHandlers(task);
UpdateUI();
}
@ -101,9 +100,12 @@ namespace SDKTemplate
/// <param name="e">Arguments of the progress report.</param>
private void OnProgress(IBackgroundTaskRegistration task, BackgroundTaskProgressEventArgs args)
{
var progress = "Progress: " + args.Progress + "%";
BackgroundTaskSample.SampleBackgroundTaskWithConditionProgress = progress;
UpdateUI();
var ignored = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
var progress = "Progress: " + args.Progress + "%";
BackgroundTaskSample.SampleBackgroundTaskWithConditionProgress = progress;
UpdateUI();
});
}
/// <summary>

Просмотреть файл

@ -48,7 +48,7 @@ namespace SDKTemplate
if (task.Value.Name == BackgroundTaskSample.ServicingCompleteTaskName)
{
AttachProgressAndCompletedHandlers(task.Value);
BackgroundTaskSample.UpdateBackgroundTaskStatus(BackgroundTaskSample.ServicingCompleteTaskName, true);
BackgroundTaskSample.UpdateBackgroundTaskRegistrationStatus(BackgroundTaskSample.ServicingCompleteTaskName, true);
break;
}
}
@ -61,14 +61,13 @@ namespace SDKTemplate
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void RegisterBackgroundTask(object sender, RoutedEventArgs e)
private void RegisterBackgroundTask(object sender, RoutedEventArgs e)
{
var task = BackgroundTaskSample.RegisterBackgroundTask(BackgroundTaskSample.ServicingCompleteTaskEntryPoint,
BackgroundTaskSample.ServicingCompleteTaskName,
new SystemTrigger(SystemTriggerType.ServicingComplete, false),
null);
await task;
AttachProgressAndCompletedHandlers(task.Result);
AttachProgressAndCompletedHandlers(task);
UpdateUI();
}
@ -100,9 +99,12 @@ namespace SDKTemplate
/// <param name="e">Arguments of the progress report.</param>
private void OnProgress(IBackgroundTaskRegistration task, BackgroundTaskProgressEventArgs args)
{
var progress = "Progress: " + args.Progress + "%";
BackgroundTaskSample.ServicingCompleteTaskProgress = progress;
UpdateUI();
var ignored = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
var progress = "Progress: " + args.Progress + "%";
BackgroundTaskSample.ServicingCompleteTaskProgress = progress;
UpdateUI();
});
}
/// <summary>

Просмотреть файл

@ -48,7 +48,7 @@ namespace SDKTemplate
if (task.Value.Name == BackgroundTaskSample.TimeTriggeredTaskName)
{
AttachProgressAndCompletedHandlers(task.Value);
BackgroundTaskSample.UpdateBackgroundTaskStatus(BackgroundTaskSample.TimeTriggeredTaskName, true);
BackgroundTaskSample.UpdateBackgroundTaskRegistrationStatus(BackgroundTaskSample.TimeTriggeredTaskName, true);
break;
}
}
@ -61,14 +61,13 @@ namespace SDKTemplate
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void RegisterBackgroundTask(object sender, RoutedEventArgs e)
private void RegisterBackgroundTask(object sender, RoutedEventArgs e)
{
var task = BackgroundTaskSample.RegisterBackgroundTask(BackgroundTaskSample.SampleBackgroundTaskEntryPoint,
BackgroundTaskSample.TimeTriggeredTaskName,
new TimeTrigger(15, false),
null);
await task;
AttachProgressAndCompletedHandlers(task.Result);
AttachProgressAndCompletedHandlers(task);
UpdateUI();
}
@ -100,9 +99,12 @@ namespace SDKTemplate
/// <param name="e">Arguments of the progress report.</param>
private void OnProgress(IBackgroundTaskRegistration task, BackgroundTaskProgressEventArgs args)
{
var progress = "Progress: " + args.Progress + "%";
BackgroundTaskSample.TimeTriggeredTaskProgress = progress;
UpdateUI();
var ignored = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
var progress = "Progress: " + args.Progress + "%";
BackgroundTaskSample.TimeTriggeredTaskProgress = progress;
UpdateUI();
});
}
/// <summary>

Просмотреть файл

@ -51,7 +51,7 @@ namespace SDKTemplate
if (task.Value.Name == BackgroundTaskSample.ApplicationTriggerTaskName)
{
AttachProgressAndCompletedHandlers(task.Value);
BackgroundTaskSample.UpdateBackgroundTaskStatus(BackgroundTaskSample.ApplicationTriggerTaskName, true);
BackgroundTaskSample.UpdateBackgroundTaskRegistrationStatus(BackgroundTaskSample.ApplicationTriggerTaskName, true);
break;
}
}
@ -65,14 +65,13 @@ namespace SDKTemplate
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void RegisterBackgroundTask(object sender, RoutedEventArgs e)
private void RegisterBackgroundTask(object sender, RoutedEventArgs e)
{
var task = BackgroundTaskSample.RegisterBackgroundTask(BackgroundTaskSample.SampleBackgroundTaskEntryPoint,
BackgroundTaskSample.ApplicationTriggerTaskName,
trigger,
null);
await task;
AttachProgressAndCompletedHandlers(task.Result);
AttachProgressAndCompletedHandlers(task);
UpdateUI();
}
@ -122,9 +121,12 @@ namespace SDKTemplate
/// <param name="e">Arguments of the progress report.</param>
private void OnProgress(IBackgroundTaskRegistration task, BackgroundTaskProgressEventArgs args)
{
var progress = "Progress: " + args.Progress + "%";
BackgroundTaskSample.ApplicationTriggerTaskProgress = progress;
UpdateUI();
var ignored = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
var progress = "Progress: " + args.Progress + "%";
BackgroundTaskSample.ApplicationTriggerTaskProgress = progress;
UpdateUI();
});
}
/// <summary>

Просмотреть файл

@ -91,13 +91,14 @@ namespace Tasks
{
_periodicTimer.Cancel();
var settings = ApplicationData.Current.LocalSettings;
var key = _taskInstance.Task.Name;
//
// Write to LocalSettings to indicate that this background task ran.
// Record that this background task ran.
//
settings.Values[key] = (_progress < 100) ? "Canceled with reason: " + _cancelReason.ToString() : "Completed";
String taskStatus = (_progress < 100) ? "Canceled with reason: " + _cancelReason.ToString() : "Completed";
var settings = ApplicationData.Current.LocalSettings;
settings.Values[key] = taskStatus;
Debug.WriteLine("Background " + _taskInstance.Task.Name + settings.Values[key]);
//

Просмотреть файл

@ -81,9 +81,10 @@ Namespace Global.SDKTemplate
''' <param name="name">A name for the background task.</param>
''' <param name="trigger">The trigger for the background task.</param>
''' <param name="condition">An optional conditional event that must be true for the task to fire.</param>
Public Shared Async Function RegisterBackgroundTask(taskEntryPoint As String, name As String, trigger As IBackgroundTrigger, condition As IBackgroundCondition) As Task(Of BackgroundTaskRegistration)
Public Shared Function RegisterBackgroundTask(taskEntryPoint As String, name As String, trigger As IBackgroundTrigger, condition As IBackgroundCondition) As BackgroundTaskRegistration
If TaskRequiresBackgroundAccess(name) Then
Await BackgroundExecutionManager.RequestAccessAsync()
' If the user denies access, the task will not run.
Dim requestTask = BackgroundExecutionManager.RequestAccessAsync()
End If
Dim builder = New BackgroundTaskBuilder()
@ -96,9 +97,9 @@ Namespace Global.SDKTemplate
End If
Dim task As BackgroundTaskRegistration = builder.Register()
UpdateBackgroundTaskStatus(name, True)
UpdateBackgroundTaskRegistrationStatus(name, True)
'
' Remove previous completion status from local settings.
' Remove previous completion status.
'
Dim settings = ApplicationData.Current.LocalSettings
settings.Values.Remove(name)
@ -116,7 +117,7 @@ Namespace Global.SDKTemplate
End If
Next
UpdateBackgroundTaskStatus(name, False)
UpdateBackgroundTaskRegistrationStatus(name, False)
End Sub
''' <summary>
@ -124,7 +125,7 @@ Namespace Global.SDKTemplate
''' </summary>
''' <param name="name">Name of background task to store registration status for.</param>
''' <param name="registered">TRUE if registered, FALSE if unregistered.</param>
Public Shared Sub UpdateBackgroundTaskStatus(name As String, registered As Boolean)
Public Shared Sub UpdateBackgroundTaskRegistrationStatus(name As String, registered As Boolean)
Select name
Case SampleBackgroundTaskName
SampleBackgroundTaskRegistered = registered
@ -160,9 +161,10 @@ Namespace Global.SDKTemplate
End Select
Dim status = If(registered, "Registered", "Unregistered")
Dim taskStatus As Object = Nothing
Dim settings = ApplicationData.Current.LocalSettings
If settings.Values.ContainsKey(name) Then
status &= " - " & settings.Values(name).ToString()
If settings.Values.TryGetValue(name, taskStatus) Then
status &= " - " & taskStatus.ToString()
End If
Return status
@ -173,7 +175,7 @@ Namespace Global.SDKTemplate
''' </summary>
''' <param name="name">Name of background task to query background access requirement.</param>
Public Shared Function TaskRequiresBackgroundAccess(name As String) As Boolean
If(name = TimeTriggeredTaskName) OrElse (name = ApplicationTriggerTaskName) Then
If (name = TimeTriggeredTaskName) OrElse (name = ApplicationTriggerTaskName) Then
Return True
Else
Return False

Просмотреть файл

@ -42,7 +42,7 @@ Namespace Global.SDKTemplate
For Each task In BackgroundTaskRegistration.AllTasks
If task.Value.Name = BackgroundTaskSample.SampleBackgroundTaskName Then
AttachProgressAndCompletedHandlers(task.Value)
BackgroundTaskSample.UpdateBackgroundTaskStatus(BackgroundTaskSample.SampleBackgroundTaskName, True)
BackgroundTaskSample.UpdateBackgroundTaskRegistrationStatus(BackgroundTaskSample.SampleBackgroundTaskName, True)
Exit For
End If
Next
@ -55,10 +55,9 @@ Namespace Global.SDKTemplate
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
Private Async Sub RegisterBackgroundTask(sender As Object, e As RoutedEventArgs)
Private Sub RegisterBackgroundTask(sender As Object, e As RoutedEventArgs)
Dim task = BackgroundTaskSample.RegisterBackgroundTask(BackgroundTaskSample.SampleBackgroundTaskEntryPoint, BackgroundTaskSample.SampleBackgroundTaskName, New SystemTrigger(SystemTriggerType.TimeZoneChange, False), Nothing)
Await task
AttachProgressAndCompletedHandlers(task.Result)
AttachProgressAndCompletedHandlers(task)
UpdateUI()
End Sub
@ -87,9 +86,11 @@ Namespace Global.SDKTemplate
''' <param name="task">The task that is reporting progress.</param>
''' <param name="e">Arguments of the progress report.</param>
Private Sub OnProgress(task As IBackgroundTaskRegistration, args As BackgroundTaskProgressEventArgs)
Dim progress = "Progress: " & args.Progress & "%"
BackgroundTaskSample.SampleBackgroundTaskProgress = progress
UpdateUI()
Dim ignored = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, Sub()
Dim progress = "Progress: " & args.Progress & "%"
BackgroundTaskSample.SampleBackgroundTaskProgress = progress
UpdateUI()
End Sub)
End Sub
''' <summary>

Просмотреть файл

@ -40,7 +40,7 @@ Namespace Global.SDKTemplate
For Each task In BackgroundTaskRegistration.AllTasks
If task.Value.Name = BackgroundTaskSample.SampleBackgroundTaskWithConditionName Then
AttachProgressAndCompletedHandlers(task.Value)
BackgroundTaskSample.UpdateBackgroundTaskStatus(BackgroundTaskSample.SampleBackgroundTaskWithConditionName, True)
BackgroundTaskSample.UpdateBackgroundTaskRegistrationStatus(BackgroundTaskSample.SampleBackgroundTaskWithConditionName, True)
Exit For
End If
Next
@ -53,10 +53,9 @@ Namespace Global.SDKTemplate
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
Private Async Sub RegisterBackgroundTask(sender As Object, e As RoutedEventArgs)
Private Sub RegisterBackgroundTask(sender As Object, e As RoutedEventArgs)
Dim task = BackgroundTaskSample.RegisterBackgroundTask(BackgroundTaskSample.SampleBackgroundTaskEntryPoint, BackgroundTaskSample.SampleBackgroundTaskWithConditionName, New SystemTrigger(SystemTriggerType.TimeZoneChange, False), New SystemCondition(SystemConditionType.InternetAvailable))
Await task
AttachProgressAndCompletedHandlers(task.Result)
AttachProgressAndCompletedHandlers(task)
UpdateUI()
End Sub
@ -85,9 +84,11 @@ Namespace Global.SDKTemplate
''' <param name="task">The task that is reporting progress.</param>
''' <param name="e">Arguments of the progress report.</param>
Private Sub OnProgress(task As IBackgroundTaskRegistration, args As BackgroundTaskProgressEventArgs)
Dim progress = "Progress: " & args.Progress & "%"
BackgroundTaskSample.SampleBackgroundTaskWithConditionProgress = progress
UpdateUI()
Dim ignored = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, Sub()
Dim progress = "Progress: " & args.Progress & "%"
BackgroundTaskSample.SampleBackgroundTaskWithConditionProgress = progress
UpdateUI()
End Sub)
End Sub
''' <summary>

Просмотреть файл

@ -40,7 +40,7 @@ Namespace Global.SDKTemplate
For Each task In BackgroundTaskRegistration.AllTasks
If task.Value.Name = BackgroundTaskSample.ServicingCompleteTaskName Then
AttachProgressAndCompletedHandlers(task.Value)
BackgroundTaskSample.UpdateBackgroundTaskStatus(BackgroundTaskSample.ServicingCompleteTaskName, True)
BackgroundTaskSample.UpdateBackgroundTaskRegistrationStatus(BackgroundTaskSample.ServicingCompleteTaskName, True)
Exit For
End If
Next
@ -53,10 +53,9 @@ Namespace Global.SDKTemplate
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
Private Async Sub RegisterBackgroundTask(sender As Object, e As RoutedEventArgs)
Private Sub RegisterBackgroundTask(sender As Object, e As RoutedEventArgs)
Dim task = BackgroundTaskSample.RegisterBackgroundTask(BackgroundTaskSample.ServicingCompleteTaskEntryPoint, BackgroundTaskSample.ServicingCompleteTaskName, New SystemTrigger(SystemTriggerType.ServicingComplete, False), Nothing)
Await task
AttachProgressAndCompletedHandlers(task.Result)
AttachProgressAndCompletedHandlers(task)
UpdateUI()
End Sub
@ -85,9 +84,11 @@ Namespace Global.SDKTemplate
''' <param name="task">The task that is reporting progress.</param>
''' <param name="e">Arguments of the progress report.</param>
Private Sub OnProgress(task As IBackgroundTaskRegistration, args As BackgroundTaskProgressEventArgs)
Dim progress = "Progress: " & args.Progress & "%"
BackgroundTaskSample.ServicingCompleteTaskProgress = progress
UpdateUI()
Dim ignored = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, Sub()
Dim progress = "Progress: " & args.Progress & "%"
BackgroundTaskSample.ServicingCompleteTaskProgress = progress
UpdateUI()
End Sub)
End Sub
''' <summary>

Просмотреть файл

@ -40,7 +40,7 @@ Namespace Global.SDKTemplate
For Each task In BackgroundTaskRegistration.AllTasks
If task.Value.Name = BackgroundTaskSample.TimeTriggeredTaskName Then
AttachProgressAndCompletedHandlers(task.Value)
BackgroundTaskSample.UpdateBackgroundTaskStatus(BackgroundTaskSample.TimeTriggeredTaskName, True)
BackgroundTaskSample.UpdateBackgroundTaskRegistrationStatus(BackgroundTaskSample.TimeTriggeredTaskName, True)
Exit For
End If
Next
@ -53,10 +53,9 @@ Namespace Global.SDKTemplate
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
Private Async Sub RegisterBackgroundTask(sender As Object, e As RoutedEventArgs)
Private Sub RegisterBackgroundTask(sender As Object, e As RoutedEventArgs)
Dim task = BackgroundTaskSample.RegisterBackgroundTask(BackgroundTaskSample.SampleBackgroundTaskEntryPoint, BackgroundTaskSample.TimeTriggeredTaskName, New TimeTrigger(15, False), Nothing)
Await task
AttachProgressAndCompletedHandlers(task.Result)
AttachProgressAndCompletedHandlers(task)
UpdateUI()
End Sub
@ -85,9 +84,11 @@ Namespace Global.SDKTemplate
''' <param name="task">The task that is reporting progress.</param>
''' <param name="e">Arguments of the progress report.</param>
Private Sub OnProgress(task As IBackgroundTaskRegistration, args As BackgroundTaskProgressEventArgs)
Dim progress = "Progress: " & args.Progress & "%"
BackgroundTaskSample.TimeTriggeredTaskProgress = progress
UpdateUI()
Dim ignored = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, Sub()
Dim progress = "Progress: " & args.Progress & "%"
BackgroundTaskSample.TimeTriggeredTaskProgress = progress
UpdateUI()
End Sub)
End Sub
''' <summary>

Просмотреть файл

@ -42,7 +42,7 @@ Namespace Global.SDKTemplate
For Each task In BackgroundTaskRegistration.AllTasks
If task.Value.Name = BackgroundTaskSample.ApplicationTriggerTaskName Then
AttachProgressAndCompletedHandlers(task.Value)
BackgroundTaskSample.UpdateBackgroundTaskStatus(BackgroundTaskSample.ApplicationTriggerTaskName, True)
BackgroundTaskSample.UpdateBackgroundTaskRegistrationStatus(BackgroundTaskSample.ApplicationTriggerTaskName, True)
Exit For
End If
Next
@ -56,10 +56,9 @@ Namespace Global.SDKTemplate
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
Private Async Sub RegisterBackgroundTask(sender As Object, e As RoutedEventArgs)
Private Sub RegisterBackgroundTask(sender As Object, e As RoutedEventArgs)
Dim task = BackgroundTaskSample.RegisterBackgroundTask(BackgroundTaskSample.SampleBackgroundTaskEntryPoint, BackgroundTaskSample.ApplicationTriggerTaskName, trigger, Nothing)
Await task
AttachProgressAndCompletedHandlers(task.Result)
AttachProgressAndCompletedHandlers(task)
UpdateUI()
End Sub
@ -104,9 +103,11 @@ Namespace Global.SDKTemplate
''' <param name="task">The task that is reporting progress.</param>
''' <param name="e">Arguments of the progress report.</param>
Private Sub OnProgress(task As IBackgroundTaskRegistration, args As BackgroundTaskProgressEventArgs)
Dim progress = "Progress: " & args.Progress & "%"
BackgroundTaskSample.ApplicationTriggerTaskProgress = progress
UpdateUI()
Dim ignored = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, Sub()
Dim progress = "Progress: " & args.Progress & "%"
BackgroundTaskSample.ApplicationTriggerTaskProgress = progress
UpdateUI()
End Sub)
End Sub
''' <summary>

Просмотреть файл

@ -72,10 +72,11 @@ Namespace Global.Tasks
_taskInstance.Progress = _progress
Else
_periodicTimer.Cancel()
Dim settings = ApplicationData.Current.LocalSettings
Dim status As String = If((_progress < 100), "Canceled with reason: " & _cancelReason.ToString(), "Completed")
Dim key = _taskInstance.Task.Name
settings.Values(key) = If((_progress < 100), "Canceled with reason: " & _cancelReason.ToString(), "Completed")
Debug.WriteLine("Background " & _taskInstance.Task.Name & settings.Values(key))
Dim settings = ApplicationData.Current.LocalSettings
settings.Values(key) = status
Debug.WriteLine("Background " & _taskInstance.Task.Name & status)
_deferral.Complete()
End If
End Sub

Просмотреть файл

@ -5,17 +5,18 @@
# Barcode scanner sample
This sample shows how to create a barcode scanner, claim it for exclusive use, enable it to receive data, and read a barcode. This sample uses [**Windows.Devices.PointOfService**](http://msdn.microsoft.com/library/windows/apps/dn298071) API.
This sample shows how to obtain a barcode scanner,
claim it for exclusive use, enable it to receive data, and read a barcode.
Specifically, this sample shows how to:
1. **Create the barcode scanner**
1. **Obtain the barcode scanner**
Uses the [**BarcodeScanner.GetDefaultAsync**](http://msdn.microsoft.com/library/windows/apps/dn263790) to get the first available barcode scanner.
Uses [**BarcodeScanner.GetDefaultAsync**](http://msdn.microsoft.com/library/windows/apps/dn263790) to get the first available barcode scanner.
2. **Claim the barcode scanner for exclusive use**
Uses the [**ClaimScannerAsync**](http://msdn.microsoft.com/library/windows/apps/dn297696) to claim the device.
Uses [**ClaimScannerAsync**](http://msdn.microsoft.com/library/windows/apps/dn297696) to claim the device.
3. **Add event handlers**
@ -41,13 +42,9 @@ To obtain information about Microsoft Visual Studio 2015 and the tools for devel
## Related topics
### Samples
[Barcode Scanner sample](/Samples/BarcodeScanner)
### Reference
[Windows.Devices.PointOfService](http://msdn.microsoft.com/library/windows/apps/dn298071)
[Windows.Devices.PointOfService namespace](http://msdn.microsoft.com/library/windows/apps/dn298071)
[USB HID POS Scanner specification](http://go.microsoft.com/fwlink/p/?linkid=309230)

Просмотреть файл

@ -4,7 +4,7 @@
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:mobile="http://schemas.microsoft.com/appx/manifest/mobile/windows10"
IgnorableNamespaces="uap mp"
IgnorableNamespaces="uap mp mobile"
>
<Identity Name="Microsoft.SDKSamples.CallerID.CS" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" Version="1.0.0.0"/>
<mp:PhoneIdentity PhoneProductId="2ae61f23-a2f1-48d1-8f76-57a630592a18" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>

Просмотреть файл

@ -47,6 +47,7 @@ MainPage::MainPage()
, _displayOrientation(DisplayOrientations::Portrait)
, _displayRequest(ref new Windows::System::Display::DisplayRequest())
, RotationKey({ 0xC380465D, 0x2271, 0x428C,{ 0x9B, 0x83, 0xEC, 0xEA, 0x3B, 0x4A, 0x85, 0xC1 } })
, _captureFolder(nullptr)
{
InitializeComponent();
@ -334,14 +335,17 @@ task<void> MainPage::TakePhotoAsync()
return create_task(_mediaCapture->CapturePhotoToStreamAsync(Windows::Media::MediaProperties::ImageEncodingProperties::CreateJpeg(), inputStream))
.then([this, inputStream]()
{
WriteLine("Photo taken!");
return create_task(_captureFolder->CreateFileAsync("SimplePhoto.jpg", CreationCollisionOption::GenerateUniqueName));
}).then([this, inputStream](StorageFile^ file)
{
WriteLine("Photo taken! Saving to " + file->Path);
// Done taking a photo, so re-enable the button
VideoButton->IsEnabled = true;
VideoButton->Opacity = 1;
auto photoOrientation = ConvertOrientationToPhotoOrientation(GetCameraOrientation());
return ReencodeAndSavePhotoAsync(inputStream, photoOrientation);
return ReencodeAndSavePhotoAsync(inputStream, file, photoOrientation);
}).then([this](task<void> previousTask)
{
try
@ -362,7 +366,7 @@ task<void> MainPage::TakePhotoAsync()
/// <returns></returns>
task<void> MainPage::StartRecordingAsync()
{
return create_task(KnownFolders::PicturesLibrary->CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption::GenerateUniqueName))
return create_task(_captureFolder->CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption::GenerateUniqueName))
.then([this](StorageFile^ file)
{
// Calculate rotation angle, taking mirroring into account if necessary
@ -370,12 +374,11 @@ task<void> MainPage::StartRecordingAsync()
auto encodingProfile = MediaProperties::MediaEncodingProfile::CreateMp4(MediaProperties::VideoEncodingQuality::Auto);
encodingProfile->Video->Properties->Insert(RotationKey, rotationAngle);
WriteLine("Starting recording...");
return create_task(_mediaCapture->StartRecordToStorageFileAsync(encodingProfile, file))
.then([this]()
.then([this, file]()
{
_isRecording = true;
WriteLine("Started recording!");
WriteLine("Started recording to " + file->Path);
});
}).then([this](task<void> previousTask)
{
@ -444,22 +447,21 @@ task<DeviceInformation^> MainPage::FindCameraDeviceByPanelAsync(Windows::Devices
/// Applies the given orientation to a photo stream and saves it as a StorageFile
/// </summary>
/// <param name="stream">The photo stream</param>
/// <param name="file">The StorageFile in which the photo stream will be saved</param>
/// <param name="photoOrientation">The orientation metadata to apply to the photo</param>
/// <returns></returns>
task<void> MainPage::ReencodeAndSavePhotoAsync(Streams::IRandomAccessStream^ stream, FileProperties::PhotoOrientation photoOrientation)
task<void> MainPage::ReencodeAndSavePhotoAsync(Streams::IRandomAccessStream^ stream, StorageFile^ file, FileProperties::PhotoOrientation photoOrientation)
{
// Using this state variable to pass multiple values through our task chain
ReencodeState^ state = ref new ReencodeState();
state->_file = file;
state->_orientation = photoOrientation;
return create_task(BitmapDecoder::CreateAsync(stream))
.then([state](BitmapDecoder^ decoder)
{
state->_decoder = decoder;
return create_task(KnownFolders::PicturesLibrary->CreateFileAsync("SimplePhoto.jpg", CreationCollisionOption::GenerateUniqueName));
}).then([](StorageFile^ file)
{
return create_task(file->OpenAsync(FileAccessMode::ReadWrite));
return create_task(state->_file->OpenAsync(FileAccessMode::ReadWrite));
}).then([state](Streams::IRandomAccessStream^ outputStream)
{
return create_task(BitmapEncoder::CreateForTranscodingAsync(outputStream, state->_decoder));
@ -528,6 +530,17 @@ task<void> MainPage::SetupUiAsync()
_deviceOrientation = _orientationSensor->GetCurrentOrientation();
}
create_task(StorageLibrary::GetLibraryAsync(KnownLibraryId::Pictures))
.then([this](StorageLibrary^ picturesLibrary)
{
_captureFolder = picturesLibrary->SaveFolder;
if (_captureFolder == nullptr)
{
// In this case fall back to the local app storage since the Pictures Library is not available
_captureFolder = ApplicationData::Current->LocalFolder;
}
});
// Hide the status bar
if (Windows::Foundation::Metadata::ApiInformation::IsTypePresent("Windows.UI.ViewManagement.StatusBar"))
{
@ -1006,12 +1019,12 @@ void MainPage::DisplayInformation_OrientationChanged(DisplayInformation^ sender,
}));
}
void MainPage::PhotoButton_Tapped(Object^, Windows::UI::Xaml::RoutedEventArgs^)
void MainPage::PhotoButton_Click(Object^, Windows::UI::Xaml::RoutedEventArgs^)
{
TakePhotoAsync();
}
void MainPage::VideoButton_Tapped(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
void MainPage::VideoButton_Click(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
task<void> taskToExecute;
if (!_isRecording)
@ -1030,7 +1043,7 @@ void MainPage::VideoButton_Tapped(Object^ sender, Windows::UI::Xaml::RoutedEvent
});
}
void MainPage::FaceDetectionButton_Tapped(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
void MainPage::FaceDetectionButton_Click(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
task<void> taskToExecute;

Просмотреть файл

@ -20,6 +20,7 @@ namespace FaceDetection
internal:
Windows::Graphics::Imaging::BitmapDecoder^ _decoder;
Windows::Graphics::Imaging::BitmapEncoder^ _encoder;
Windows::Storage::StorageFile^ _file;
Windows::Storage::FileProperties::PhotoOrientation _orientation;
};
@ -54,6 +55,9 @@ namespace FaceDetection
// Reference: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868174.aspx
const GUID RotationKey;
// Folder in which the captures will be stored (availability check performed in SetupUiAsync)
Windows::Storage::StorageFolder^ _captureFolder;
// Event tokens
Windows::Foundation::EventRegistrationToken _applicationSuspendingEventToken;
Windows::Foundation::EventRegistrationToken _applicationResumingEventToken;
@ -79,7 +83,7 @@ namespace FaceDetection
// Helpers
Concurrency::task<Windows::Devices::Enumeration::DeviceInformation^> FindCameraDeviceByPanelAsync(Windows::Devices::Enumeration::Panel panel);
Concurrency::task<void> ReencodeAndSavePhotoAsync(Windows::Storage::Streams::IRandomAccessStream^ stream, Windows::Storage::FileProperties::PhotoOrientation photoOrientation);
Concurrency::task<void> ReencodeAndSavePhotoAsync(Windows::Storage::Streams::IRandomAccessStream^ stream, Windows::Storage::StorageFile^ file, Windows::Storage::FileProperties::PhotoOrientation photoOrientation);
void UpdateCaptureControls();
Concurrency::task<void> SetupUiAsync();
Concurrency::task<void> CleanupUiAsync();
@ -106,10 +110,10 @@ namespace FaceDetection
void Application_Suspending(Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ e);
void Application_Resuming(Object^ sender, Object^ args);
void DisplayInformation_OrientationChanged(Windows::Graphics::Display::DisplayInformation^ sender, Object^ args);
void PhotoButton_Tapped(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void VideoButton_Tapped(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void PhotoButton_Click(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void VideoButton_Click(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void SystemMediaControls_PropertyChanged(Windows::Media::SystemMediaTransportControls^ sender, Windows::Media::SystemMediaTransportControlsPropertyChangedEventArgs^ args);
void FaceDetectionButton_Tapped(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void FaceDetectionButton_Click(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void OrientationSensor_OrientationChanged(Windows::Devices::Sensors::SimpleOrientationSensor^, Windows::Devices::Sensors::SimpleOrientationSensorOrientationChangedEventArgs^);
void HardwareButtons_CameraPressed(Platform::Object^, Windows::Phone::UI::Input::CameraEventArgs^);

Просмотреть файл

@ -55,6 +55,9 @@ namespace FaceDetection
// Reference: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868174.aspx
private static readonly Guid RotationKey = new Guid("C380465D-2271-428C-9B83-ECEA3B4A85C1");
// Folder in which the captures will be stored (initialized in SetupUiAsync)
private StorageFolder _captureFolder = null;
// Prevent the screen from sleeping while the camera is running
private readonly DisplayRequest _displayRequest = new DisplayRequest();
@ -198,12 +201,12 @@ namespace FaceDetection
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => UpdateButtonOrientation());
}
private async void PhotoButton_Tapped(object sender, TappedRoutedEventArgs e)
private async void PhotoButton_Click(object sender, RoutedEventArgs e)
{
await TakePhotoAsync();
}
private async void VideoButton_Tapped(object sender, TappedRoutedEventArgs e)
private async void VideoButton_Click(object sender, RoutedEventArgs e)
{
if (!_isRecording)
{
@ -218,7 +221,7 @@ namespace FaceDetection
UpdateCaptureControls();
}
private async void FaceDetectionButton_Tapped(object sender, TappedRoutedEventArgs e)
private async void FaceDetectionButton_Click(object sender, RoutedEventArgs e)
{
if (_faceDetectionEffect == null || !_faceDetectionEffect.Enabled)
{
@ -456,7 +459,7 @@ namespace FaceDetection
/// <returns></returns>
private async Task TakePhotoAsync()
{
// While taking a photo, keep the video button enabled only if the camera supports simultaneosly taking pictures and recording video
// While taking a photo, keep the video button enabled only if the camera supports simultaneously taking pictures and recording video
VideoButton.IsEnabled = _mediaCapture.MediaCaptureSettings.ConcurrentRecordAndPhotoSupported;
// Make the button invisible if it's disabled, so it's obvious it cannot be interacted with
@ -464,20 +467,25 @@ namespace FaceDetection
var stream = new InMemoryRandomAccessStream();
Debug.WriteLine("Taking photo...");
await _mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), stream);
try
{
Debug.WriteLine("Taking photo...");
await _mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), stream);
Debug.WriteLine("Photo taken!");
var file = await _captureFolder.CreateFileAsync("SimplePhoto.jpg", CreationCollisionOption.GenerateUniqueName);
Debug.WriteLine("Photo taken! Saving to " + file.Path);
var photoOrientation = ConvertOrientationToPhotoOrientation(GetCameraOrientation());
await ReencodeAndSavePhotoAsync(stream, photoOrientation);
await ReencodeAndSavePhotoAsync(stream, file, photoOrientation);
Debug.WriteLine("Photo saved!");
}
catch (Exception ex)
{
// File I/O errors are reported as exceptions
Debug.WriteLine("Exception when taking a photo: {0}", ex.ToString());
Debug.WriteLine("Exception when taking a photo: " + ex.ToString());
}
// Done taking a photo, so re-enable the button
@ -494,7 +502,7 @@ namespace FaceDetection
try
{
// Create storage file in Pictures Library
var videoFile = await KnownFolders.PicturesLibrary.CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption.GenerateUniqueName);
var videoFile = await _captureFolder.CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption.GenerateUniqueName);
var encodingProfile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto);
@ -502,7 +510,7 @@ namespace FaceDetection
var rotationAngle = 360 - ConvertDeviceOrientationToDegrees(GetCameraOrientation());
encodingProfile.Video.Properties.Add(RotationKey, PropertyValue.CreateInt32(rotationAngle));
Debug.WriteLine("Starting recording...");
Debug.WriteLine("Starting recording to " + videoFile.Path);
await _mediaCapture.StartRecordToStorageFileAsync(encodingProfile, videoFile);
_isRecording = true;
@ -512,7 +520,7 @@ namespace FaceDetection
catch (Exception ex)
{
// File I/O errors are reported as exceptions
Debug.WriteLine("Exception when starting video recording: {0}", ex.ToString());
Debug.WriteLine("Exception when starting video recording: " + ex.ToString());
}
}
@ -599,6 +607,10 @@ namespace FaceDetection
}
RegisterEventHandlers();
var picturesLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures);
// Fall back to the local app storage if the Pictures Library is not available
_captureFolder = picturesLibrary.SaveFolder ?? ApplicationData.Current.LocalFolder;
}
/// <summary>
@ -713,16 +725,15 @@ namespace FaceDetection
/// Applies the given orientation to a photo stream and saves it as a StorageFile
/// </summary>
/// <param name="stream">The photo stream</param>
/// <param name="file">The StorageFile in which the photo stream will be saved</param>
/// <param name="photoOrientation">The orientation metadata to apply to the photo</param>
/// <returns></returns>
private static async Task ReencodeAndSavePhotoAsync(IRandomAccessStream stream, PhotoOrientation photoOrientation)
private static async Task ReencodeAndSavePhotoAsync(IRandomAccessStream stream, StorageFile file, PhotoOrientation photoOrientation)
{
using (var inputStream = stream)
{
var decoder = await BitmapDecoder.CreateAsync(inputStream);
var file = await KnownFolders.PicturesLibrary.CreateFileAsync("SimplePhoto.jpeg", CreationCollisionOption.GenerateUniqueName);
using (var outputStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateForTranscodingAsync(outputStream, decoder);

Просмотреть файл

@ -13,7 +13,7 @@
<mp:PhoneIdentity PhoneProductId="d73539b4-c2ee-4d29-bc00-4bfd38e96567" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>
<DisplayName>CameraFaceDetection</DisplayName>
<DisplayName>CameraFaceDetection JS Sample</DisplayName>
<PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
<Logo>images\storelogo-sdk.png</Logo>
</Properties>

Просмотреть файл

@ -20,6 +20,9 @@
var Media = Windows.Media;
var SimpleOrientation = Windows.Devices.Sensors.SimpleOrientation;
var SimpleOrientationSensor = Windows.Devices.Sensors.SimpleOrientationSensor;
var StorageLibrary = Windows.Storage.StorageLibrary;
var KnownLibraryId = Windows.Storage.KnownLibraryId;
var ApplicationData = Windows.Storage.ApplicationData;
// Receive notifications about rotation of the device and UI and apply any necessary rotation to the preview stream and UI controls
var oOrientationSensor = SimpleOrientationSensor.getDefault(),
@ -49,6 +52,9 @@
// Reference: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868174.aspx
var RotationKey = "C380465D-2271-428C-9B83-ECEA3B4A85C1";
// Folder in which the captures will be stored (initialized in SetupUiAsync)
var oCaptureFolder;
// Initialization
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
@ -312,13 +318,18 @@
console.log("Taking photo...");
return oMediaCapture.capturePhotoToStreamAsync(Windows.Media.MediaProperties.ImageEncodingProperties.createJpeg(), inputStream)
.then(function () {
console.log("Photo taken!");
return oCaptureFolder.createFileAsync("SimplePhoto.jpg", Windows.Storage.CreationCollisionOption.generateUniqueName);
})
.then(function (file) {
console.log("Photo taken! Saving to " + file.path);
// Done taking a photo, so re-enable the button
videoButton.isDisabled = false;
var photoOrientation = convertOrientationToPhotoOrientation(getCameraOrientation());
return reencodeAndSavePhotoAsync(inputStream, photoOrientation);
return reencodeAndSavePhotoAsync(inputStream, file, photoOrientation);
}).then(function () {
console.log("Photo saved!");
}, function (error) {
console.log(error.message);
}).done();
@ -329,14 +340,14 @@
/// </summary>
/// <returns></returns>
function startRecordingAsync() {
return Windows.Storage.KnownFolders.picturesLibrary.createFileAsync("SimpleVideo.mp4", Windows.Storage.CreationCollisionOption.generateUniqueName)
return oCaptureFolder.createFileAsync("SimpleVideo.mp4", Windows.Storage.CreationCollisionOption.generateUniqueName)
.then(function (file) {
// Calculate rotation angle, taking mirroring into account if necessary
var rotationAngle = 360 - convertDeviceOrientationToDegrees(getCameraOrientation());
var encodingProfile = Windows.Media.MediaProperties.MediaEncodingProfile.createMp4(Windows.Media.MediaProperties.VideoEncodingQuality.auto);
encodingProfile.video.properties.insert(RotationKey, rotationAngle);
console.log("Starting recording...");
console.log("Starting recording to " + file.path);
return oMediaCapture.startRecordToStorageFileAsync(encodingProfile, file)
.then(function () {
isRecording = true;
@ -390,7 +401,7 @@
/// <param name="stream">The photo stream</param>
/// <param name="photoOrientation">The orientation metadata to apply to the photo</param>
/// <returns></returns>
function reencodeAndSavePhotoAsync(inputStream, orientation) {
function reencodeAndSavePhotoAsync(inputStream, file, orientation) {
var Imaging = Windows.Graphics.Imaging;
var bitmapDecoder = null,
bitmapEncoder = null,
@ -399,8 +410,6 @@
return Imaging.BitmapDecoder.createAsync(inputStream)
.then(function (decoder) {
bitmapDecoder = decoder;
return Windows.Storage.KnownFolders.picturesLibrary.createFileAsync("SimplePhoto.jpg", Windows.Storage.CreationCollisionOption.generateUniqueName);
}).then(function (file) {
return file.openAsync(Windows.Storage.FileAccessMode.readWrite);
}).then(function (outStream) {
outputStream = outStream;
@ -468,13 +477,19 @@
oDeviceOrientation = oOrientationSensor.getCurrentOrientation();
}
// Hide the status bar
if (Windows.Foundation.Metadata.ApiInformation.isTypePresent("Windows.UI.ViewManagement.StatusBar")) {
return Windows.UI.ViewManagement.StatusBar.getForCurrentView().hideAsync();
}
else {
return WinJS.Promise.as();
}
return StorageLibrary.getLibraryAsync(KnownLibraryId.pictures)
.then(function (picturesLibrary) {
// Fall back to the local app storage if the Pictures Library is not available
oCaptureFolder = picturesLibrary.saveFolder || ApplicationData.current.localFolder;
// Hide the status bar
if (Windows.Foundation.Metadata.ApiInformation.isTypePresent("Windows.UI.ViewManagement.StatusBar")) {
return Windows.UI.ViewManagement.StatusBar.getForCurrentView().hideAsync();
}
else {
return WinJS.Promise.as();
}
})
}
/// <summary>

Просмотреть файл

@ -54,13 +54,13 @@
<!-- Capture + Record buttons -->
<StackPanel HorizontalAlignment="Right" VerticalAlignment="Center">
<Button Name="PhotoButton" Tapped="PhotoButton_Tapped" IsEnabled="False">
<Button Name="PhotoButton" Click="PhotoButton_Click" IsEnabled="False">
<Viewbox>
<SymbolIcon Symbol="Camera"/>
</Viewbox>
</Button>
<Button Name="VideoButton" Tapped="VideoButton_Tapped" IsEnabled="False">
<Button Name="VideoButton" Click="VideoButton_Click" IsEnabled="False">
<Grid>
<Ellipse x:Name="StartRecordingIcon" Fill="Red" Width="20" Height="20"/>
<Rectangle x:Name="StopRecordingIcon" Fill="White" Width="20" Height="20" Visibility="Collapsed"/>
@ -69,7 +69,7 @@
</StackPanel>
<!--Button to enable / disable face detection-->
<Button Name="FaceDetectionButton" Tapped="FaceDetectionButton_Tapped" IsEnabled="False">
<Button Name="FaceDetectionButton" Click="FaceDetectionButton_Click" IsEnabled="False">
<Viewbox>
<Grid>
<SymbolIcon Name="FaceDetectionDisabledIcon" Symbol="Contact" Visibility="Visible"/>

Просмотреть файл

@ -57,6 +57,9 @@ Namespace Global.FaceDetection
' Reference: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868174.aspx
Private Shared ReadOnly RotationKey As Guid = New Guid("C380465D-2271-428C-9B83-ECEA3B4A85C1")
' Folder in which the captures will be stored (initialized in SetupUiAsync)
Private _captureFolder As StorageFolder = Nothing
' Prevent the screen from sleeping while the camera is running
Private ReadOnly _displayRequest As DisplayRequest = New DisplayRequest()
@ -161,11 +164,11 @@ Namespace Global.FaceDetection
Await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, Sub() UpdateButtonOrientation())
End Sub
Private Async Sub PhotoButton_Tapped(sender As Object, e As TappedRoutedEventArgs)
Private Async Sub PhotoButton_Click(sender As Object, e As RoutedEventArgs)
Await TakePhotoAsync()
End Sub
Private Async Sub VideoButton_Tapped(sender As Object, e As TappedRoutedEventArgs)
Private Async Sub VideoButton_Click(sender As Object, e As RoutedEventArgs)
If Not _isRecording Then
Await StartRecordingAsync()
Else
@ -175,7 +178,7 @@ Namespace Global.FaceDetection
UpdateCaptureControls()
End Sub
Private Async Sub FaceDetectionButton_Tapped(sender As Object, e As TappedRoutedEventArgs)
Private Async Sub FaceDetectionButton_Click(sender As Object, e As RoutedEventArgs)
If _faceDetectionEffect Is Nothing OrElse Not _faceDetectionEffect.Enabled Then
FacesCanvas.Children.Clear()
Await CreateFaceDetectionEffectAsync()
@ -331,14 +334,15 @@ Namespace Global.FaceDetection
VideoButton.IsEnabled = _mediaCapture.MediaCaptureSettings.ConcurrentRecordAndPhotoSupported
VideoButton.Opacity = If(VideoButton.IsEnabled, 1, 0)
Dim stream = New InMemoryRandomAccessStream()
Debug.WriteLine("Taking photo...")
Await _mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), stream)
Try
Debug.WriteLine("Taking photo...")
Await _mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), stream)
Debug.WriteLine("Photo taken!")
Dim file = Await _captureFolder.CreateFileAsync("SimplePhoto.jpg", CreationCollisionOption.GenerateUniqueName)
Debug.WriteLine("Photo taken! Saving to " & file.Path)
Dim photoOrientation = ConvertOrientationToPhotoOrientation(GetCameraOrientation())
Await ReencodeAndSavePhotoAsync(stream, photoOrientation)
Await ReencodeAndSavePhotoAsync(stream, file, photoOrientation)
Catch ex As Exception
Debug.WriteLine("Exception when taking a photo: {0}", ex.ToString())
Debug.WriteLine("Exception when taking a photo: " & ex.ToString())
End Try
VideoButton.IsEnabled = True
@ -352,17 +356,17 @@ Namespace Global.FaceDetection
Private Async Function StartRecordingAsync() As Task
Try
' Create storage file in Pictures Library
Dim videoFile = Await KnownFolders.PicturesLibrary.CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption.GenerateUniqueName)
Dim videoFile = Await _captureFolder.CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption.GenerateUniqueName)
Dim encodingProfile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto)
' Calculate rotation angle, taking mirroring into account if necessary
Dim rotationAngle = 360 - ConvertDeviceOrientationToDegrees(GetCameraOrientation())
encodingProfile.Video.Properties.Add(RotationKey, PropertyValue.CreateInt32(rotationAngle))
Debug.WriteLine("Starting recording...")
Debug.WriteLine("Starting recording to " & videoFile.Path)
Await _mediaCapture.StartRecordToStorageFileAsync(encodingProfile, videoFile)
_isRecording = True
Debug.WriteLine("Started recording!")
Catch ex As Exception
Debug.WriteLine("Exception when starting video recording: {0}", ex.ToString())
Debug.WriteLine("Exception when starting video recording: " & ex.ToString())
End Try
End Function
@ -427,6 +431,10 @@ Namespace Global.FaceDetection
End If
RegisterEventHandlers()
Dim picturesLibrary = Await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures)
' Fall back to the local app storage if the Pictures Library is not available
_captureFolder = If(picturesLibrary.SaveFolder, ApplicationData.Current.LocalFolder)
End Function
''' <summary>
@ -510,12 +518,12 @@ Namespace Global.FaceDetection
''' Applies the given orientation to a photo stream and saves it as a StorageFile
''' </summary>
''' <param name="stream">The photo stream</param>
''' <param name="file">The StorageFile in which the photo stream will be saved</param>
''' <param name="photoOrientation">The orientation metadata to apply to the photo</param>
''' <returns></returns>
Private Shared Async Function ReencodeAndSavePhotoAsync(stream As IRandomAccessStream, photoOrientation As PhotoOrientation) As Task
Private Shared Async Function ReencodeAndSavePhotoAsync(stream As IRandomAccessStream, file As StorageFile, photoOrientation As PhotoOrientation) As Task
Using inputStream = stream
Dim decoder = Await BitmapDecoder.CreateAsync(inputStream)
Dim file = Await KnownFolders.PicturesLibrary.CreateFileAsync("SimplePhoto.jpeg", CreationCollisionOption.GenerateUniqueName)
Using outputStream = Await file.OpenAsync(FileAccessMode.ReadWrite)
Dim encoder = Await BitmapEncoder.CreateForTranscodingAsync(outputStream, decoder)
Dim properties = New BitmapPropertySet From {{"System.Photo.Orientation", New BitmapTypedValue(photoOrientation, PropertyType.UInt16)}}

Просмотреть файл

@ -42,6 +42,7 @@ MainPage::MainPage()
, _displayOrientation(DisplayOrientations::Portrait)
, _displayRequest(ref new Windows::System::Display::DisplayRequest())
, RotationKey({ 0xC380465D, 0x2271, 0x428C,{ 0x9B, 0x83, 0xEC, 0xEA, 0x3B, 0x4A, 0x85, 0xC1 } })
, _captureFolder(nullptr)
{
InitializeComponent();
@ -127,6 +128,18 @@ task<void> MainPage::InitializeCameraAsync()
WriteLine("The app was denied access to the camera");
}
});
}).then([this]()
{
create_task(StorageLibrary::GetLibraryAsync(KnownLibraryId::Pictures))
.then([this](StorageLibrary^ picturesLibrary)
{
_captureFolder = picturesLibrary->SaveFolder;
if (_captureFolder == nullptr)
{
// In this case fall back to the local app storage since the Pictures Library is not available
_captureFolder = ApplicationData::Current->LocalFolder;
}
});
});
}
@ -352,7 +365,7 @@ task<void> MainPage::GetPreviewFrameAsD3DSurfaceAsync()
/// <returns></returns>
task<void> MainPage::SaveSoftwareBitmapAsync(SoftwareBitmap^ bitmap)
{
return create_task(KnownFolders::PicturesLibrary->CreateFileAsync("PreviewFrame.jpg", CreationCollisionOption::GenerateUniqueName))
return create_task(_captureFolder->CreateFileAsync("PreviewFrame.jpg", CreationCollisionOption::GenerateUniqueName))
.then([bitmap](StorageFile^ file)
{
return create_task(file->OpenAsync(FileAccessMode::ReadWrite));
@ -581,7 +594,7 @@ void MainPage::DisplayInformation_OrientationChanged(DisplayInformation^ sender,
}
}
void MainPage::GetPreviewFrameButton_Tapped(Object^, RoutedEventArgs^)
void MainPage::GetPreviewFrameButton_Click(Object^, RoutedEventArgs^)
{
// If preview is not running, no preview frames can be acquired
if (!_isPreviewing) return;

Просмотреть файл

@ -41,6 +41,9 @@ namespace CameraGetPreviewFrame
// Reference: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868174.aspx
const GUID RotationKey;
// Folder in which the captures will be stored (availability check performed in InitializeCameraAsync)
Windows::Storage::StorageFolder^ _captureFolder;
// Event tokens
Windows::Foundation::EventRegistrationToken _applicationSuspendingEventToken;
Windows::Foundation::EventRegistrationToken _applicationResumingEventToken;
@ -70,7 +73,7 @@ namespace CameraGetPreviewFrame
void Application_Resuming(Object^ sender, Object^ args);
void DisplayInformation_OrientationChanged(Windows::Graphics::Display::DisplayInformation^ sender, Object^ args);
void SystemMediaControls_PropertyChanged(Windows::Media::SystemMediaTransportControls^ sender, Windows::Media::SystemMediaTransportControlsPropertyChangedEventArgs^ args);
void GetPreviewFrameButton_Tapped(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void GetPreviewFrameButton_Click(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void MediaCapture_Failed(Windows::Media::Capture::MediaCapture ^currentCaptureObject, Windows::Media::Capture::MediaCaptureFailedEventArgs^ errorEventArgs);
protected:

Просмотреть файл

@ -50,6 +50,9 @@ namespace CameraGetPreviewFrame
// Reference: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868174.aspx
private static readonly Guid RotationKey = new Guid("C380465D-2271-428C-9B83-ECEA3B4A85C1");
// Folder in which the captures will be stored (initialized in InitializeCameraAsync)
private StorageFolder _captureFolder = null;
// Prevent the screen from sleeping while the camera is running
private readonly DisplayRequest _displayRequest = new DisplayRequest();
@ -173,7 +176,7 @@ namespace CameraGetPreviewFrame
}
}
private async void GetPreviewFrameButton_Tapped(object sender, TappedRoutedEventArgs e)
private async void GetPreviewFrameButton_Click(object sender, RoutedEventArgs e)
{
// If preview is not running, no preview frames can be acquired
if (!_isPreviewing) return;
@ -259,6 +262,10 @@ namespace CameraGetPreviewFrame
}
await StartPreviewAsync();
var picturesLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures);
// Fall back to the local app storage if the Pictures Library is not available
_captureFolder = picturesLibrary.SaveFolder ?? ApplicationData.Current.LocalFolder;
}
}
}
@ -381,7 +388,11 @@ namespace CameraGetPreviewFrame
// Save the frame (as is, no rotation is being applied)
if (SaveFrameCheckBox.IsChecked == true)
{
await SaveSoftwareBitmapAsync(previewFrame);
var file = await _captureFolder.CreateFileAsync("PreviewFrame.jpg", CreationCollisionOption.GenerateUniqueName);
Debug.WriteLine("Saving preview frame to " + file.Path);
await SaveSoftwareBitmapAsync(previewFrame, file);
}
}
}
@ -491,13 +502,12 @@ namespace CameraGetPreviewFrame
}
/// <summary>
/// Saves a SoftwareBitmap to the Pictures library with the specified name
/// Saves a SoftwareBitmap with the specified name
/// </summary>
/// <param name="bitmap"></param>
/// <returns></returns>
private static async Task SaveSoftwareBitmapAsync(SoftwareBitmap bitmap)
private static async Task SaveSoftwareBitmapAsync(SoftwareBitmap bitmap, StorageFile file)
{
var file = await KnownFolders.PicturesLibrary.CreateFileAsync("PreviewFrame.jpg", CreationCollisionOption.GenerateUniqueName);
using (var outputStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, outputStream);

Просмотреть файл

@ -13,7 +13,7 @@
<mp:PhoneIdentity PhoneProductId="dcdc78d0-a1e6-44b7-b9cb-aa569a827aa0" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>
<DisplayName>CameraGetPreviewFrame</DisplayName>
<DisplayName>CameraGetPreviewFrame JS Sample</DisplayName>
<PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
<Logo>images\storelogo-sdk.png</Logo>
</Properties>

Просмотреть файл

@ -18,10 +18,13 @@
var DisplayOrientations = Windows.Graphics.Display.DisplayOrientations;
var Imaging = Windows.Graphics.Imaging;
var Media = Windows.Media;
var StorageLibrary = Windows.Storage.StorageLibrary;
var KnownLibraryId = Windows.Storage.KnownLibraryId;
var ApplicationData = Windows.Storage.ApplicationData;
// Receive notifications about rotation of the device and UI and apply any necessary rotation to the preview stream and UI controls
var oDisplayInformation = Windows.Graphics.Display.DisplayInformation.getForCurrentView(),
oDisplayOrientation = DisplayOrientations.portrait;
oDisplayOrientation = DisplayOrientations.landscape;
// Prevent the screen from sleeping while the camera is running
var oDisplayRequest = new Windows.System.Display.DisplayRequest();
@ -42,6 +45,9 @@
// Reference: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868174.aspx
var RotationKey = "C380465D-2271-428C-9B83-ECEA3B4A85C1";
// Folder in which the captures will be stored (initialized in SetupUiAsync)
var oCaptureFolder;
// Initialization
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
@ -49,7 +55,7 @@
if (args.detail.kind === activation.ActivationKind.launch) {
if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
document.getElementById("getPreviewFrameButton").addEventListener("click", getPreviewFrameButton_tapped);
previewFrameImage.src = null;
previewFrameImage.src = "";
}
oDisplayInformation.addEventListener("orientationchanged", displayInformation_orientationChanged);
@ -122,6 +128,11 @@
}).then(function () {
isInitialized = true;
return startPreviewAsync();
}).then(function () {
return StorageLibrary.getLibraryAsync(KnownLibraryId.pictures)
}).then(function (picturesLibrary) {
// Fall back to the local app storage if the Pictures Library is not available
oCaptureFolder = picturesLibrary.saveFolder || ApplicationData.current.localFolder;
}).done();
}
@ -216,7 +227,7 @@
// Cleanup the UI
var previewVidTag = document.getElementById("cameraPreview");
previewVidTag.pause();
previewVidTag.src = null;
previewVidTag.src = "";
// Allow the device screen to sleep now that the preview is stopped
oDisplayRequest.requestRelease();
@ -248,7 +259,10 @@
// Save and show the frame (as is, no rotation is being applied)
if (saveShowFrameCheckBox.checked === true) {
return saveAndShowSoftwareBitmapAsync(frameBitmap);
return oCaptureFolder.createFileAsync("PreviewFrame.jpg", Windows.Storage.CreationCollisionOption.generateUniqueName)
.then(function (file) {
return saveAndShowSoftwareBitmapAsync(frameBitmap, file);
})
}
else {
return WinJS.Promise.as();
@ -284,7 +298,7 @@
}
// Clear the image
previewFrameImage.src = null;
previewFrameImage.src = "";
});
}
@ -293,23 +307,22 @@
/// </summary>
/// <param name="bitmap"></param>
/// <returns></returns>
function saveAndShowSoftwareBitmapAsync(bitmap) {
var oFile = null;
return Windows.Storage.ApplicationData.current.localFolder.createFileAsync("PreviewFrame.jpg", Windows.Storage.CreationCollisionOption.generateUniqueName)
.then(function (file) {
oFile = file;
return file.openAsync(Windows.Storage.FileAccessMode.readWrite);
}).then(function (outputStream) {
return Imaging.BitmapEncoder.createAsync(Imaging.BitmapEncoder.jpegEncoderId, outputStream);
function saveAndShowSoftwareBitmapAsync(bitmap, file) {
var imageStream = null;
return file.openAsync(Windows.Storage.FileAccessMode.readWrite)
.then(function (outputStream) {
imageStream = outputStream;
return Imaging.BitmapEncoder.createAsync(Imaging.BitmapEncoder.jpegEncoderId, imageStream);
}).then(function (encoder) {
// Grab the data from the SoftwareBitmap
encoder.setSoftwareBitmap(bitmap);
return encoder.flushAsync();
}).done(function () {
}).then(function () {
var imageBlob = window.MSApp.createBlobFromRandomAccessStream("image/jpg", imageStream);
// Finally display the image at the correct orientation
previewFrameImage.src = oFile.path;
previewFrameImage.src = URL.createObjectURL(imageBlob, { oneTimeOnly: true });
previewFrameImage.style.transform = "rotate(" + convertDisplayOrientationToDegrees(oDisplayOrientation) + "deg)";
});
})
}

Просмотреть файл

@ -36,13 +36,13 @@
<CaptureElement Name="PreviewControl" Stretch="Uniform" Grid.Column="0"/>
<!--Captured preview frame image-->
<Image Name="PreviewFrameImage" Grid.Column="1"/>
<Image Name="PreviewFrameImage" Grid.Column="1"/>
</Grid>
<!--User input-->
<StackPanel Grid.Row="1">
<StackPanel Orientation="Horizontal">
<Button Name="GetPreviewFrameButton" Content="GetPreviewFrameAsync" Tapped="GetPreviewFrameButton_Tapped" Margin="10" IsEnabled="False"/>
<Button Name="GetPreviewFrameButton" Content="GetPreviewFrameAsync" Click="GetPreviewFrameButton_Click" Margin="10" IsEnabled="False"/>
<TextBlock Name="FrameInfoTextBlock" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Orientation="Horizontal">

Просмотреть файл

@ -49,6 +49,7 @@ MainPage::MainPage()
, _displayOrientation(DisplayOrientations::Portrait)
, _displayRequest(ref new Windows::System::Display::DisplayRequest())
, RotationKey({ 0xC380465D, 0x2271, 0x428C,{ 0x9B, 0x83, 0xEC, 0xEA, 0x3B, 0x4A, 0x85, 0xC1 } })
, _captureFolder(nullptr)
{
this->InitializeComponent();
@ -410,13 +411,15 @@ task<void> MainPage::TakeNormalPhotoAsync()
return create_task(_mediaCapture->CapturePhotoToStreamAsync(Windows::Media::MediaProperties::ImageEncodingProperties::CreateJpeg(), inputStream))
.then([this, inputStream]()
{
WriteLine("Photo taken!");
// Create file based off the current time
auto fileName = L"SimplePhoto_" + GetTimeStr() + L".jpg";
return create_task(_captureFolder->CreateFileAsync(fileName, CreationCollisionOption::GenerateUniqueName));
}).then([this, inputStream](StorageFile^ file)
{
WriteLine("Photo taken! Saving to " + file->Path);
auto photoOrientation = ConvertOrientationToPhotoOrientation(GetCameraOrientation());
return ReencodeAndSavePhotoAsync(inputStream, fileName, photoOrientation);
return ReencodeAndSavePhotoAsync(inputStream, file, photoOrientation);
}).then([this](task<void> previousTask)
{
try
@ -450,8 +453,12 @@ task<void> MainPage::TakeHdrPhotoAsync()
return create_task(_advancedCapture->CaptureAsync(context))
.then([this, context](Capture::AdvancedCapturedPhoto^ photo)
{
WriteLine("HDR photo taken!");
return ReencodeAndSavePhotoAsync(photo->Frame, context->_captureFileName, context->_captureOrientation);
context->_photo = photo;
return create_task(_captureFolder->CreateFileAsync(context->_captureFileName, CreationCollisionOption::GenerateUniqueName));
}).then([this, context](StorageFile^ file)
{
WriteLine("HDR photo taken! Saving to " + file->Path);
return ReencodeAndSavePhotoAsync(context->_photo->Frame, file, context->_captureOrientation);
}).then([this](task<void> previousTask)
{
try
@ -505,20 +512,18 @@ task<DeviceInformation^> MainPage::FindCameraDeviceByPanelAsync(Windows::Devices
/// <param name="stream">The photo stream</param>
/// <param name="photoOrientation">The orientation metadata to apply to the photo</param>
/// <returns></returns>
task<void> MainPage::ReencodeAndSavePhotoAsync(Streams::IRandomAccessStream^ stream, String^ fileName, FileProperties::PhotoOrientation photoOrientation)
task<void> MainPage::ReencodeAndSavePhotoAsync(Streams::IRandomAccessStream^ stream, StorageFile^ file, FileProperties::PhotoOrientation photoOrientation)
{
// Using this state variable to pass multiple values through our task chain
ReencodeState^ state = ref new ReencodeState();
state->_file = file;
state->_orientation = photoOrientation;
return create_task(BitmapDecoder::CreateAsync(stream))
.then([state, fileName](BitmapDecoder^ decoder)
.then([state](BitmapDecoder^ decoder)
{
state->_decoder = decoder;
return create_task(KnownFolders::PicturesLibrary->CreateFileAsync(fileName, CreationCollisionOption::GenerateUniqueName));
}).then([](StorageFile^ file)
{
return create_task(file->OpenAsync(FileAccessMode::ReadWrite));
return create_task(state->_file->OpenAsync(FileAccessMode::ReadWrite));
}).then([state](Streams::IRandomAccessStream^ outputStream)
{
return create_task(BitmapEncoder::CreateForTranscodingAsync(outputStream, state->_decoder));
@ -569,6 +574,17 @@ task<void> MainPage::SetupUiAsync()
_deviceOrientation = _orientationSensor->GetCurrentOrientation();
}
create_task(StorageLibrary::GetLibraryAsync(KnownLibraryId::Pictures))
.then([this](StorageLibrary^ picturesLibrary)
{
_captureFolder = picturesLibrary->SaveFolder;
if (_captureFolder == nullptr)
{
// In this case fall back to the local app storage since the Pictures Library is not available
_captureFolder = ApplicationData::Current->LocalFolder;
}
});
// Hide the status bar
if (Windows::Foundation::Metadata::ApiInformation::IsTypePresent("Windows.UI.ViewManagement.StatusBar"))
{
@ -920,7 +936,7 @@ void MainPage::SceneAnalysisEffect_SceneAnalyzed(Core::SceneAnalysisEffect^ send
}));
}
void MainPage::PhotoButton_Tapped(Object^, Windows::UI::Xaml::RoutedEventArgs^)
void MainPage::PhotoButton_Click(Object^, Windows::UI::Xaml::RoutedEventArgs^)
{
TakePhotoInCurrentModeAsync();
}
@ -1004,15 +1020,18 @@ void MainPage::AdvancedCapture_OptionalReferencePhotoCaptured(Capture::AdvancedP
{
// Retrieve the context (i.e. what capture does this belong to?)
auto context = static_cast<AdvancedCaptureContext^>(args->Context);
WriteLine("AdvancedCapture_OptionalReferencePhotoCaptured for " + context->_captureFileName);
// Remove "_HDR" from the name of the capture to create the name of the reference
// Remove "_HDR" from the name of the capture to create the name of the reference photo (this is the non-HDR capture)
std::wstringstream fileName;
fileName << context->_captureFileName->Data();
StringReplace(fileName.str(), std::wstring(L"_HDR"), std::wstring(L""));
ReencodeAndSavePhotoAsync(args->Frame, ref new String(fileName.str().c_str()), context->_captureOrientation);
create_task(_captureFolder->CreateFileAsync(ref new String(fileName.str().c_str()), CreationCollisionOption::GenerateUniqueName))
.then([this, args, context](StorageFile^ file)
{
ReencodeAndSavePhotoAsync(args->Frame, file, context->_captureOrientation);
});
}
/// <summary>

Просмотреть файл

@ -20,6 +20,7 @@ namespace CameraHdr
internal:
Windows::Graphics::Imaging::BitmapDecoder^ _decoder;
Windows::Graphics::Imaging::BitmapEncoder^ _encoder;
Windows::Storage::StorageFile^ _file;
Windows::Storage::FileProperties::PhotoOrientation _orientation;
};
@ -31,6 +32,7 @@ namespace CameraHdr
internal:
Platform::String^ _captureFileName;
Windows::Storage::FileProperties::PhotoOrientation _captureOrientation;
Windows::Media::Capture::AdvancedCapturedPhoto^ _photo;
};
public ref class MainPage sealed
@ -46,6 +48,9 @@ namespace CameraHdr
// Reference: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868174.aspx
const GUID RotationKey;
// Folder in which the captures will be stored (availability check performed in SetupUiAsync)
Windows::Storage::StorageFolder^ _captureFolder;
// Prevent the screen from sleeping while the camera is running
Windows::System::Display::DisplayRequest^ _displayRequest;
@ -97,7 +102,7 @@ namespace CameraHdr
// Helpers
Concurrency::task<Windows::Devices::Enumeration::DeviceInformation^> FindCameraDeviceByPanelAsync(Windows::Devices::Enumeration::Panel panel);
Concurrency::task<void> ReencodeAndSavePhotoAsync(Windows::Storage::Streams::IRandomAccessStream^ stream, Platform::String^ fileName, Windows::Storage::FileProperties::PhotoOrientation photoOrientation);
Concurrency::task<void> ReencodeAndSavePhotoAsync(Windows::Storage::Streams::IRandomAccessStream^ stream, Windows::Storage::StorageFile^ file, Windows::Storage::FileProperties::PhotoOrientation photoOrientation);
void UpdateUi();
Concurrency::task<void> SetupUiAsync();
Concurrency::task<void> CleanupUiAsync();
@ -121,7 +126,7 @@ namespace CameraHdr
void Application_Resuming(Object^ sender, Object^ args);
void DisplayInformation_OrientationChanged(Windows::Graphics::Display::DisplayInformation^ sender, Object^ args);
void SceneAnalysisEffect_SceneAnalyzed(Windows::Media::Core::SceneAnalysisEffect^ sender, Windows::Media::Core::SceneAnalyzedEventArgs^ args);
void PhotoButton_Tapped(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void PhotoButton_Click(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void SystemMediaControls_PropertyChanged(Windows::Media::SystemMediaTransportControls^ sender, Windows::Media::SystemMediaTransportControlsPropertyChangedEventArgs^ args);
void HdrToggleButton_Checked(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void OrientationSensor_OrientationChanged(Windows::Devices::Sensors::SimpleOrientationSensor^, Windows::Devices::Sensors::SimpleOrientationSensorOrientationChangedEventArgs^);

Просмотреть файл

@ -52,6 +52,9 @@ namespace CameraHdr
// Reference: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868174.aspx
private static readonly Guid RotationKey = new Guid("C380465D-2271-428C-9B83-ECEA3B4A85C1");
// Folder in which the captures will be stored (initialized in SetupUiAsync)
private StorageFolder _captureFolder = null;
// Prevent the screen from sleeping while the camera is running
private readonly DisplayRequest _displayRequest = new DisplayRequest();
@ -256,14 +259,15 @@ namespace CameraHdr
// Retrieve the context (i.e. what capture does this belong to?)
var context = args.Context as AdvancedCaptureContext;
Debug.WriteLine("AdvancedCapture_OptionalReferencePhotoCaptured for {0}", context.CaptureFileName);
// Remove "_HDR" from the name of the capture to create the name of the reference
// Remove "_HDR" from the name of the capture to create the name of the reference photo (this is the non-HDR capture)
var referenceName = context.CaptureFileName.Replace("_HDR", "");
var file = await _captureFolder.CreateFileAsync(referenceName, CreationCollisionOption.GenerateUniqueName);
Debug.WriteLine("AdvancedCapture_OptionalReferencePhotoCaptured for " + context.CaptureFileName + ". Saving to " + file.Path);
using (var frame = args.Frame)
{
await ReencodeAndSavePhotoAsync(frame, referenceName, context.CaptureOrientation);
await ReencodeAndSavePhotoAsync(frame, file, context.CaptureOrientation);
}
}
@ -278,7 +282,7 @@ namespace CameraHdr
Debug.WriteLine("AdvancedCapture_AllPhotosCaptured");
}
private async void PhotoButton_Tapped(object sender, TappedRoutedEventArgs e)
private async void PhotoButton_Click(object sender, RoutedEventArgs e)
{
await TakePhotoInCurrentModeAsync();
}
@ -555,21 +559,21 @@ namespace CameraHdr
{
Debug.WriteLine("Taking photo...");
// Generate a filename based on the current time
// Read the current orientation of the camera and the capture time
var photoOrientation = ConvertOrientationToPhotoOrientation(GetCameraOrientation());
var fileName = String.Format("SimplePhoto_{0}.jpg", DateTime.Now.ToString("HHmmss"));
// Get the orientation of the camera at the time of capture
var photoOrientation = ConvertOrientationToPhotoOrientation(GetCameraOrientation());
await _mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), stream);
Debug.WriteLine("Photo taken!");
await ReencodeAndSavePhotoAsync(stream, fileName, photoOrientation);
var file = await _captureFolder.CreateFileAsync(fileName, CreationCollisionOption.GenerateUniqueName);
Debug.WriteLine("Photo taken! Saving to " + file.Path);
await ReencodeAndSavePhotoAsync(stream, file, photoOrientation);
}
catch (Exception ex)
{
// File I/O errors are reported as exceptions
Debug.WriteLine("Exception when taking a photo: {0}", ex.ToString());
Debug.WriteLine("Exception when taking a photo: " + ex.ToString());
}
}
@ -591,17 +595,19 @@ namespace CameraHdr
// Start capture, and pass the context object
var capture = await _advancedCapture.CaptureAsync(context);
Debug.WriteLine("HDR photo taken! {0}", fileName);
using (var frame = capture.Frame)
{
await ReencodeAndSavePhotoAsync(frame, fileName, photoOrientation);
var file = await _captureFolder.CreateFileAsync(fileName, CreationCollisionOption.GenerateUniqueName);
Debug.WriteLine("HDR photo taken! Saving to " + file.Path);
await ReencodeAndSavePhotoAsync(frame, file, photoOrientation);
}
}
catch (Exception ex)
{
// File I/O errors are reported as exceptions
Debug.WriteLine("Exception when taking an HDR photo: {0}", ex.ToString());
Debug.WriteLine("Exception when taking an HDR photo: " + ex.ToString());
}
}
@ -672,6 +678,10 @@ namespace CameraHdr
}
RegisterEventHandlers();
var picturesLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures);
// Fall back to the local app storage if the Pictures Library is not available
_captureFolder = picturesLibrary.SaveFolder ?? ApplicationData.Current.LocalFolder;
}
/// <summary>
@ -771,24 +781,22 @@ namespace CameraHdr
/// Applies the given orientation to a photo stream and saves it as a StorageFile
/// </summary>
/// <param name="stream">The photo stream</param>
/// <param name="file">The StorageFile in which the photo stream will be saved</param>
/// <param name="photoOrientation">The orientation metadata to apply to the photo</param>
/// <returns></returns>
private static async Task ReencodeAndSavePhotoAsync(IRandomAccessStream stream, string fileName, PhotoOrientation photoOrientation = PhotoOrientation.Normal)
private static async Task ReencodeAndSavePhotoAsync(IRandomAccessStream stream, StorageFile file, PhotoOrientation photoOrientation)
{
using (var inputStream = stream)
{
var decoder = await BitmapDecoder.CreateAsync(inputStream);
var file = await KnownFolders.PicturesLibrary.CreateFileAsync(fileName, CreationCollisionOption.GenerateUniqueName);
using (var outputStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateForTranscodingAsync(outputStream, decoder);
// Set the orientation of the capture
var properties = new BitmapPropertySet { { "System.Photo.Orientation", new BitmapTypedValue(photoOrientation, PropertyType.UInt16) } };
await encoder.BitmapProperties.SetPropertiesAsync(properties);
var properties = new BitmapPropertySet { { "System.Photo.Orientation", new BitmapTypedValue(photoOrientation, PropertyType.UInt16) } };
await encoder.BitmapProperties.SetPropertiesAsync(properties);
await encoder.FlushAsync();
}
}

Просмотреть файл

@ -20,6 +20,9 @@
var Media = Windows.Media;
var SimpleOrientation = Windows.Devices.Sensors.SimpleOrientation;
var SimpleOrientationSensor = Windows.Devices.Sensors.SimpleOrientationSensor;
var StorageLibrary = Windows.Storage.StorageLibrary;
var KnownLibraryId = Windows.Storage.KnownLibraryId;
var ApplicationData = Windows.Storage.ApplicationData;
// Receive notifications about rotation of the device and UI and apply any necessary rotation to the preview stream and UI controls
var oOrientationSensor = SimpleOrientationSensor.getDefault(),
@ -57,6 +60,9 @@
// Reference: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868174.aspx
var RotationKey = "C380465D-2271-428C-9B83-ECEA3B4A85C1";
// Folder in which the captures will be stored (initialized in SetupUiAsync)
var oCaptureFolder;
// Initialization
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
@ -391,16 +397,18 @@
console.log("Taking photo...");
return oMediaCapture.capturePhotoToStreamAsync(Windows.Media.MediaProperties.ImageEncodingProperties.createJpeg(), inputStream)
.then(function() {
console.log("Photo taken!");
.then(function () {
var fileName = "SimplePhoto_" + getTimeStr() + ".jpg";
return oCaptureFolder.createFileAsync(fileName, Windows.Storage.CreationCollisionOption.GenerateUniqueName)
}).then(function(file){
console.log("Photo taken! Saving to " + file.path);
var photoOrientation = convertOrientationToPhotoOrientation(getCameraOrientation());
return reencodeAndSavePhotoAsync(inputStream, fileName, photoOrientation);
return reencodeAndSavePhotoAsync(inputStream, file, photoOrientation);
});
}
function takeHdrPhotoAsync() {
var captureFile = null;
// Take the picture
console.log("Taking photo...");
@ -409,10 +417,14 @@
context.insert("fileName", "SimplePhoto_" + getTimeStr() + "_HDR.jpg");
context.insert("orientation", convertOrientationToPhotoOrientation(getCameraOrientation()));
return oAdvancedCapture.captureAsync(context)
return oCaptureFolder.createFileAsync(fileName, Windows.Storage.CreationCollisionOption.GenerateUniqueName)
.then(function (file) {
captureFile = file;
return oAdvancedCapture.captureAsync(context)
})
.then(function(advancedCapturedPhoto) {
console.log("HDR photo taken!");
return reencodeAndSavePhotoAsync(advancedCapturedPhoto.frame, context.fileName, context.orientation);
console.log("HDR photo taken! Saving to " + captureFile.path);
return reencodeAndSavePhotoAsync(advancedCapturedPhoto.frame, captureFile, context.orientation);
});
}
@ -448,7 +460,7 @@
/// <param name="stream">The photo stream</param>
/// <param name="photoOrientation">The orientation metadata to apply to the photo</param>
/// <returns></returns>
function reencodeAndSavePhotoAsync(inputStream, fileName, orientation) {
function reencodeAndSavePhotoAsync(inputStream, file, orientation) {
var Imaging = Windows.Graphics.Imaging;
var bitmapDecoder = null,
bitmapEncoder = null,
@ -457,8 +469,6 @@
return Imaging.BitmapDecoder.createAsync(inputStream)
.then(function (decoder) {
bitmapDecoder = decoder;
return Windows.Storage.KnownFolders.picturesLibrary.createFileAsync(fileName, Windows.Storage.CreationCollisionOption.generateUniqueName);
}).then(function (file) {
return file.openAsync(Windows.Storage.FileAccessMode.readWrite);
}).then(function (outStream) {
outputStream = outStream;
@ -508,14 +518,19 @@
if (oOrientationSensor != null) {
oDeviceOrientation = oOrientationSensor.getCurrentOrientation();
}
return StorageLibrary.getLibraryAsync(KnownLibraryId.pictures)
.then(function (picturesLibrary) {
// Fall back to the local app storage if the Pictures Library is not available
oCaptureFolder = picturesLibrary.saveFolder || ApplicationData.current.localFolder;
// Hide the status bar
if (Windows.Foundation.Metadata.ApiInformation.isTypePresent("Windows.UI.ViewManagement.StatusBar")) {
return Windows.UI.ViewManagement.StatusBar.getForCurrentView().hideAsync();
}
else {
return WinJS.Promise.as();
}
// Hide the status bar
if (Windows.Foundation.Metadata.ApiInformation.isTypePresent("Windows.UI.ViewManagement.StatusBar")) {
return Windows.UI.ViewManagement.StatusBar.getForCurrentView().hideAsync();
}
else {
return WinJS.Promise.as();
}
})
}
/// <summary>
@ -755,12 +770,14 @@
// Retrieve the context (i.e. what capture does this belong to?)
var context = args.context;
console.log("AdvancedCapture_OptionalReferencePhotoCaptured for " + context.fileName);
// Remove "_HDR" from the name of the capture to create the name of the reference (this is the non-HDR capture)
var fileName = context.fileName.replace("_HDR", "");
// Remove "_HDR" from the name of the capture to create the name of the reference
context.fileName = context.fileName.replace("_HDR", "");
reencodeAndSavePhotoAsync(args.frame, context.fileName, context.orientation);
return oCaptureFolder.createFileAsync(fileName, Windows.Storage.CreationCollisionOption.GenerateUniqueName)
.then(function (file) {
console.log("AdvancedCapture_OptionalReferencePhotoCaptured for " + context.fileName + ". Saving to " + file.path);
return reencodeAndSavePhotoAsync(args.frame, file, context.orientation);
})
}
/// <summary>

Просмотреть файл

@ -13,7 +13,7 @@
<mp:PhoneIdentity PhoneProductId="dede2df4-b097-4464-bb96-66a644f32d55" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>
<DisplayName>CameraHDR</DisplayName>
<DisplayName>CameraHDR JS Sample</DisplayName>
<PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
<Logo>images\storelogo-sdk.png</Logo>
</Properties>

Просмотреть файл

@ -66,7 +66,7 @@
</Viewbox>
</ToggleButton>
<Button Name="PhotoButton" Tapped="PhotoButton_Tapped" IsEnabled="False">
<Button Name="PhotoButton" Click="PhotoButton_Click" IsEnabled="False">
<Viewbox MaxWidth="40" MaxHeight="40">
<SymbolIcon Symbol="Camera"/>
</Viewbox>

Просмотреть файл

@ -54,6 +54,9 @@ Namespace Global.CameraHdr
' Reference: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868174.aspx
Private Shared ReadOnly RotationKey As Guid = New Guid("C380465D-2271-428C-9B83-ECEA3B4A85C1")
' Folder in which the captures will be stored (initialized in SetupUiAsync)
Private _captureFolder As StorageFolder = Nothing
' Prevent the screen from sleeping while the camera is running
Private ReadOnly _displayRequest As DisplayRequest = New DisplayRequest()
@ -208,11 +211,12 @@ Namespace Global.CameraHdr
Private Async Sub AdvancedCapture_OptionalReferencePhotoCaptured(sender As AdvancedPhotoCapture, args As OptionalReferencePhotoCapturedEventArgs)
' Retrieve the context (i.e. what capture does this belong to?)
Dim context = TryCast(args.Context, AdvancedCaptureContext)
Debug.WriteLine("AdvancedCapture_OptionalReferencePhotoCaptured for {0}", context.CaptureFileName)
' Remove "_HDR" from the name of the capture to create the name of the reference
Dim referenceName = context.CaptureFileName.Replace("_HDR", "")
Dim file = Await _captureFolder.CreateFileAsync(referenceName, CreationCollisionOption.GenerateUniqueName)
Debug.WriteLine("AdvancedCapture_OptionalReferencePhotoCaptured for " & context.CaptureFileName & ". Saving to " & file.Path)
Using frame = args.Frame
Await ReencodeAndSavePhotoAsync(frame, referenceName, context.CaptureOrientation)
Await ReencodeAndSavePhotoAsync(frame, file, context.CaptureOrientation)
End Using
End Sub
@ -226,7 +230,7 @@ Namespace Global.CameraHdr
Debug.WriteLine("AdvancedCapture_AllPhotosCaptured")
End Sub
Private Async Sub PhotoButton_Tapped(sender As Object, e As TappedRoutedEventArgs)
Private Async Sub PhotoButton_Click(sender As Object, e As RoutedEventArgs)
Await TakePhotoInCurrentModeAsync()
End Sub
@ -416,15 +420,15 @@ Namespace Global.CameraHdr
Dim stream = New InMemoryRandomAccessStream()
Try
Debug.WriteLine("Taking photo...")
' Generate a filename based on the current time
Dim fileName = String.Format("SimplePhoto_{0}.jpg", DateTime.Now.ToString("HHmmss"))
' Get the orientation of the camera at the time of capture
' Read the current orientation of the camera and the capture time
Dim photoOrientation = ConvertOrientationToPhotoOrientation(GetCameraOrientation())
Dim fileName = String.Format("SimplePhoto_{0}_HDR.jpg", DateTime.Now.ToString("HHmmss"))
Await _mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), stream)
Debug.WriteLine("Photo taken!")
Await ReencodeAndSavePhotoAsync(stream, fileName, photoOrientation)
Dim file = Await _captureFolder.CreateFileAsync(fileName, CreationCollisionOption.GenerateUniqueName)
Debug.WriteLine("Photo taken! Saving to " & file.Path)
Await ReencodeAndSavePhotoAsync(stream, file, photoOrientation)
Catch ex As Exception
Debug.WriteLine("Exception when taking a photo: {0}", ex.ToString())
Debug.WriteLine("Exception when taking a photo: " & ex.ToString())
End Try
End Function
@ -442,12 +446,13 @@ Namespace Global.CameraHdr
Dim context = New AdvancedCaptureContext() With {.CaptureFileName = fileName, .CaptureOrientation = photoOrientation}
' Start capture, and pass the context object
Dim capture = Await _advancedCapture.CaptureAsync(context)
Debug.WriteLine("HDR photo taken! {0}", fileName)
Using frame = capture.Frame
Await ReencodeAndSavePhotoAsync(frame, fileName, photoOrientation)
Dim file = Await _captureFolder.CreateFileAsync(fileName, CreationCollisionOption.GenerateUniqueName)
Debug.WriteLine("HDR photo taken! Saving to " & file.Path)
Await ReencodeAndSavePhotoAsync(frame, file, photoOrientation)
End Using
Catch ex As Exception
Debug.WriteLine("Exception when taking an HDR photo: {0}", ex.ToString())
Debug.WriteLine("Exception when taking an HDR photo: " & ex.ToString())
End Try
End Function
@ -500,6 +505,10 @@ Namespace Global.CameraHdr
End If
RegisterEventHandlers()
Dim picturesLibrary = Await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures)
' Fall back to the local app storage if the Pictures Library is not available
_captureFolder = If(picturesLibrary.SaveFolder, ApplicationData.Current.LocalFolder)
End Function
''' <summary>
@ -575,15 +584,14 @@ Namespace Global.CameraHdr
''' Applies the given orientation to a photo stream and saves it as a StorageFile
''' </summary>
''' <param name="stream">The photo stream</param>
''' <param name="file">The StorageFile in which the photo stream will be saved</param>
''' <param name="photoOrientation">The orientation metadata to apply to the photo</param>
''' <returns></returns>
Private Shared Async Function ReencodeAndSavePhotoAsync(stream As IRandomAccessStream, fileName As String, Optional photoOrientation As PhotoOrientation = PhotoOrientation.Normal) As Task
Private Shared Async Function ReencodeAndSavePhotoAsync(stream As IRandomAccessStream, file As StorageFile, photoOrientation As PhotoOrientation) As Task
Using inputStream = stream
Dim decoder = Await BitmapDecoder.CreateAsync(inputStream)
Dim file = Await KnownFolders.PicturesLibrary.CreateFileAsync(fileName, CreationCollisionOption.GenerateUniqueName)
Using outputStream = Await file.OpenAsync(FileAccessMode.ReadWrite)
Dim encoder = Await BitmapEncoder.CreateForTranscodingAsync(outputStream, decoder)
' Set the orientation of the capture
Dim properties = New BitmapPropertySet From {{"System.Photo.Orientation", New BitmapTypedValue(photoOrientation, PropertyType.UInt16)}}
Await encoder.BitmapProperties.SetPropertiesAsync(properties)
Await encoder.FlushAsync()

Просмотреть файл

@ -67,13 +67,13 @@
</Style>
</StackPanel.Resources>
<Button Name="PhotoButton" Tapped="PhotoButton_Tapped" IsEnabled="False">
<Button Name="PhotoButton" Click="PhotoButton_Click" IsEnabled="False">
<Viewbox MaxHeight="40" MaxWidth="40">
<SymbolIcon Symbol="Camera"/>
</Viewbox>
</Button>
<Button Name="VideoButton" Tapped="VideoButton_Tapped" IsEnabled="False">
<Button Name="VideoButton" Click="VideoButton_Click" IsEnabled="False">
<Grid>
<Ellipse x:Name="StartRecordingIcon" Fill="Red" Width="20" Height="20"/>
<Rectangle x:Name="StopRecordingIcon" Fill="White" Width="20" Height="20" Visibility="Collapsed"/>
@ -102,13 +102,13 @@
</TransitionCollection>
</StackPanel.ChildrenTransitions>
<Button Name="FlashButton" Content="Flash" Tapped="ManualControlButton_Tapped"/>
<Button Name="ZoomButton" Content="Zoom" Tapped="ManualControlButton_Tapped"/>
<Button Name="FocusButton" Content="Focus" Tapped="ManualControlButton_Tapped"/>
<Button Name="WbButton" Content="WB" Tapped="ManualControlButton_Tapped"/>
<Button Name="IsoButton" Content="ISO" Tapped="ManualControlButton_Tapped"/>
<Button Name="ShutterButton" Content="Shutter" Tapped="ManualControlButton_Tapped"/>
<Button Name="EvButton" Content="EV" Tapped="ManualControlButton_Tapped"/>
<Button Name="FlashButton" Content="Flash" Click="ManualControlButton_Click"/>
<Button Name="ZoomButton" Content="Zoom" Click="ManualControlButton_Click"/>
<Button Name="FocusButton" Content="Focus" Click="ManualControlButton_Click"/>
<Button Name="WbButton" Content="WB" Click="ManualControlButton_Click"/>
<Button Name="IsoButton" Content="ISO" Click="ManualControlButton_Click"/>
<Button Name="ShutterButton" Content="Shutter" Click="ManualControlButton_Click"/>
<Button Name="EvButton" Content="EV" Click="ManualControlButton_Click"/>
</StackPanel>
<!--Grid that hosts all of the manual controls for the selected camera control-->

Просмотреть файл

@ -54,6 +54,9 @@ namespace CameraManualControls
// Reference: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868174.aspx
private static readonly Guid RotationKey = new Guid("C380465D-2271-428C-9B83-ECEA3B4A85C1");
// Folder in which the captures will be stored (initialized in SetupUiAsync)
private StorageFolder _captureFolder = null;
// Prevent the screen from sleeping while the camera is running
private readonly DisplayRequest _displayRequest = new DisplayRequest();
@ -205,12 +208,12 @@ namespace CameraManualControls
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => UpdateButtonOrientation());
}
private async void PhotoButton_Tapped(object sender, TappedRoutedEventArgs e)
private async void PhotoButton_Click(object sender, RoutedEventArgs e)
{
await TakePhotoAsync();
}
private async void VideoButton_Tapped(object sender, TappedRoutedEventArgs e)
private async void VideoButton_Click(object sender, RoutedEventArgs e)
{
if (!_isRecording)
{
@ -433,20 +436,25 @@ namespace CameraManualControls
var stream = new InMemoryRandomAccessStream();
Debug.WriteLine("Taking photo...");
await _mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), stream);
try
{
Debug.WriteLine("Taking photo...");
await _mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), stream);
Debug.WriteLine("Photo taken!");
var file = await _captureFolder.CreateFileAsync("SimplePhoto.jpg", CreationCollisionOption.GenerateUniqueName);
Debug.WriteLine("Photo taken! Saving to " + file.Path);
var photoOrientation = ConvertOrientationToPhotoOrientation(GetCameraOrientation());
await ReencodeAndSavePhotoAsync(stream, photoOrientation);
await ReencodeAndSavePhotoAsync(stream, file, photoOrientation);
Debug.WriteLine("Photo saved!");
}
catch (Exception ex)
{
// File I/O errors are reported as exceptions
Debug.WriteLine("Exception when taking a photo: {0}", ex.ToString());
Debug.WriteLine("Exception when taking a photo: " + ex.ToString());
}
// Done taking a photo, so re-enable the button
@ -463,7 +471,7 @@ namespace CameraManualControls
try
{
// Create storage file in Pictures Library
var videoFile = await KnownFolders.PicturesLibrary.CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption.GenerateUniqueName);
var videoFile = await _captureFolder.CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption.GenerateUniqueName);
var encodingProfile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto);
@ -471,7 +479,7 @@ namespace CameraManualControls
var rotationAngle = 360 - ConvertDeviceOrientationToDegrees(GetCameraOrientation());
encodingProfile.Video.Properties.Add(RotationKey, PropertyValue.CreateInt32(rotationAngle));
Debug.WriteLine("Starting recording...");
Debug.WriteLine("Starting recording to " + videoFile.Path);
await _mediaCapture.StartRecordToStorageFileAsync(encodingProfile, videoFile);
_isRecording = true;
@ -481,7 +489,7 @@ namespace CameraManualControls
catch (Exception ex)
{
// File I/O errors are reported as exceptions
Debug.WriteLine("Exception when starting video recording: {0}", ex.ToString());
Debug.WriteLine("Exception when starting video recording: " + ex.ToString());
}
}
@ -560,6 +568,10 @@ namespace CameraManualControls
}
RegisterEventHandlers();
var picturesLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures);
// Fall back to the local app storage if the Pictures Library is not available
_captureFolder = picturesLibrary.SaveFolder ?? ApplicationData.Current.LocalFolder;
}
/// <summary>
@ -680,16 +692,15 @@ namespace CameraManualControls
/// Applies the given orientation to a photo stream and saves it as a StorageFile
/// </summary>
/// <param name="stream">The photo stream</param>
/// <param name="file">The StorageFile in which the photo stream will be saved</param>
/// <param name="photoOrientation">The orientation metadata to apply to the photo</param>
/// <returns></returns>
private static async Task ReencodeAndSavePhotoAsync(IRandomAccessStream stream, PhotoOrientation photoOrientation)
private static async Task ReencodeAndSavePhotoAsync(IRandomAccessStream stream, StorageFile file, PhotoOrientation photoOrientation)
{
using (var inputStream = stream)
{
var decoder = await BitmapDecoder.CreateAsync(inputStream);
var file = await KnownFolders.PicturesLibrary.CreateFileAsync("SimplePhoto.jpeg", CreationCollisionOption.GenerateUniqueName);
using (var outputStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateForTranscodingAsync(outputStream, decoder);
@ -928,7 +939,7 @@ namespace CameraManualControls
}
private void ManualControlButton_Tapped(object sender, TappedRoutedEventArgs e)
private void ManualControlButton_Click(object sender, RoutedEventArgs e)
{
// Toggle single control mode
SetSingleControl(_singleControlMode ? null : sender);

Просмотреть файл

@ -13,7 +13,7 @@
<mp:PhoneIdentity PhoneProductId="2a15042f-e258-4b7e-9260-62ceea6b5305" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>
<DisplayName>CameraProfile</DisplayName>
<DisplayName>CameraProfile JS Sample</DisplayName>
<PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
<Logo>images\storelogo-sdk.png</Logo>
</Properties>

Просмотреть файл

@ -114,7 +114,7 @@ task<void> Scenario1_PreviewSettings::CleanupCameraAsync()
/// Initializes the camera and populates the UI
/// </summary>
/// <param name="sender"></param>
void Scenario1_PreviewSettings::InitializeCameraButton_Tapped(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^)
void Scenario1_PreviewSettings::InitializeCameraButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^)
{
Button^ button = static_cast<Button^>(sender);
button->IsEnabled = false;

Просмотреть файл

@ -36,7 +36,7 @@ namespace SDKTemplate
Concurrency::task<void> InitializeCameraAsync();
Concurrency::task<void> CleanupCameraAsync();
void InitializeCameraButton_Tapped(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void InitializeCameraButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void ComboBoxSettings_Changed(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void PopulateSettingsComboBox();

Просмотреть файл

@ -40,6 +40,7 @@ Scenario2_PhotoSettings::Scenario2_PhotoSettings()
: _rootPage(MainPage::Current)
, _mediaCapture(nullptr)
, _isPreviewing(false)
, _captureFolder(nullptr)
{
InitializeComponent();
}
@ -68,6 +69,17 @@ task<void> Scenario2_PhotoSettings::InitializeCameraAsync()
{
PreviewControl->Source = _mediaCapture.Get();
return create_task(_mediaCapture->StartPreviewAsync());
}).then([this]()
{
return create_task(StorageLibrary::GetLibraryAsync(KnownLibraryId::Pictures));
}).then([this](StorageLibrary^ picturesLibrary)
{
_captureFolder = picturesLibrary->SaveFolder;
if (_captureFolder == nullptr)
{
// In this case fall back to the local app storage since the Pictures Library is not available
_captureFolder = ApplicationData::Current->LocalFolder;
}
}).then([this](task<void> previousTask)
{
try
@ -114,7 +126,7 @@ task<void> Scenario2_PhotoSettings::CleanupCameraAsync()
/// Initializes the camera and populates the UI
/// </summary>
/// <param name="sender"></param>
void Scenario2_PhotoSettings::InitializeCameraButton_Tapped(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^)
void Scenario2_PhotoSettings::InitializeCameraButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^)
{
Button^ button = static_cast<Button^>(sender);
button->IsEnabled = false;
@ -137,14 +149,14 @@ void Scenario2_PhotoSettings::InitializeCameraButton_Tapped(Platform::Object^ se
/// <summary>
/// Takes a photo to and saves to a StorageFile
/// </summary>
void Scenario2_PhotoSettings::PhotoButton_Tapped(Platform::Object^, Windows::UI::Xaml::RoutedEventArgs^)
void Scenario2_PhotoSettings::PhotoButton_Click(Platform::Object^, Windows::UI::Xaml::RoutedEventArgs^)
{
if (_isPreviewing)
{
// Disable the photo button while taking a photo
PhotoButton->IsEnabled = false;
create_task(KnownFolders::PicturesLibrary->CreateFileAsync("SimplePhoto.jpg", CreationCollisionOption::GenerateUniqueName))
create_task(_captureFolder->CreateFileAsync("SimplePhoto.jpg", CreationCollisionOption::GenerateUniqueName))
.then([this](StorageFile^ file)
{
return create_task(_mediaCapture->CapturePhotoToStorageFileAsync(ImageEncodingProperties::CreateJpeg(), file))

Просмотреть файл

@ -33,11 +33,14 @@ namespace SDKTemplate
bool _isPreviewing;
// Folder in which the captures will be stored
Windows::Storage::StorageFolder^ _captureFolder;
Concurrency::task<void> InitializeCameraAsync();
Concurrency::task<void> CleanupCameraAsync();
void InitializeCameraButton_Tapped(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void PhotoButton_Tapped(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void InitializeCameraButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void PhotoButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void PreviewSettings_Changed(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void PhotoSettings_Changed(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);

Просмотреть файл

@ -42,6 +42,7 @@ Scenario3_AspectRatio::Scenario3_AspectRatio()
, _mediaCapture(nullptr)
, _isPreviewing(false)
, _isRecording(false)
, _captureFolder(nullptr)
{
InitializeComponent();
}
@ -70,6 +71,17 @@ task<void> Scenario3_AspectRatio::InitializeCameraAsync()
{
PreviewControl->Source = _mediaCapture.Get();
return create_task(_mediaCapture->StartPreviewAsync());
}).then([this]()
{
return create_task(StorageLibrary::GetLibraryAsync(KnownLibraryId::Pictures));
}).then([this](StorageLibrary^ picturesLibrary)
{
_captureFolder = picturesLibrary->SaveFolder;
if (_captureFolder == nullptr)
{
// In this case fall back to the local app storage since the Pictures Library is not available
_captureFolder = ApplicationData::Current->LocalFolder;
}
}).then([this](task<void> previousTask)
{
try
@ -119,7 +131,7 @@ task<void> Scenario3_AspectRatio::CleanupCameraAsync()
/// Initializes the camera and populates the UI
/// </summary>
/// <param name="sender"></param>
void Scenario3_AspectRatio::InitializeCameraButton_Tapped(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^)
void Scenario3_AspectRatio::InitializeCameraButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^)
{
Button^ button = static_cast<Button^>(sender);
button->IsEnabled = false;
@ -141,14 +153,14 @@ void Scenario3_AspectRatio::InitializeCameraButton_Tapped(Platform::Object^ send
/// <summary>
/// Records an MP4 video to a StorageFile
/// </summary>
void Scenario3_AspectRatio::VideoButton_Tapped(Platform::Object^, Windows::UI::Xaml::RoutedEventArgs^)
void Scenario3_AspectRatio::VideoButton_Click(Platform::Object^, Windows::UI::Xaml::RoutedEventArgs^)
{
if (_isPreviewing)
{
if (!_isRecording)
{
// Create a storage file and begin recording
create_task(KnownFolders::VideosLibrary->CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption::GenerateUniqueName))
create_task(_captureFolder->CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption::GenerateUniqueName))
.then([this](StorageFile^ file)
{
return create_task(_mediaCapture->StartRecordToStorageFileAsync(MediaEncodingProfile::CreateMp4(VideoEncodingQuality::Auto), file))

Просмотреть файл

@ -34,11 +34,14 @@ namespace SDKTemplate
bool _isPreviewing;
bool _isRecording;
// Folder in which the captures will be stored
Windows::Storage::StorageFolder^ _captureFolder;
Concurrency::task<void> InitializeCameraAsync();
Concurrency::task<void> CleanupCameraAsync();
void InitializeCameraButton_Tapped(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void VideoButton_Tapped(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void InitializeCameraButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void VideoButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void PreviewSettings_Changed(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void VideoSettings_Changed(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);

Просмотреть файл

@ -49,7 +49,7 @@ namespace SDKTemplate
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void InitializeCameraButton_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
private async void InitializeCameraButton_Click(object sender, RoutedEventArgs e)
{
var button = sender as Button;

Просмотреть файл

@ -35,6 +35,9 @@ namespace SDKTemplate
// Object to manage access to camera devices
private MediaCapturePreviewer _previewer = null;
// Folder in which the captures will be stored (initialized in InitializeCameraButton_Click)
private StorageFolder _captureFolder = null;
/// <summary>
/// Initializes a new instance of the <see cref="Scenario2_PhotoSettings"/> class.
/// </summary>
@ -67,7 +70,7 @@ namespace SDKTemplate
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void InitializeCameraButton_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
private async void InitializeCameraButton_Click(object sender, RoutedEventArgs e)
{
var button = sender as Button;
@ -87,6 +90,10 @@ namespace SDKTemplate
PopulateComboBox(MediaStreamType.Photo, PhotoSettings, false);
PhotoButton.IsEnabled = true;
}
var picturesLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures);
// Fall back to the local app storage if the Pictures Library is not available
_captureFolder = picturesLibrary.SaveFolder ?? ApplicationData.Current.LocalFolder;
}
/// <summary>
@ -124,7 +131,7 @@ namespace SDKTemplate
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void PhotoButton_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
private async void PhotoButton_Click(object sender, RoutedEventArgs e)
{
if (_previewer.IsPreviewing)
{
@ -136,7 +143,7 @@ namespace SDKTemplate
try
{
// Take and save the photo
var file = await KnownFolders.PicturesLibrary.CreateFileAsync("SimplePhoto.jpeg", CreationCollisionOption.GenerateUniqueName);
var file = await _captureFolder.CreateFileAsync("SimplePhoto.jpg", CreationCollisionOption.GenerateUniqueName);
await _previewer.MediaCapture.CapturePhotoToStorageFileAsync(ImageEncodingProperties.CreateJpeg(), file);
rootPage.NotifyUser("Photo taken, saved to: " + file.Path, NotifyType.StatusMessage);
}

Просмотреть файл

@ -33,6 +33,9 @@ namespace SDKTemplate
// Object to manage access to camera devices
private MediaCapturePreviewer _previewer = null;
// Folder in which the captures will be stored (initialized in InitializeCameraButton_Click)
private StorageFolder _captureFolder = null;
/// <summary>
/// Initializes a new instance of the <see cref="Scenario1_PreviewSettings"/> class.
/// </summary>
@ -65,7 +68,7 @@ namespace SDKTemplate
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void InitializeCameraButton_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
private async void InitializeCameraButton_Click(object sender, RoutedEventArgs e)
{
var button = sender as Button;
@ -91,6 +94,10 @@ namespace SDKTemplate
VideoButton.IsEnabled = true;
}
}
var picturesLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures);
// Fall back to the local app storage if the Pictures Library is not available
_captureFolder = picturesLibrary.SaveFolder ?? ApplicationData.Current.LocalFolder;
}
/// <summary>
@ -132,7 +139,7 @@ namespace SDKTemplate
/// <summary>
/// Records an MP4 video to a StorageFile
/// </summary>
private async void VideoButton_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
private async void VideoButton_Click(object sender, RoutedEventArgs e)
{
if (_previewer.IsPreviewing)
{
@ -141,7 +148,7 @@ namespace SDKTemplate
try
{
// Create storage file in Video Library
var videoFile = await KnownFolders.VideosLibrary.CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption.GenerateUniqueName);
var videoFile = await _captureFolder.CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption.GenerateUniqueName);
var encodingProfile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto);
await _previewer.MediaCapture.StartRecordToStorageFileAsync(encodingProfile, videoFile);

Просмотреть файл

@ -3,7 +3,7 @@
<Identity Name="Microsoft.SDKSamples.CameraResolution.JS" Version="1.0.0.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
<mp:PhoneIdentity PhoneProductId="97c9deff-bfd1-434f-9da0-aee0febba635" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
<Properties>
<DisplayName>CameraProfile</DisplayName>
<DisplayName>CameraProfile JS Sample</DisplayName>
<PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
<Logo>images\storelogo-sdk.png</Logo>
</Properties>

Просмотреть файл

@ -30,10 +30,10 @@
</div>
<div id="scenarioContent">
<select id="previewSettings" class="win-dropdown">
<option selected="selected" value"">Preview Settings</option>
<option selected="selected" value="">Preview Settings</option>
</select>
<select id="photoSettings" class="win-dropdown">
<option selected="selected" value"">Photo Settings</option>
<option selected="selected" value="">Photo Settings</option>
</select>
<button id="photoButton" class="win-button" disabled>Take Photo</button>
</div>

Просмотреть файл

@ -84,7 +84,7 @@
if (cameraSettings.value == "")
return;
oMediaCapture.videoDeviceController.setMediaStreamPropertiesAsync(Capture.MediaStreamType.videoPreview, allProperties[cameraSettings.value]);
mediaCapture.videoDeviceController.setMediaStreamPropertiesAsync(Capture.MediaStreamType.videoPreview, allProperties[cameraSettings.value]);
}
}

Просмотреть файл

@ -13,6 +13,9 @@
"use strict";
var Capture = Windows.Media.Capture;
var StorageLibrary = Windows.Storage.StorageLibrary;
var KnownLibraryId = Windows.Storage.KnownLibraryId;
var ApplicationData = Windows.Storage.ApplicationData;
var mediaCapture = null,
previewProperties = [],
@ -20,6 +23,9 @@
var isPreviewing = false;
// Folder in which the captures will be stored (initialized in SetupUiAsync)
var captureFolder;
var page = WinJS.UI.Pages.define("/html/Scenario2_PhotoSettings.html", {
ready: function (element, options) {
document.getElementById("initCameraBtn").addEventListener("click", initCameraBtn_click, false);
@ -71,7 +77,12 @@
/// Initializes the camera and populates the UI
/// </summary>
function initCameraBtn_click() {
initializeCameraAsync()
return StorageLibrary.getLibraryAsync(KnownLibraryId.pictures)
.then(function (picturesLibrary) {
// Fall back to the local app storage if the Pictures Library is not available
captureFolder = picturesLibrary.saveFolder || ApplicationData.current.localFolder;
return initializeCameraAsync();
})
.then(function () {
initCameraBtn.style.visibility = "hidden";
checkIfStreamsAreIdentical();
@ -117,7 +128,7 @@
var Storage = Windows.Storage;
Storage.KnownFolders.picturesLibrary.createFileAsync("SimplePhoto.jpg", Storage.CreationCollisionOption.generateUniqueName)
captureFolder.createFileAsync("SimplePhoto.jpg", Storage.CreationCollisionOption.generateUniqueName)
.then(function (file) {
return mediaCapture.capturePhotoToStorageFileAsync(Windows.Media.MediaProperties.ImageEncodingProperties.createJpeg(), file)
.then(function () {

Просмотреть файл

@ -14,6 +14,10 @@
var Capture = Windows.Media.Capture;
var MediaProperties = Windows.Media.MediaProperties;
var StorageLibrary = Windows.Storage.StorageLibrary;
var KnownLibraryId = Windows.Storage.KnownLibraryId;
var ApplicationData = Windows.Storage.ApplicationData;
var mediaCapture = null,
previewProperties = [],
@ -22,6 +26,9 @@
var isPreviewing = false;
var isRecording = false;
// Folder in which the captures will be stored (availability check performed in SetupUiAsync)
var captureFolder = Windows.Storage.KnownFolders.videosLibrary;
var page = WinJS.UI.Pages.define("/html/Scenario3_AspectRatio.html", {
ready: function (element, options) {
document.getElementById("initCameraBtn").addEventListener("click", initCameraBtn_click, false);
@ -83,11 +90,16 @@
/// Initializes the camera and populates the UI
/// </summary>
function initCameraBtn_click() {
initializeCameraAsync()
return StorageLibrary.getLibraryAsync(KnownLibraryId.pictures)
.then(function (picturesLibrary) {
// Fall back to the local app storage if the Pictures Library is not available
captureFolder = picturesLibrary.saveFolder || ApplicationData.current.localFolder;
return initializeCameraAsync();
})
.then(function () {
initCameraBtn.style.visibility = "hidden";
checkIfStreamsAreIdentical();
populateComboBoxes();
populateComboBox();
videoButton.disabled = false;
});
}
@ -100,7 +112,7 @@
// The first element is just text
if (previewSettings.value == "")
return;
console.log(previewSettings.value)
mediaCapture.videoDeviceController.setMediaStreamPropertiesAsync(Capture.MediaStreamType.videoPreview, previewProperties[previewSettings.value]);
// The preview just changed, update the video combo box
@ -116,7 +128,6 @@
// The first element is just text
if (videoSettings.value == "")
return;
mediaCapture.videoDeviceController.setMediaStreamPropertiesAsync(Capture.MediaStreamType.videoRecord, videoProperties[videoSettings.value]);
}
}
@ -131,7 +142,7 @@
var file = null;
// Create a storage file and begin recording
Storage.KnownFolders.videosLibrary.createFileAsync("SimpleVideo.mp4", Storage.CreationCollisionOption.generateUniqueName)
captureFolder.createFileAsync("SimpleVideo.mp4", Storage.CreationCollisionOption.generateUniqueName)
.then(function (videoFile) {
file = videoFile;
var encodingProfile = MediaProperties.MediaEncodingProfile.createMp4(MediaProperties.VideoEncodingQuality.auto);
@ -185,7 +196,7 @@
/// <summary>
/// Populates the combo boxes with preview settings and matching ratio settings for the video stream
/// </summary>
function populateComboBoxes() {
function populateComboBox() {
// Query all properties preview properties of the device
previewProperties = mediaCapture.videoDeviceController.getAvailableMediaStreamProperties(Capture.MediaStreamType.videoPreview);
@ -194,8 +205,6 @@
var streamResolution = new streamResolutionHelper(properties);
addOptionToComboBox(previewSettings, streamResolution.getFriendlyName(true), index);
});
MatchPreviewAspectRatio();
}
/// <summary>
@ -216,10 +225,10 @@
// Get all formats that have the same-ish aspect ratio as the preview and create new entries in the UI
// Allow for some tolerance in the aspect ratio comparison
const ASPECT_RATIO_TOLERANCE = 0.015;
videoProperties.forEach(function (properties) {
videoProperties.forEach(function (properties, index) {
var streamHelper = new streamResolutionHelper(properties);
if (Math.abs(streamHelper.aspectRatio() - previewProperties.aspectRatio()) < ASPECT_RATIO_TOLERANCE) {
addOptionToComboBox(videoSettings, streamHelper.getFriendlyName(true));
addOptionToComboBox(videoSettings, streamHelper.getFriendlyName(true), index);
}
})
}

Просмотреть файл

@ -32,12 +32,11 @@
</TextBlock>
</StackPanel>
<StackPanel Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top">
<ComboBox Name="CameraSettings" PlaceholderText="Preview Settings" SelectionChanged="ComboBoxSettings_Changed" Width="auto"/>
</StackPanel>
<ComboBox Name="CameraSettings" PlaceholderText="Preview Settings" SelectionChanged="ComboBoxSettings_Changed"
Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top" Width="Auto"/>
<Button Grid.Row="2" Content="Initialize Camera" Tapped="InitializeCameraButton_Tapped"
HorizontalAlignment="Center" VerticalAlignment="Center"></Button>
<Button Grid.Row="2" Content="Initialize Camera" Click="InitializeCameraButton_Click" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Viewbox Grid.Row="2">
<!--Camera preview-->
<CaptureElement Name="PreviewControl" Stretch="Uniform" Visibility="Collapsed"/>

Просмотреть файл

@ -35,12 +35,11 @@
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top">
<ComboBox Name="PreviewSettings" PlaceholderText="Preview Settings" SelectionChanged="PreviewSettings_Changed" Width="auto"/>
<ComboBox Name="PhotoSettings" PlaceholderText="Photo Settings" SelectionChanged="PhotoSettings_Changed" Width="auto"/>
<Button Name="PhotoButton" Tapped="PhotoButton_Tapped" IsEnabled="False">Take Photo</Button>
<Button Name="PhotoButton" Click="PhotoButton_Click" IsEnabled="False">Take Photo</Button>
</StackPanel>
<Button Grid.Row="2" Content="Initialize Camera" Tapped="InitializeCameraButton_Tapped"
HorizontalAlignment="Center" VerticalAlignment="Center">
</Button>
<Button Grid.Row="2" Content="Initialize Camera" Click="InitializeCameraButton_Click" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Viewbox Grid.Row="2">
<!--Camera preview-->
<CaptureElement Name="PreviewControl" Stretch="Uniform" Visibility="Collapsed"/>

Просмотреть файл

@ -35,10 +35,10 @@
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top">
<ComboBox Name="PreviewSettings" PlaceholderText="Preview Settings" SelectionChanged="PreviewSettings_Changed" Width="auto"/>
<ComboBox Name="VideoSettings" PlaceholderText="Video Settings" SelectionChanged="VideoSettings_Changed" Width="auto"/>
<Button Name="VideoButton" Tapped="VideoButton_Tapped" IsEnabled="False">Record Video</Button>
<Button Name="VideoButton" Click="VideoButton_Click" IsEnabled="False">Record Video</Button>
</StackPanel>
<Button Grid.Row="2" Content="Initialize Camera" Tapped="InitializeCameraButton_Tapped"
<Button Grid.Row="2" Content="Initialize Camera" Click="InitializeCameraButton_Click"
HorizontalAlignment="Center" VerticalAlignment="Center">
</Button>
<Viewbox Grid.Row="2">

Просмотреть файл

@ -44,6 +44,7 @@ MainPage::MainPage()
, _displayOrientation(DisplayOrientations::Portrait)
, _displayRequest(ref new Windows::System::Display::DisplayRequest())
, RotationKey({ 0xC380465D, 0x2271, 0x428C,{ 0x9B, 0x83, 0xEC, 0xEA, 0x3B, 0x4A, 0x85, 0xC1 } })
, _captureFolder(nullptr)
{
InitializeComponent();
@ -268,14 +269,17 @@ task<void> MainPage::TakePhotoAsync()
return create_task(_mediaCapture->CapturePhotoToStreamAsync(Windows::Media::MediaProperties::ImageEncodingProperties::CreateJpeg(), inputStream))
.then([this, inputStream]()
{
WriteLine("Photo taken!");
return create_task(_captureFolder->CreateFileAsync("SimplePhoto.jpg", CreationCollisionOption::GenerateUniqueName));
}).then([this, inputStream](StorageFile^ file)
{
WriteLine("Photo taken! Saving to " + file->Path);
// Done taking a photo, so re-enable the button
VideoButton->IsEnabled = true;
VideoButton->Opacity = 1;
auto photoOrientation = ConvertOrientationToPhotoOrientation(GetCameraOrientation());
return ReencodeAndSavePhotoAsync(inputStream, photoOrientation);
return ReencodeAndSavePhotoAsync(inputStream, file, photoOrientation);
}).then([this](task<void> previousTask)
{
try
@ -296,7 +300,7 @@ task<void> MainPage::TakePhotoAsync()
/// <returns></returns>
task<void> MainPage::StartRecordingAsync()
{
return create_task(KnownFolders::PicturesLibrary->CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption::GenerateUniqueName))
return create_task(_captureFolder->CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption::GenerateUniqueName))
.then([this](StorageFile^ file)
{
// Calculate rotation angle, taking mirroring into account if necessary
@ -304,12 +308,11 @@ task<void> MainPage::StartRecordingAsync()
auto encodingProfile = MediaProperties::MediaEncodingProfile::CreateMp4(MediaProperties::VideoEncodingQuality::Auto);
encodingProfile->Video->Properties->Insert(RotationKey, rotationAngle);
WriteLine("Starting recording...");
return create_task(_mediaCapture->StartRecordToStorageFileAsync(encodingProfile, file))
.then([this]()
.then([this, file]()
{
_isRecording = true;
WriteLine("Started recording!");
WriteLine("Started recording to " + file->Path);
});
}).then([this](task<void> previousTask)
{
@ -378,22 +381,21 @@ task<DeviceInformation^> MainPage::FindCameraDeviceByPanelAsync(Windows::Devices
/// Applies the given orientation to a photo stream and saves it as a StorageFile
/// </summary>
/// <param name="stream">The photo stream</param>
/// <param name="file">The StorageFile in which the photo stream will be saved</param>
/// <param name="photoOrientation">The orientation metadata to apply to the photo</param>
/// <returns></returns>
task<void> MainPage::ReencodeAndSavePhotoAsync(Streams::IRandomAccessStream^ stream, FileProperties::PhotoOrientation photoOrientation)
task<void> MainPage::ReencodeAndSavePhotoAsync(Streams::IRandomAccessStream^ stream, StorageFile^ file, FileProperties::PhotoOrientation photoOrientation)
{
// Using this state variable to pass multiple values through our task chain
ReencodeState^ state = ref new ReencodeState();
state->_file = file;
state->_orientation = photoOrientation;
return create_task(BitmapDecoder::CreateAsync(stream))
.then([state](BitmapDecoder^ decoder)
{
state->_decoder = decoder;
return create_task(KnownFolders::PicturesLibrary->CreateFileAsync("SimplePhoto.jpg", CreationCollisionOption::GenerateUniqueName));
}).then([](StorageFile^ file)
{
return create_task(file->OpenAsync(FileAccessMode::ReadWrite));
return create_task(state->_file->OpenAsync(FileAccessMode::ReadWrite));
}).then([state](Streams::IRandomAccessStream^ outputStream)
{
return create_task(BitmapEncoder::CreateForTranscodingAsync(outputStream, state->_decoder));
@ -451,6 +453,17 @@ task<void> MainPage::SetupUiAsync()
_deviceOrientation = _orientationSensor->GetCurrentOrientation();
}
create_task(StorageLibrary::GetLibraryAsync(KnownLibraryId::Pictures))
.then([this](StorageLibrary^ picturesLibrary)
{
_captureFolder = picturesLibrary->SaveFolder;
if (_captureFolder == nullptr)
{
// In this case fall back to the local app storage since the Pictures Library is not available
_captureFolder = ApplicationData::Current->LocalFolder;
}
});
// Hide the status bar
if (Windows::Foundation::Metadata::ApiInformation::IsTypePresent("Windows.UI.ViewManagement.StatusBar"))
{
@ -747,12 +760,12 @@ void MainPage::DisplayInformation_OrientationChanged(DisplayInformation^ sender,
}));
}
void MainPage::PhotoButton_Tapped(Object^, Windows::UI::Xaml::RoutedEventArgs^)
void MainPage::PhotoButton_Click(Object^, Windows::UI::Xaml::RoutedEventArgs^)
{
TakePhotoAsync();
}
void MainPage::VideoButton_Tapped(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
void MainPage::VideoButton_Click(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
task<void> taskToExecute;
if (!_isRecording)

Просмотреть файл

@ -20,6 +20,7 @@ namespace CameraStarterKit
internal:
Windows::Graphics::Imaging::BitmapDecoder^ _decoder;
Windows::Graphics::Imaging::BitmapEncoder^ _encoder;
Windows::Storage::StorageFile^ _file;
Windows::Storage::FileProperties::PhotoOrientation _orientation;
};
@ -52,6 +53,9 @@ namespace CameraStarterKit
// Reference: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868174.aspx
const GUID RotationKey;
// Folder in which the captures will be stored (availability check performed in SetupUiAsync)
Windows::Storage::StorageFolder^ _captureFolder;
// Event tokens
Windows::Foundation::EventRegistrationToken _applicationSuspendingEventToken;
Windows::Foundation::EventRegistrationToken _applicationResumingEventToken;
@ -74,7 +78,7 @@ namespace CameraStarterKit
// Helpers
Concurrency::task<Windows::Devices::Enumeration::DeviceInformation^> FindCameraDeviceByPanelAsync(Windows::Devices::Enumeration::Panel panel);
Concurrency::task<void> ReencodeAndSavePhotoAsync(Windows::Storage::Streams::IRandomAccessStream^ stream, Windows::Storage::FileProperties::PhotoOrientation photoOrientation);
Concurrency::task<void> ReencodeAndSavePhotoAsync(Windows::Storage::Streams::IRandomAccessStream^ stream, Windows::Storage::StorageFile^ file, Windows::Storage::FileProperties::PhotoOrientation photoOrientation);
void UpdateCaptureControls();
Concurrency::task<void> SetupUiAsync();
Concurrency::task<void> CleanupUiAsync();
@ -95,8 +99,8 @@ namespace CameraStarterKit
void Application_Suspending(Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ e);
void Application_Resuming(Object^ sender, Object^ args);
void DisplayInformation_OrientationChanged(Windows::Graphics::Display::DisplayInformation^ sender, Object^ args);
void PhotoButton_Tapped(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void VideoButton_Tapped(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void PhotoButton_Click(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void VideoButton_Click(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void SystemMediaControls_PropertyChanged(Windows::Media::SystemMediaTransportControls^ sender, Windows::Media::SystemMediaTransportControlsPropertyChangedEventArgs^ args);
void OrientationSensor_OrientationChanged(Windows::Devices::Sensors::SimpleOrientationSensor^, Windows::Devices::Sensors::SimpleOrientationSensorOrientationChangedEventArgs^);
void HardwareButtons_CameraPressed(Platform::Object^, Windows::Phone::UI::Input::CameraEventArgs^);

Просмотреть файл

@ -50,6 +50,9 @@ namespace CameraStarterKit
// Reference: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868174.aspx
private static readonly Guid RotationKey = new Guid("C380465D-2271-428C-9B83-ECEA3B4A85C1");
// Folder in which the captures will be stored (initialized in SetupUiAsync)
private StorageFolder _captureFolder = null;
// Prevent the screen from sleeping while the camera is running
private readonly DisplayRequest _displayRequest = new DisplayRequest();
@ -191,12 +194,12 @@ namespace CameraStarterKit
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => UpdateButtonOrientation());
}
private async void PhotoButton_Tapped(object sender, TappedRoutedEventArgs e)
private async void PhotoButton_Click(object sender, RoutedEventArgs e)
{
await TakePhotoAsync();
}
private async void VideoButton_Tapped(object sender, TappedRoutedEventArgs e)
private async void VideoButton_Click(object sender, RoutedEventArgs e)
{
if (!_isRecording)
{
@ -385,20 +388,25 @@ namespace CameraStarterKit
var stream = new InMemoryRandomAccessStream();
Debug.WriteLine("Taking photo...");
await _mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), stream);
try
{
Debug.WriteLine("Taking photo...");
await _mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), stream);
Debug.WriteLine("Photo taken!");
var file = await _captureFolder.CreateFileAsync("SimplePhoto.jpg", CreationCollisionOption.GenerateUniqueName);
Debug.WriteLine("Photo taken! Saving to " + file.Path);
var photoOrientation = ConvertOrientationToPhotoOrientation(GetCameraOrientation());
await ReencodeAndSavePhotoAsync(stream, photoOrientation);
await ReencodeAndSavePhotoAsync(stream, file, photoOrientation);
Debug.WriteLine("Photo saved!");
}
catch (Exception ex)
{
// File I/O errors are reported as exceptions
Debug.WriteLine("Exception when taking a photo: {0}", ex.ToString());
Debug.WriteLine("Exception when taking a photo: " + ex.ToString());
}
// Done taking a photo, so re-enable the button
@ -415,7 +423,7 @@ namespace CameraStarterKit
try
{
// Create storage file in Pictures Library
var videoFile = await KnownFolders.PicturesLibrary.CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption.GenerateUniqueName);
var videoFile = await _captureFolder.CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption.GenerateUniqueName);
var encodingProfile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto);
@ -423,7 +431,7 @@ namespace CameraStarterKit
var rotationAngle = 360 - ConvertDeviceOrientationToDegrees(GetCameraOrientation());
encodingProfile.Video.Properties.Add(RotationKey, PropertyValue.CreateInt32(rotationAngle));
Debug.WriteLine("Starting recording...");
Debug.WriteLine("Starting recording to " + videoFile.Path);
await _mediaCapture.StartRecordToStorageFileAsync(encodingProfile, videoFile);
_isRecording = true;
@ -433,7 +441,7 @@ namespace CameraStarterKit
catch (Exception ex)
{
// File I/O errors are reported as exceptions
Debug.WriteLine("Exception when starting video recording: {0}", ex.ToString());
Debug.WriteLine("Exception when starting video recording: " + ex.ToString());
}
}
@ -515,6 +523,10 @@ namespace CameraStarterKit
}
RegisterEventHandlers();
var picturesLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures);
// Fall back to the local app storage if the Pictures Library is not available
_captureFolder = picturesLibrary.SaveFolder ?? ApplicationData.Current.LocalFolder;
}
/// <summary>
@ -621,16 +633,15 @@ namespace CameraStarterKit
/// Applies the given orientation to a photo stream and saves it as a StorageFile
/// </summary>
/// <param name="stream">The photo stream</param>
/// <param name="file">The StorageFile in which the photo stream will be saved</param>
/// <param name="photoOrientation">The orientation metadata to apply to the photo</param>
/// <returns></returns>
private static async Task ReencodeAndSavePhotoAsync(IRandomAccessStream stream, PhotoOrientation photoOrientation)
private static async Task ReencodeAndSavePhotoAsync(IRandomAccessStream stream, StorageFile file, PhotoOrientation photoOrientation)
{
using (var inputStream = stream)
{
var decoder = await BitmapDecoder.CreateAsync(inputStream);
var file = await KnownFolders.PicturesLibrary.CreateFileAsync("SimplePhoto.jpeg", CreationCollisionOption.GenerateUniqueName);
using (var outputStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateForTranscodingAsync(outputStream, decoder);

Просмотреть файл

@ -13,7 +13,7 @@
<mp:PhoneIdentity PhoneProductId="d1e912c9-777b-4ead-9fe2-c797d7eebae2" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>
<DisplayName>CameraStarterKit</DisplayName>
<DisplayName>CameraStarterKit JS Sample</DisplayName>
<PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
<Logo>images\storelogo-sdk.png</Logo>
</Properties>

Просмотреть файл

@ -20,6 +20,9 @@
var Media = Windows.Media;
var SimpleOrientation = Windows.Devices.Sensors.SimpleOrientation;
var SimpleOrientationSensor = Windows.Devices.Sensors.SimpleOrientationSensor;
var StorageLibrary = Windows.Storage.StorageLibrary;
var KnownLibraryId = Windows.Storage.KnownLibraryId;
var ApplicationData = Windows.Storage.ApplicationData;
// Receive notifications about rotation of the device and UI and apply any necessary rotation to the preview stream and UI controls
var oOrientationSensor = SimpleOrientationSensor.getDefault(),
@ -47,6 +50,9 @@
// Reference: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868174.aspx
var RotationKey = "C380465D-2271-428C-9B83-ECEA3B4A85C1";
// Folder in which the captures will be stored (initialized in SetupUiAsync)
var oCaptureFolder;
// Initialization
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
@ -250,13 +256,18 @@
console.log("Taking photo...");
return oMediaCapture.capturePhotoToStreamAsync(Windows.Media.MediaProperties.ImageEncodingProperties.createJpeg(), inputStream)
.then(function () {
console.log("Photo taken!");
return oCaptureFolder.createFileAsync("SimplePhoto.jpg", Windows.Storage.CreationCollisionOption.generateUniqueName);
})
.then(function (file) {
console.log("Photo taken! Saving to " + file.path);
// Done taking a photo, so re-enable the button
videoButton.disabled = false;
var photoOrientation = convertOrientationToPhotoOrientation(getCameraOrientation());
return reencodeAndSavePhotoAsync(inputStream, photoOrientation);
return reencodeAndSavePhotoAsync(inputStream, file, photoOrientation);
}).then(function () {
console.log("Photo saved!");
}, function (error) {
console.log(error.message);
}).done();
@ -267,14 +278,14 @@
/// </summary>
/// <returns></returns>
function startRecordingAsync() {
return Windows.Storage.KnownFolders.picturesLibrary.createFileAsync("SimpleVideo.mp4", Windows.Storage.CreationCollisionOption.generateUniqueName)
return oCaptureFolder.createFileAsync("SimpleVideo.mp4", Windows.Storage.CreationCollisionOption.generateUniqueName)
.then(function (file) {
// Calculate rotation angle, taking mirroring into account if necessary
var rotationAngle = 360 - convertDeviceOrientationToDegrees(getCameraOrientation());
var encodingProfile = Windows.Media.MediaProperties.MediaEncodingProfile.createMp4(Windows.Media.MediaProperties.VideoEncodingQuality.auto);
encodingProfile.video.properties.insert(RotationKey, rotationAngle);
console.log("Starting recording...");
console.log("Starting recording to " + file.path);
return oMediaCapture.startRecordToStorageFileAsync(encodingProfile, file)
.then(function () {
isRecording = true;
@ -328,7 +339,7 @@
/// <param name="stream">The photo stream</param>
/// <param name="photoOrientation">The orientation metadata to apply to the photo</param>
/// <returns></returns>
function reencodeAndSavePhotoAsync(inputStream, orientation) {
function reencodeAndSavePhotoAsync(inputStream, file, orientation) {
var Imaging = Windows.Graphics.Imaging;
var bitmapDecoder = null,
bitmapEncoder = null,
@ -337,8 +348,6 @@
return Imaging.BitmapDecoder.createAsync(inputStream)
.then(function (decoder) {
bitmapDecoder = decoder;
return Windows.Storage.KnownFolders.picturesLibrary.createFileAsync("SimplePhoto.jpg", Windows.Storage.CreationCollisionOption.generateUniqueName);
}).then(function (file) {
return file.openAsync(Windows.Storage.FileAccessMode.readWrite);
}).then(function (outStream) {
outputStream = outStream;
@ -396,13 +405,19 @@
oDeviceOrientation = oOrientationSensor.getCurrentOrientation();
}
// Hide the status bar
if (Windows.Foundation.Metadata.ApiInformation.isTypePresent("Windows.UI.ViewManagement.StatusBar")) {
return Windows.UI.ViewManagement.StatusBar.getForCurrentView().hideAsync();
}
else {
return WinJS.Promise.as();
}
return StorageLibrary.getLibraryAsync(KnownLibraryId.pictures)
.then(function (picturesLibrary) {
// Fall back to the local app storage if the Pictures Library is not available
oCaptureFolder = picturesLibrary.saveFolder || ApplicationData.current.localFolder;
// Hide the status bar
if (Windows.Foundation.Metadata.ApiInformation.isTypePresent("Windows.UI.ViewManagement.StatusBar")) {
return Windows.UI.ViewManagement.StatusBar.getForCurrentView().hideAsync();
}
else {
return WinJS.Promise.as();
}
});
}
/// <summary>

Просмотреть файл

@ -43,13 +43,13 @@
</Style>
</StackPanel.Resources>
<Button Name="PhotoButton" Tapped="PhotoButton_Tapped" IsEnabled="False">
<Button Name="PhotoButton" Click="PhotoButton_Click" IsEnabled="False">
<Viewbox MaxHeight="40" MaxWidth="40">
<SymbolIcon Symbol="Camera"/>
</Viewbox>
</Button>
<Button Name="VideoButton" Tapped="VideoButton_Tapped" IsEnabled="False">
<Button Name="VideoButton" Click="VideoButton_Click" IsEnabled="False">
<Grid>
<Ellipse x:Name="StartRecordingIcon" Fill="Red" Width="20" Height="20"/>
<Rectangle x:Name="StopRecordingIcon" Fill="White" Width="20" Height="20" Visibility="Collapsed"/>

Просмотреть файл

@ -52,6 +52,9 @@ Namespace Global.CameraStarterKit
' Reference: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868174.aspx
Private Shared ReadOnly RotationKey As Guid = New Guid("C380465D-2271-428C-9B83-ECEA3B4A85C1")
' Folder in which the captures will be stored (initialized in SetupUiAsync)
Private _captureFolder As StorageFolder = Nothing
' Prevent the screen from sleeping while the camera is running
Private ReadOnly _displayRequest As DisplayRequest = New DisplayRequest()
@ -154,11 +157,11 @@ Namespace Global.CameraStarterKit
Await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, Sub() UpdateButtonOrientation())
End Sub
Private Async Sub PhotoButton_Tapped(sender As Object, e As TappedRoutedEventArgs)
Private Async Sub PhotoButton_Click(sender As Object, e As RoutedEventArgs)
Await TakePhotoAsync()
End Sub
Private Async Sub VideoButton_Tapped(sender As Object, e As TappedRoutedEventArgs)
Private Async Sub VideoButton_Click(sender As Object, e As RoutedEventArgs)
If Not _isRecording Then
Await StartRecordingAsync()
Else
@ -282,14 +285,15 @@ Namespace Global.CameraStarterKit
VideoButton.IsEnabled = _mediaCapture.MediaCaptureSettings.ConcurrentRecordAndPhotoSupported
VideoButton.Opacity = If(VideoButton.IsEnabled, 1, 0)
Dim stream = New InMemoryRandomAccessStream()
Debug.WriteLine("Taking photo...")
Await _mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), stream)
Try
Debug.WriteLine("Taking photo...")
Await _mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), stream)
Debug.WriteLine("Photo taken!")
Dim file = Await _captureFolder.CreateFileAsync("SimplePhoto.jpg", CreationCollisionOption.GenerateUniqueName)
Debug.WriteLine("Photo taken! Saving to " & file.Path)
Dim photoOrientation = ConvertOrientationToPhotoOrientation(GetCameraOrientation())
Await ReencodeAndSavePhotoAsync(stream, photoOrientation)
Await ReencodeAndSavePhotoAsync(stream, file, photoOrientation)
Catch ex As Exception
Debug.WriteLine("Exception when taking a photo: {0}", ex.ToString())
Debug.WriteLine("Exception when taking a photo: " & ex.ToString())
End Try
VideoButton.IsEnabled = True
@ -303,17 +307,17 @@ Namespace Global.CameraStarterKit
Private Async Function StartRecordingAsync() As Task
Try
' Create storage file in Pictures Library
Dim videoFile = Await KnownFolders.PicturesLibrary.CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption.GenerateUniqueName)
Dim videoFile = Await _captureFolder.CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption.GenerateUniqueName)
Dim encodingProfile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto)
' Calculate rotation angle, taking mirroring into account if necessary
Dim rotationAngle = 360 - ConvertDeviceOrientationToDegrees(GetCameraOrientation())
encodingProfile.Video.Properties.Add(RotationKey, PropertyValue.CreateInt32(rotationAngle))
Debug.WriteLine("Starting recording...")
Debug.WriteLine("Starting recording to " & videoFile.Path)
Await _mediaCapture.StartRecordToStorageFileAsync(encodingProfile, videoFile)
_isRecording = True
Debug.WriteLine("Started recording!")
Catch ex As Exception
Debug.WriteLine("Exception when starting video recording: {0}", ex.ToString())
Debug.WriteLine("Exception when starting video recording: " & ex.ToString())
End Try
End Function
@ -374,6 +378,10 @@ Namespace Global.CameraStarterKit
End If
RegisterEventHandlers()
Dim picturesLibrary = Await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures)
' Fall back to the local app storage if the Pictures Library is not available
_captureFolder = If(picturesLibrary.SaveFolder, ApplicationData.Current.LocalFolder)
End Function
''' <summary>
@ -453,12 +461,12 @@ Namespace Global.CameraStarterKit
''' Applies the given orientation to a photo stream and saves it as a StorageFile
''' </summary>
''' <param name="stream">The photo stream</param>
''' <param name="file">The StorageFile in which the photo stream will be saved</param>
''' <param name="photoOrientation">The orientation metadata to apply to the photo</param>
''' <returns></returns>
Private Shared Async Function ReencodeAndSavePhotoAsync(stream As IRandomAccessStream, photoOrientation As PhotoOrientation) As Task
Private Shared Async Function ReencodeAndSavePhotoAsync(stream As IRandomAccessStream, file As StorageFile, photoOrientation As PhotoOrientation) As Task
Using inputStream = stream
Dim decoder = Await BitmapDecoder.CreateAsync(inputStream)
Dim file = Await KnownFolders.PicturesLibrary.CreateFileAsync("SimplePhoto.jpeg", CreationCollisionOption.GenerateUniqueName)
Using outputStream = Await file.OpenAsync(FileAccessMode.ReadWrite)
Dim encoder = Await BitmapEncoder.CreateForTranscodingAsync(outputStream, decoder)
Dim properties = New BitmapPropertySet From {{"System.Photo.Orientation", New BitmapTypedValue(photoOrientation, PropertyType.UInt16)}}

Просмотреть файл

@ -48,6 +48,7 @@ MainPage::MainPage()
, _videoStabilizationEffect(nullptr)
, _inputPropertiesBackup(nullptr)
, _outputPropertiesBackup(nullptr)
, _captureFolder(nullptr)
{
InitializeComponent();
@ -416,7 +417,7 @@ task<void> MainPage::CleanUpVideoStabilizationEffectAsync()
task<void> MainPage::StartRecordingAsync()
{
// Create storage file in Pictures Library
return create_task(KnownFolders::PicturesLibrary->CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption::GenerateUniqueName))
return create_task(_captureFolder->CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption::GenerateUniqueName))
.then([this](StorageFile^ file)
{
// Calculate rotation angle, taking mirroring into account if necessary
@ -425,12 +426,11 @@ task<void> MainPage::StartRecordingAsync()
// Add it to the encoding profile, or edit the value if the GUID was already a part of the properties
_encodingProfile->Video->Properties->Insert(RotationKey, rotationAngle);
WriteLine("Starting recording...");
return create_task(_mediaCapture->StartRecordToStorageFileAsync(_encodingProfile, file))
.then([this]()
.then([this, file]()
{
_isRecording = true;
WriteLine("Started recording!");
WriteLine("Started recording to: " + file->Path);
});
}).then([this](task<void> previousTask)
{
@ -556,6 +556,17 @@ task<void> MainPage::SetupUiAsync()
_deviceOrientation = _orientationSensor->GetCurrentOrientation();
}
create_task(StorageLibrary::GetLibraryAsync(KnownLibraryId::Pictures))
.then([this](StorageLibrary^ picturesLibrary)
{
_captureFolder = picturesLibrary->SaveFolder;
if (_captureFolder == nullptr)
{
// In this case fall back to the local app storage since the Pictures Library is not available
_captureFolder = ApplicationData::Current->LocalFolder;
}
});
// Hide the status bar
if (Windows::Foundation::Metadata::ApiInformation::IsTypePresent("Windows.UI.ViewManagement.StatusBar"))
{
@ -845,7 +856,7 @@ void MainPage::DisplayInformation_OrientationChanged(DisplayInformation^ sender,
}));
}
void MainPage::VsToggleButton_Tapped(Object^, Windows::UI::Xaml::RoutedEventArgs^)
void MainPage::VsToggleButton_Click(Object^, Windows::UI::Xaml::RoutedEventArgs^)
{
// Note that for the most part, this button is disabled during recording, except when VS is turned off automatically
task<void> taskToExecute;
@ -884,7 +895,7 @@ void MainPage::VsToggleButton_Tapped(Object^, Windows::UI::Xaml::RoutedEventArgs
});
}
void MainPage::VideoButton_Tapped(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
void MainPage::VideoButton_Click(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
task<void> taskToExecute;
if (!_isRecording)

Просмотреть файл

@ -45,6 +45,9 @@ namespace CameraVideoStabilization
// Reference: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868174.aspx
const GUID RotationKey;
// Folder in which the captures will be stored (availability check performed in SetupUiAsync)
Windows::Storage::StorageFolder^ _captureFolder;
Windows::Media::Core::VideoStabilizationEffect^ _videoStabilizationEffect;
Windows::Media::MediaProperties::VideoEncodingProperties^ _inputPropertiesBackup;
Windows::Media::MediaProperties::VideoEncodingProperties^ _outputPropertiesBackup;
@ -94,8 +97,8 @@ namespace CameraVideoStabilization
void Application_Suspending(Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ e);
void Application_Resuming(Object^ sender, Object^ args);
void DisplayInformation_OrientationChanged(Windows::Graphics::Display::DisplayInformation^ sender, Object^ args);
void VsToggleButton_Tapped(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void VideoButton_Tapped(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void VsToggleButton_Click(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void VideoButton_Click(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void SystemMediaControls_PropertyChanged(Windows::Media::SystemMediaTransportControls^ sender, Windows::Media::SystemMediaTransportControlsPropertyChangedEventArgs^ args);
void VideoStabilizationEffect_EnabledChanged(Windows::Media::Core::VideoStabilizationEffect^ sender, Windows::Media::Core::VideoStabilizationEffectEnabledChangedEventArgs^ args);
void OrientationSensor_OrientationChanged(Windows::Devices::Sensors::SimpleOrientationSensor^, Windows::Devices::Sensors::SimpleOrientationSensorOrientationChangedEventArgs^);

Просмотреть файл

@ -50,6 +50,9 @@ namespace CameraVideoStabilization
// Reference: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868174.aspx
private static readonly Guid RotationKey = new Guid("C380465D-2271-428C-9B83-ECEA3B4A85C1");
// Folder in which the captures will be stored (initialized in SetupUiAsync)
private StorageFolder _captureFolder = null;
// Prevent the screen from sleeping while the camera is running
private readonly DisplayRequest _displayRequest = new DisplayRequest();
@ -196,7 +199,7 @@ namespace CameraVideoStabilization
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => UpdateButtonOrientation());
}
private async void VsToggleButton_Tapped(object sender, RoutedEventArgs e)
private async void VsToggleButton_Click(object sender, RoutedEventArgs e)
{
// Note that for the most part, this button is disabled during recording, except when VS is turned off automatically
@ -227,7 +230,7 @@ namespace CameraVideoStabilization
UpdateCaptureControls();
}
private async void VideoButton_Tapped(object sender, TappedRoutedEventArgs e)
private async void VideoButton_Click(object sender, RoutedEventArgs e)
{
if (!_isRecording)
{
@ -544,7 +547,7 @@ namespace CameraVideoStabilization
try
{
// Create storage file in Pictures Library
var videoFile = await KnownFolders.PicturesLibrary.CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption.GenerateUniqueName);
var videoFile = await _captureFolder.CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption.GenerateUniqueName);
// Calculate rotation angle, taking mirroring into account if necessary
var rotationAngle = 360 - ConvertDeviceOrientationToDegrees(GetCameraOrientation());
@ -552,7 +555,7 @@ namespace CameraVideoStabilization
// Add it to the encoding profile, or edit the value if the GUID was already a part of the properties
_encodingProfile.Video.Properties[RotationKey] = PropertyValue.CreateInt32(rotationAngle);
Debug.WriteLine("Starting recording...");
Debug.WriteLine("Starting recording to " + videoFile.Path);
await _mediaCapture.StartRecordToStorageFileAsync(_encodingProfile, videoFile);
_isRecording = true;
@ -562,7 +565,7 @@ namespace CameraVideoStabilization
catch (Exception ex)
{
// File I/O errors are reported as exceptions
Debug.WriteLine("Exception when starting video recording: {0}", ex.ToString());
Debug.WriteLine("Exception when starting video recording: " + ex.ToString());
}
}
@ -594,7 +597,7 @@ namespace CameraVideoStabilization
catch (Exception ex)
{
// File I/O errors are reported as exceptions
Debug.WriteLine("Exception when stopping video recording: {0}", ex.ToString());
Debug.WriteLine("Exception when stopping video recording: " + ex.ToString());
}
}
@ -668,6 +671,10 @@ namespace CameraVideoStabilization
}
RegisterEventHandlers();
var picturesLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures);
// Fall back to the local app storage if the Pictures Library is not available
_captureFolder = picturesLibrary.SaveFolder ?? ApplicationData.Current.LocalFolder;
}
/// <summary>
@ -766,7 +773,6 @@ namespace CameraVideoStabilization
return desiredDevice ?? allVideoDevices.FirstOrDefault();
}
#endregion Helper functions

Просмотреть файл

@ -13,7 +13,7 @@
<mp:PhoneIdentity PhoneProductId="5fbda83f-d3b6-4577-a1fe-768211883cd4" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>
<DisplayName>CameraVideoStabilization</DisplayName>
<DisplayName>CameraVideoStabilization JS Sample</DisplayName>
<PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
<Logo>images\storelogo-sdk.png</Logo>
</Properties>

Просмотреть файл

@ -23,6 +23,9 @@
var Media = Windows.Media;
var SimpleOrientation = Windows.Devices.Sensors.SimpleOrientation;
var SimpleOrientationSensor = Windows.Devices.Sensors.SimpleOrientationSensor;
var StorageLibrary = Windows.Storage.StorageLibrary;
var KnownLibraryId = Windows.Storage.KnownLibraryId;
var ApplicationData = Windows.Storage.ApplicationData;
// Receive notifications about rotation of the device and UI and apply any necessary rotation to the preview stream and UI controls
var oOrientationSensor = SimpleOrientationSensor.getDefault(),
@ -56,6 +59,9 @@
// Reference: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868174.aspx
var RotationKey = "C380465D-2271-428C-9B83-ECEA3B4A85C1";
// Folder in which the captures will be stored (initialized in SetupUiAsync)
var oCaptureFolder;
// Initialization
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
@ -392,14 +398,14 @@
/// </summary>
/// <returns></returns>
function startRecordingAsync() {
return Windows.Storage.KnownFolders.picturesLibrary.createFileAsync("SimpleVideo.mp4", Windows.Storage.CreationCollisionOption.generateUniqueName)
return oCaptureFolder.createFileAsync("SimpleVideo.mp4", Windows.Storage.CreationCollisionOption.generateUniqueName)
.then(function (file) {
// Calculate rotation angle, taking mirroring into account if necessary
var rotationAngle = 360 - convertDeviceOrientationToDegrees(getCameraOrientation());
var encodingProfile = Windows.Media.MediaProperties.MediaEncodingProfile.createMp4(Windows.Media.MediaProperties.VideoEncodingQuality.auto);
encodingProfile.video.properties.insert(RotationKey, rotationAngle);
console.log("Starting recording...");
console.log("Starting recording to " + file.path);
return oMediaCapture.startRecordToStorageFileAsync(encodingProfile, file)
.then(function () {
isRecording = true;
@ -460,7 +466,7 @@
/// <param name="stream">The photo stream</param>
/// <param name="photoOrientation">The orientation metadata to apply to the photo</param>
/// <returns></returns>
function reencodeAndSavePhotoAsync(inputStream, orientation) {
function reencodeAndSavePhotoAsync(inputStream, file, orientation) {
var Imaging = Windows.Graphics.Imaging;
var bitmapDecoder = null,
bitmapEncoder = null,
@ -469,8 +475,6 @@
return Imaging.BitmapDecoder.createAsync(inputStream)
.then(function (decoder) {
bitmapDecoder = decoder;
return Windows.Storage.KnownFolders.picturesLibrary.createFileAsync("SimplePhoto.jpg", Windows.Storage.CreationCollisionOption.generateUniqueName);
}).then(function (file) {
return file.openAsync(Windows.Storage.FileAccessMode.readWrite);
}).then(function (outStream) {
outputStream = outStream;
@ -480,7 +484,7 @@
var properties = new Imaging.BitmapPropertySet();
properties.insert("System.Photo.Orientation", new Imaging.BitmapTypedValue(orientation, Windows.Foundation.PropertyType.uint16));
return bitmapEncoder.bitmapProperties.setPropertiesAsync(properties)
}).then(function() {
}).then(function () {
return bitmapEncoder.flushAsync();
}).then(function () {
inputStream.close();
@ -558,13 +562,19 @@
oDeviceOrientation = oOrientationSensor.getCurrentOrientation();
}
// Hide the status bar
if (Windows.Foundation.Metadata.ApiInformation.isTypePresent("Windows.UI.ViewManagement.StatusBar")) {
return Windows.UI.ViewManagement.StatusBar.getForCurrentView().hideAsync();
}
else {
return WinJS.Promise.as();
}
return StorageLibrary.getLibraryAsync(KnownLibraryId.pictures)
.then(function (picturesLibrary) {
// Fall back to the local app storage if the Pictures Library is not available
oCaptureFolder = picturesLibrary.saveFolder || ApplicationData.current.localFolder;
// Hide the status bar
if (Windows.Foundation.Metadata.ApiInformation.isTypePresent("Windows.UI.ViewManagement.StatusBar")) {
return Windows.UI.ViewManagement.StatusBar.getForCurrentView().hideAsync();
}
else {
return WinJS.Promise.as();
}
})
}
/// <summary>

Просмотреть файл

@ -44,7 +44,7 @@
<StackPanel HorizontalAlignment="Right" VerticalAlignment="Center">
<!--VS Toggle button-->
<Button Name="VsToggleButton" Tapped="VsToggleButton_Tapped" IsEnabled="False">
<Button Name="VsToggleButton" Click="VsToggleButton_Click" IsEnabled="False">
<Viewbox MaxHeight="40" MaxWidth="40">
<Grid>
<!--Off icon-->
@ -66,7 +66,7 @@
</Button>
<!--Video record button-->
<Button Name="VideoButton" Tapped="VideoButton_Tapped" IsEnabled="False">
<Button Name="VideoButton" Click="VideoButton_Click" IsEnabled="False">
<Grid>
<Ellipse Name="StartRecordingIcon" Fill="Red" Width="20" Height="20"/>
<Rectangle Name="StopRecordingIcon" Fill="White" Width="20" Height="20" Visibility="Collapsed"/>

Просмотреть файл

@ -51,6 +51,9 @@ Namespace Global.CameraVideoStabilization
' Reference: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868174.aspx
Private Shared ReadOnly RotationKey As Guid = New Guid("C380465D-2271-428C-9B83-ECEA3B4A85C1")
' Folder in which the captures will be stored (initialized in SetupUiAsync)
Private _captureFolder As StorageFolder = Nothing
' Prevent the screen from sleeping while the camera is running
Private ReadOnly _displayRequest As DisplayRequest = New DisplayRequest()
@ -161,7 +164,7 @@ Namespace Global.CameraVideoStabilization
Await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, Sub() UpdateButtonOrientation())
End Sub
Private Async Sub VsToggleButton_Tapped(sender As Object, e As RoutedEventArgs)
Private Async Sub VsToggleButton_Click(sender As Object, e As RoutedEventArgs)
If Not _isRecording Then
If _videoStabilizationEffect Is Nothing Then
Await CreateVideoStabilizationEffectAsync()
@ -175,7 +178,7 @@ Namespace Global.CameraVideoStabilization
UpdateCaptureControls()
End Sub
Private Async Sub VideoButton_Tapped(sender As Object, e As TappedRoutedEventArgs)
Private Async Sub VideoButton_Click(sender As Object, e As RoutedEventArgs)
If Not _isRecording Then
Await StartRecordingAsync()
Else
@ -372,16 +375,16 @@ Namespace Global.CameraVideoStabilization
Private Async Function StartRecordingAsync() As Task
Try
' Create storage file in Pictures Library
Dim videoFile = Await KnownFolders.PicturesLibrary.CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption.GenerateUniqueName)
Dim videoFile = Await _captureFolder.CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption.GenerateUniqueName)
' Calculate rotation angle, taking mirroring into account if necessary
Dim rotationAngle = 360 - ConvertDeviceOrientationToDegrees(GetCameraOrientation())
_encodingProfile.Video.Properties(RotationKey) = PropertyValue.CreateInt32(rotationAngle)
Debug.WriteLine("Starting recording...")
Debug.WriteLine("Starting recording to " & videoFile.Path)
Await _mediaCapture.StartRecordToStorageFileAsync(_encodingProfile, videoFile)
_isRecording = True
Debug.WriteLine("Started recording to: " & videoFile.Path)
Debug.WriteLine("Started recording!")
Catch ex As Exception
Debug.WriteLine("Exception when starting video recording: {0}", ex.ToString())
Debug.WriteLine("Exception when starting video recording: " & ex.ToString())
End Try
End Function
@ -454,6 +457,10 @@ Namespace Global.CameraVideoStabilization
End If
RegisterEventHandlers()
Dim picturesLibrary = Await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures)
' Fall back to the local app storage if the Pictures Library is not available
_captureFolder = If(picturesLibrary.SaveFolder, ApplicationData.Current.LocalFolder)
End Function
''' <summary>

Просмотреть файл

@ -53,14 +53,15 @@ void MainPage::NotifyUserFileNotExist()
NotifyUser("The file '" + Filename + "' does not exist. Use scenario one to create this file.", NotifyType::ErrorMessage);
}
void MainPage::HandleFileNotFoundException(Platform::COMException^ e)
// I/O errors are reported as exceptions.
void MainPage::HandleIoException(Platform::COMException^ e, Platform::String^ description)
{
if (e->HResult == 0x80070002) // Catch FileNotExistException
if (e->HResult == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
{
NotifyUserFileNotExist();
}
else
{
throw e;
NotifyUser(description + ": " + e->Message, NotifyType::ErrorMessage);
}
}

Просмотреть файл

@ -74,7 +74,7 @@ namespace SDKTemplate
void Initialize();
void ValidateFile();
void NotifyUserFileNotExist();
void HandleFileNotFoundException(Platform::COMException^ e);
void HandleIoException(Platform::COMException^ e, Platform::String^ description);
private:
static Platform::Array<Scenario>^ scenariosInner;

Просмотреть файл

@ -44,7 +44,7 @@ void Scenario10::DeleteFileButton_Click(Object^ sender, RoutedEventArgs^ e)
}
catch (COMException^ ex)
{
rootPage->HandleFileNotFoundException(ex);
rootPage->HandleIoException(ex, "Error deleting file '" + fileName + "'");
}
});
}

Просмотреть файл

@ -15,6 +15,7 @@
using namespace SDKTemplate;
using namespace concurrency;
using namespace Platform;
using namespace Windows::Storage;
using namespace Windows::UI::Xaml;
@ -28,11 +29,19 @@ Scenario1::Scenario1() : rootPage(MainPage::Current)
void Scenario1::CreateFileButton_Click(Object^ sender, RoutedEventArgs^ e)
{
create_task(KnownFolders::GetFolderForUserAsync(nullptr /* current user */, KnownFolderId::PicturesLibrary)).then([this](StorageFolder^ picturesFolder)
{
return picturesFolder->CreateFileAsync(rootPage->Filename, CreationCollisionOption::ReplaceExisting);
}).then([this](StorageFile^ file)
}).then([this](task<StorageFile^> task)
{
rootPage->SampleFile = file;
rootPage->NotifyUser("The file '" + file->Name + "' was created.", NotifyType::StatusMessage);
try
{
StorageFile^ file = task.get();
rootPage->SampleFile = file;
rootPage->NotifyUser("The file '" + file->Name + "' was created.", NotifyType::StatusMessage);
}
catch (Exception^ e)
{
// I/O errors are reported as exceptions.
rootPage->NotifyUser("Error creating file '" + MainPage::Filename + "': " + e->Message, NotifyType::ErrorMessage);
}
});
}

Просмотреть файл

@ -45,7 +45,7 @@ void Scenario3::WriteTextButton_Click(Object^ sender, RoutedEventArgs^ e)
}
catch (COMException^ ex)
{
rootPage->HandleFileNotFoundException(ex);
rootPage->HandleIoException(ex, "Error writing to '" + file->Name + "'");
}
});
}
@ -74,7 +74,7 @@ void Scenario3::ReadTextButton_Click(Object^ sender, RoutedEventArgs^ e)
}
catch(COMException^ ex)
{
rootPage->HandleFileNotFoundException(ex);
rootPage->HandleIoException(ex, "Error reading from '" + file->Name + "'");
}
});
}

Просмотреть файл

@ -56,7 +56,7 @@ void Scenario4::WriteBytesButton_Click(Object^ sender, RoutedEventArgs^ e)
}
catch (COMException^ ex)
{
rootPage->HandleFileNotFoundException(ex);
rootPage->HandleIoException(ex, "Error writing to '" + file->Name + "'");
}
});
}
@ -88,7 +88,7 @@ void Scenario4::ReadBytesButton_Click(Object^ sender, RoutedEventArgs^ e)
}
catch (COMException^ ex)
{
rootPage->HandleFileNotFoundException(ex);
rootPage->HandleIoException(ex, "Error reading from '" + file->Name + "'");
}
});
}

Просмотреть файл

@ -57,7 +57,7 @@ void Scenario5::WriteToStreamButton_Click(Object^ sender, RoutedEventArgs^ e)
}
catch (COMException^ ex)
{
rootPage->HandleFileNotFoundException(ex);
rootPage->HandleIoException(ex, "Error writing to '" + file->Name + "'");
}
});
}
@ -101,7 +101,7 @@ void Scenario5::ReadFromStreamButton_Click(Object^ sender, RoutedEventArgs^ e)
}
catch (COMException^ ex)
{
rootPage->HandleFileNotFoundException(ex);
rootPage->HandleIoException(ex, "Error reading from '" + file->Name + "'");
}
});
}

Просмотреть файл

@ -47,22 +47,13 @@ void Scenario6::ShowPropertiesButton_Click(Object^ sender, RoutedEventArgs^ e)
*outputText += "\nFile type: " + file->FileType;
// Get basic properties
create_task(file->GetBasicPropertiesAsync()).then([this, outputText](task<BasicProperties^> task)
create_task(file->GetBasicPropertiesAsync()).then([this, file, outputText](BasicProperties^ basicProperties)
{
try
{
BasicProperties^ basicProperties = task.get();
*outputText += "\nFile size: " + basicProperties->Size.ToString() + " bytes";
*outputText += "\nFile size: " + basicProperties->Size.ToString() + " bytes";
String^ dateModifiedString = dateFormat->Format(basicProperties->DateModified) + " " + timeFormat->Format(basicProperties->DateModified);
*outputText += "\nDate modified: " + dateModifiedString;
String^ dateModifiedString = dateFormat->Format(basicProperties->DateModified) + " " + timeFormat->Format(basicProperties->DateModified);
*outputText += "\nDate modified: " + dateModifiedString;
}
catch (COMException^ ex)
{
rootPage->HandleFileNotFoundException(ex);
}
}).then([this, file]()
{
// Get extra properties
auto propertiesName = ref new Vector<String^>();
propertiesName->Append(dateAccessedProperty);
@ -83,6 +74,16 @@ void Scenario6::ShowPropertiesButton_Click(Object^ sender, RoutedEventArgs^ e)
}
rootPage->NotifyUser(*outputText, NotifyType::StatusMessage);
}).then([this, file](task<void> task)
{
try
{
task.get();
}
catch (COMException^ ex)
{
rootPage->HandleIoException(ex, "Error retrieving properties for '" + file->Name + "'");
}
});
}
else

Просмотреть файл

@ -42,11 +42,26 @@ void Scenario7::AddToListButton_Click(Object^ sender, RoutedEventArgs^ e)
rootPage->MruToken = StorageApplicationPermissions::MostRecentlyUsedList->Add(file, file->Name, visibility);
rootPage->NotifyUser("The file '" + file->Name + "' was added to the MRU list and a token was stored.", NotifyType::StatusMessage);
}
else if (FALRadioButton->IsChecked->Value)
else
{
// Add the file to the MRU
rootPage->FalToken = StorageApplicationPermissions::FutureAccessList->Add(file, file->Name);
rootPage->NotifyUser("The file '" + file->Name + "' was added to the FAL list and a token was stored.", NotifyType::StatusMessage);
// Add the file to the FAL
try
{
rootPage->FalToken = StorageApplicationPermissions::FutureAccessList->Add(file, file->Name);
rootPage->NotifyUser("The file '" + file->Name + "' was added to the FAL list and a token was stored.", NotifyType::StatusMessage);
}
catch (COMException^ ex)
{
if (ex->HResult == FA_E_MAX_PERSISTED_ITEMS_REACHED)
{
// A real program would call Remove() to create room in the FAL.
rootPage->NotifyUser("The file '" + file->Name + "' was not added to the FAL list because the FAL list is full.", NotifyType::ErrorMessage);
}
else
{
throw;
}
}
}
}
else
@ -57,115 +72,94 @@ void Scenario7::AddToListButton_Click(Object^ sender, RoutedEventArgs^ e)
void Scenario7::ShowListButton_Click(Object^ sender, RoutedEventArgs^ e)
{
StorageFile^ file = rootPage->SampleFile;
if (file != nullptr)
AccessListEntryView^ entries = nullptr;
String^ listName;
if (MRURadioButton->IsChecked->Value)
{
String^ outputText;
NotifyType statusOrError = NotifyType::StatusMessage;
if (MRURadioButton->IsChecked->Value)
{
AccessListEntryView^ entries = StorageApplicationPermissions::MostRecentlyUsedList->Entries;
if (entries->Size > 0)
{
outputText = "The MRU list contains the following item(s):";
std::for_each(begin(entries), end(entries), [this, &outputText](const AccessListEntry& entry)
{
outputText += "\n" + entry.Metadata; // Application previously chose to store sampleFile->Name in this field
});
}
else
{
outputText = "The MRU list is empty, please select 'Most Recently Used' list and click 'Add to List' to add a file to the MRU list.";
statusOrError = NotifyType::ErrorMessage;
}
}
else if (FALRadioButton->IsChecked->Value)
{
AccessListEntryView^ entries = StorageApplicationPermissions::FutureAccessList->Entries;
if (entries->Size > 0)
{
outputText = "The FAL list contains the following item(s):";
std::for_each(begin(entries), end(entries), [this, &outputText](const AccessListEntry& entry)
{
outputText += "\n" + entry.Metadata; // Application previously chose to store sampleFile->Name in this field
});
}
else
{
outputText = "The FAL list is empty, please select 'Future Access List' list and click 'Add to List' to add a file to the FAL list.";
statusOrError = NotifyType::ErrorMessage;
}
}
rootPage->NotifyUser(outputText, statusOrError);
listName = "MRU";
entries = StorageApplicationPermissions::MostRecentlyUsedList->Entries;
}
else
{
rootPage->NotifyUserFileNotExist();
listName = "FAL";
entries = StorageApplicationPermissions::FutureAccessList->Entries;
}
if (entries->Size > 0)
{
String^ outputText = "The " + listName + " + list contains the following item(s):";
for (const AccessListEntry& entry : entries)
{
outputText += "\n" + entry.Metadata; // Application previously chose to store sampleFile->Name in this field
}
rootPage->NotifyUser(outputText, NotifyType::StatusMessage);
}
else
{
rootPage->NotifyUser("The " + listName + " list is empty.", NotifyType::ErrorMessage);
}
}
void Scenario7::OpenFromListButton_Click(Object^ sender, RoutedEventArgs^ e)
{
StorageFile^ file = rootPage->SampleFile;
if (file != nullptr)
task<StorageFile^> fileTask = task_from_result<StorageFile^>(nullptr);
if (MRURadioButton->IsChecked->Value)
{
if (MRURadioButton->IsChecked->Value)
if (rootPage->MruToken != nullptr)
{
if (rootPage->MruToken != nullptr)
// Open the file via the token that was stored when adding this file into the MRU list
fileTask = create_task(StorageApplicationPermissions::MostRecentlyUsedList->GetFileAsync(rootPage->MruToken)).then([this](task<StorageFile^> task)
{
// Open the file via the token that was stored when adding this file into the MRU list
create_task(StorageApplicationPermissions::MostRecentlyUsedList->GetFileAsync(rootPage->MruToken)).then([this](task<StorageFile^> task)
StorageFile^ file = nullptr;
try
{
try
{
StorageFile^ file = task.get();
// Read the file
create_task(FileIO::ReadTextAsync(file)).then([this, file](String^ fileContent)
{
rootPage->NotifyUser("The file '" + file->Name + "' was opened by a stored token from the MRU list, it contains the following text:\n" + fileContent, NotifyType::StatusMessage);
});
}
catch (COMException^ ex)
{
rootPage->HandleFileNotFoundException(ex);
}
});
}
else
{
rootPage->NotifyUser("The MRU list is empty, please select 'Most Recently Used' list and click 'Add to List' to add a file to the MRU list.", NotifyType::ErrorMessage);
}
file = task.get();
}
catch (InvalidArgumentException^)
{
// When the MRU becomes full, older entries are automatically deleted.
rootPage->NotifyUser("The token is no longer valid.", NotifyType::ErrorMessage);
}
return file;
});
}
else if (FALRadioButton->IsChecked->Value)
else
{
if (rootPage->FalToken != nullptr)
{
// Open the file via the token that was stored when adding this file into the FAL list
create_task(StorageApplicationPermissions::FutureAccessList->GetFileAsync(rootPage->FalToken)).then([this](task<StorageFile^> task)
{
try
{
StorageFile^ file = task.get();
// Read the file
create_task(FileIO::ReadTextAsync(file)).then([this, file](String^ fileContent)
{
rootPage->NotifyUser("The file '" + file->Name + "' was opened by a stored token from the FAL list, it contains the following text:\n" + fileContent, NotifyType::StatusMessage);
});
}
catch (COMException^ ex)
{
rootPage->HandleFileNotFoundException(ex);
}
});
}
else
{
rootPage->NotifyUser("The FAL list is empty, please select 'Future Access List' list and click 'Add to List' to add a file to the FAL list.", NotifyType::ErrorMessage);
}
rootPage->NotifyUser("This operation requires a token. Add file to the MRU list first.", NotifyType::ErrorMessage);
}
}
else
{
rootPage->NotifyUserFileNotExist();
if (rootPage->FalToken != nullptr)
{
// Open the file via the token that was stored when adding this file into the FAL list
fileTask = create_task(StorageApplicationPermissions::FutureAccessList->GetFileAsync(rootPage->FalToken));
}
else
{
rootPage->NotifyUser("This operation requires a token. Add file to the FAL list first.", NotifyType::ErrorMessage);
}
}
fileTask.then([this](StorageFile^ file)
{
if (file != nullptr)
{
create_task(FileIO::ReadTextAsync(file)).then([this, file](task<String^> task)
{
try
{
String^ fileContent = task.get();
rootPage->NotifyUser("The file '" + file->Name + "' was opened by a stored token. It contains the following text:\n" + fileContent, NotifyType::StatusMessage);
}
catch (COMException^ ex)
{
// I/O errors are reported as exceptions.
rootPage->HandleIoException(ex, "Error reading file opened from list");
}
});
}
});
}

Просмотреть файл

@ -45,7 +45,7 @@ void Scenario8::CopyFileButton_Click(Object^ sender, RoutedEventArgs^ e)
}
catch (COMException^ ex)
{
rootPage->HandleFileNotFoundException(ex);
rootPage->HandleIoException(ex, "Error copying file '" + file->Name + "'");
}
});
}

Просмотреть файл

@ -54,7 +54,7 @@ void Scenario9::CompareFilesButton_Click(Object^ sender, RoutedEventArgs^ e)
}
catch (COMException^ ex)
{
rootPage->HandleFileNotFoundException(ex);
rootPage->HandleIoException(ex, "Error determining whether two files are the same");
}
}
else

Просмотреть файл

@ -53,6 +53,11 @@ namespace SDKTemplate
{
rootPage.NotifyUserFileNotExist();
}
catch (Exception ex)
{
// I/O errors are reported as exceptions.
rootPage.NotifyUser(String.Format("Error deleting file '{0}': {1}", file.Name, ex.Message), NotifyType.ErrorMessage);
}
}
else
{

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше