Skip to content

Commit

Permalink
Takes photo after countdown and when user presses space key.
Browse files Browse the repository at this point in the history
  • Loading branch information
andijakl committed Aug 20, 2016
1 parent f7b10f8 commit 61ba6d1
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 24 deletions.
2 changes: 1 addition & 1 deletion KissMachineKinect/KissMachineKinect.Windows/MainPage.xaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Page
<Page x:Name="RootPage"
x:Class="KissMachineKinect.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Expand Down
130 changes: 107 additions & 23 deletions KissMachineKinect/KissMachineKinect.Windows/MainPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
using System.Windows.Input;
using Windows.ApplicationModel.Resources;
using Windows.Foundation;
using Windows.Graphics.Imaging;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.System;
using Windows.UI;
using Windows.UI.Core;
using Windows.UI.Popups;
Expand All @@ -32,6 +36,21 @@ namespace KissMachineKinect
/// </summary>
public sealed partial class MainPage : Page, INotifyPropertyChanged
{
// Screenshots
private const FileFormat DefaultPhotoFileFormat = FileFormat.Png;
private const string DefaultPhotoFileName = "kiss_{0:yyyy-MM-dd_HH-mm-ss}";
private readonly StorageFolder _defaultPhotoFolder = KnownFolders.PicturesLibrary;
private const string DefaultPhotoSubFolder = "Wedding";

private enum FileFormat
{
Jpeg,
Png,
Bmp,
Tiff,
Gif
}

// Kinect
private KinectSensor _sensor;
private CoordinateMapper _coordinateMapper;
Expand Down Expand Up @@ -104,8 +123,10 @@ public MainPage()
{
InitializeComponent();
Loaded += MainPage_Loaded;
Window.Current.CoreWindow.KeyUp += CoreWindow_KeyUp;
}


#region Init

private void MainPage_Loaded(object sender, RoutedEventArgs e)
Expand Down Expand Up @@ -229,6 +250,8 @@ private void InitKinect()
_displayWidth = frameDescription.Width;
_displayHeight = frameDescription.Height;

ColorImg.Source = _bitmap;


// ----------------------------------------------------------------------------------
// Body frames
Expand Down Expand Up @@ -302,11 +325,13 @@ private void Reader_ColorFrameArrived(ColorFrameReader sender, ColorFrameArrived
{
if (colorFrame.RawColorImageFormat == ColorImageFormat.Bgra)
{
colorFrame.CopyRawFrameDataToArray(_colorPixels);
colorFrame.CopyRawFrameDataToBuffer(_bitmap.PixelBuffer);
//colorFrame.CopyRawFrameDataToArray(_colorPixels);
}
else
{
colorFrame.CopyConvertedFrameDataToArray(_colorPixels, ColorImageFormat.Bgra);
//colorFrame.CopyConvertedFrameDataToArray(_colorPixels, ColorImageFormat.Bgra);
colorFrame.CopyConvertedFrameDataToBuffer(_bitmap.PixelBuffer, ColorImageFormat.Bgra);
}

colorFrameProcessed = true;
Expand All @@ -317,10 +342,73 @@ private void Reader_ColorFrameArrived(ColorFrameReader sender, ColorFrameArrived
// we got a frame, render
if (colorFrameProcessed)
{
RenderColorPixels(_colorPixels);
_bitmap.Invalidate();
//RenderColorPixels(_colorPixels);
}
}


private async void CoreWindow_KeyUp(CoreWindow sender, KeyEventArgs args)
{
var key = args.VirtualKey;
if (key == VirtualKey.Space)
{
// Take screenshot when releasing the space key
await WriteableBitmapToStorageFile(_bitmap);
}
}

private async Task<StorageFile> WriteableBitmapToStorageFile(WriteableBitmap wb)
{
var fileName = string.Format(DefaultPhotoFileName, DateTime.Now);
Guid bitmapEncoderGuid;
switch (DefaultPhotoFileFormat)
{
case FileFormat.Jpeg:
fileName += ".jpeg";
bitmapEncoderGuid = BitmapEncoder.JpegEncoderId;
break;

case FileFormat.Png:
fileName += ".png";
bitmapEncoderGuid = BitmapEncoder.PngEncoderId;
break;

case FileFormat.Bmp:
fileName += ".bmp";
bitmapEncoderGuid = BitmapEncoder.BmpEncoderId;
break;

case FileFormat.Tiff:
fileName += ".tiff";
bitmapEncoderGuid = BitmapEncoder.TiffEncoderId;
break;

case FileFormat.Gif:
fileName += ".gif";
bitmapEncoderGuid = BitmapEncoder.GifEncoderId;
break;

default:
throw new ArgumentOutOfRangeException(nameof(DefaultPhotoFileFormat));
}

var targetFolder = await _defaultPhotoFolder.CreateFolderAsync(DefaultPhotoSubFolder, CreationCollisionOption.OpenIfExists);
var file = await targetFolder.CreateFileAsync(fileName, CreationCollisionOption.GenerateUniqueName);
using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateAsync(bitmapEncoderGuid, stream);
var pixelStream = wb.PixelBuffer.AsStream();
var pixels = new byte[pixelStream.Length];
await pixelStream.ReadAsync(pixels, 0, pixels.Length);

encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint) wb.PixelWidth, (uint) wb.PixelHeight, 96.0, 96.0, pixels);
await encoder.FlushAsync();
}
return file;
}


/// <summary>
/// Renders color pixels into the writeableBitmap.
/// </summary>
Expand All @@ -332,9 +420,11 @@ private void RenderColorPixels(byte[] pixels)
_bitmap.Invalidate();
ColorImg.Source = _bitmap;
}

#endregion

#region Player Management

private void CreateNewPlayer(ulong trackingId, int bodyNum)
{
Debug.WriteLine("Create player: " + bodyNum + " / id: " + trackingId);
Expand Down Expand Up @@ -366,8 +456,8 @@ private bool IsPlayerTracked(ulong trackingId)
{
return _players.Any(curPlayer => curPlayer.TrackingId == trackingId);
}
#endregion

#endregion

/// <summary>
/// Handles the body frame data arriving from the sensor
Expand Down Expand Up @@ -412,10 +502,7 @@ private void Reader_BodyFrameArrived(BodyFrameReader sender, BodyFrameArrivedEve
if (minPair.DistanceInM < 4.0f)
{
// Draw line between heads
_minPlayerLine.SetPosition(minPair.Player1Pos.X,
minPair.Player1Pos.Y,
minPair.Player2Pos.X,
minPair.Player2Pos.Y);
_minPlayerLine.SetPosition(minPair.Player1Pos.X, minPair.Player1Pos.Y, minPair.Player2Pos.X, minPair.Player2Pos.Y);
_minPlayerLine.SetVisibility(true);
}
else
Expand All @@ -440,22 +527,22 @@ private void Reader_BodyFrameArrived(BodyFrameReader sender, BodyFrameArrivedEve
SetCountdown(99);
}
}

}


private KissPositionModel CheckPlayersCloseBy()
{
// TODO Simulation only
#if DEBUG
if (_players.Count < 1) return null;
if (_players.Count == 1)
{
_players.Add(new PlayerInfo(_drawingCanvas, 1, -1)
{
FacePosInCamera = new CameraSpacePoint { X = -0.0366f, Y = -0.0486f, Z = 1.164f },
FacePosInColor = new ColorSpacePoint { X = 972f, Y = 599f }
FacePosInCamera = new CameraSpacePoint {X = -0.0366f, Y = -0.0486f, Z = 1.164f}, FacePosInColor = new ColorSpacePoint {X = 972f, Y = 599f}
});
}
#endif

// Real code
if (_players.Count < 2) return null;
Expand Down Expand Up @@ -512,23 +599,22 @@ private void UpdatePlayer(Body curBody)
private void StartKissPhotoTimer()
{
if (_photoCountdownTimer != null || _photoTaken) return;
PhotoCountDown = 5;
_photoCountdownTimer = new Timer(PhotoTimerCallback, null, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(2));
PhotoCountDown = 4;
_photoCountdownTimer = new Timer(PhotoTimerCallback, null, TimeSpan.FromSeconds(1.5), TimeSpan.FromSeconds(1.5));
}

private void PhotoTimerCallback(object state)
private async void PhotoTimerCallback(object state)
{
if (PhotoCountDown == 0)
{
// TODO Take picture
await WriteableBitmapToStorageFile(_bitmap);
StopKissPhotoTimer();
_photoTaken = true;
}
if (PhotoCountDown > 0)
{
SetCountdown(PhotoCountDown - 1);
}

}

private void StopKissPhotoTimer()
Expand All @@ -544,18 +630,18 @@ private void SetCountdown(int newValue)
if (PhotoCountDown == newValue) return;
// Speak the text
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
_dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
_dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
PhotoCountDown = newValue;
// Convert countdown value to text
var textConverter = new CountdownIntToStringConverter();
var speakText = (string)textConverter.Convert(PhotoCountDown, typeof(string), null, Windows.Globalization.Language.CurrentInputMethodLanguageTag);
var speakText = (string) textConverter.Convert(PhotoCountDown, typeof(string), null, Windows.Globalization.Language.CurrentInputMethodLanguageTag);
await _speechService.SpeakTextAsync(speakText);
});
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
}
#endregion

#endregion

/// <summary>
/// Shows a message box containing a specified message and a specified title.
Expand All @@ -578,10 +664,8 @@ public async Task<bool> ShowOkCancelQueryAsync(string message, string title)
{
bool? result = null;
var dlg = new MessageDialog(message, title);
dlg.Commands.Add(
new UICommand("OK", cmd => result = true));
dlg.Commands.Add(
new UICommand("Cancel", cmd => result = false));
dlg.Commands.Add(new UICommand("OK", cmd => result = true));
dlg.Commands.Add(new UICommand("Cancel", cmd => result = false));
dlg.DefaultCommandIndex = 0;
dlg.CancelCommandIndex = 1;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
</Applications>
<Capabilities>
<Capability Name="internetClient" />
<Capability Name="picturesLibrary" />
<DeviceCapability Name="webcam" />
<DeviceCapability Name="microphone" />
</Capabilities>
Expand Down

0 comments on commit 61ba6d1

Please sign in to comment.