0

This is the code from the SlideshowGestures-WPF sample that can be used to recognize swipe gestures. I've used Fizbin's (http://www.exceptontuesdays.com/gestures-with-microsoft-kinect-for-windows-sdk-v1-5/) library to add the zooming gestures in this code. The gesture is identified correctly and the code goes into the 'if' loop in the function 'OnGestureRecognised'. What I want to do is, once that is done I want to zoom in on the image. I tried using the solution here: https://stackoverflow.com/a/927134/1473556 by Kelly. But the problem is, RenderTransform does not work with objects of BitmapImage class. So how do I go about it?

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
    /// <summary>
    /// The recognizer being used.
    /// </summary>
    private readonly Recognizer activeRecognizer;

    // skeleton gesture recognizer
    private GestureController gestureController;

    /// <summary>
    /// The paths of the picture files.
    /// </summary>
    private readonly string[] picturePaths = CreatePicturePaths();

    /// <summary>
    /// Array of arrays of contiguous line segements that represent a skeleton.
    /// </summary>
    private static readonly JointType[][] SkeletonSegmentRuns = new JointType[][]
    {
        new JointType[] 
        { 
            JointType.Head, JointType.ShoulderCenter, JointType.HipCenter 
        },
        new JointType[] 
        { 
            JointType.HandLeft, JointType.WristLeft, JointType.ElbowLeft, JointType.ShoulderLeft,
            JointType.ShoulderCenter,
            JointType.ShoulderRight, JointType.ElbowRight, JointType.WristRight, JointType.HandRight
        },
        new JointType[]
        {
            JointType.FootLeft, JointType.AnkleLeft, JointType.KneeLeft, JointType.HipLeft,
            JointType.HipCenter,
            JointType.HipRight, JointType.KneeRight, JointType.AnkleRight, JointType.FootRight
        }
    };

    /// <summary>
    /// The sensor we're currently tracking.
    /// </summary>
    private KinectSensor nui;

    /// <summary>
    /// There is currently no connected sensor.
    /// </summary>
    private bool isDisconnectedField = true;

    /// <summary>
    /// Any message associated with a failure to connect.
    /// </summary>
    private string disconnectedReasonField;

    /// <summary>
    /// Array to receive skeletons from sensor, resize when needed.
    /// </summary>
    private Skeleton[] skeletons = new Skeleton[0];

    /// <summary>
    /// Time until skeleton ceases to be highlighted.
    /// </summary>
    private DateTime highlightTime = DateTime.MinValue;

    /// <summary>
    /// The ID of the skeleton to highlight.
    /// </summary>
    private int highlightId = -1;

    /// <summary>
    /// The ID of the skeleton to be tracked.
    /// </summary>
    private int nearestId = -1;

    /// <summary>
    /// The index of the current image.
    /// </summary>
    private int indexField = 1;

    /// <summary>
    /// Initializes a new instance of the <see cref="MainWindow" /> class.
    /// </summary>
    public MainWindow()
    {
        this.PreviousPicture = this.LoadPicture(this.Index - 1);
        this.Picture = this.LoadPicture(this.Index);
        this.NextPicture = this.LoadPicture(this.Index + 1);

        InitializeComponent();

        // initialize the gesture recognizer
        gestureController = new GestureController();
        gestureController.GestureRecognized += OnGestureRecognized;

        // Create the gesture recognizer.
        this.activeRecognizer = this.CreateRecognizer();

        // Wire-up window loaded event.
        Loaded += this.OnMainWindowLoaded;
    }

    /// <summary>
    /// Event implementing INotifyPropertyChanged interface.
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// Gets a value indicating whether no Kinect is currently connected.
    /// </summary>
    public bool IsDisconnected
    {
        get
        {
            return this.isDisconnectedField;
        }

        private set
        {
            if (this.isDisconnectedField != value)
            {
                this.isDisconnectedField = value;

                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs("IsDisconnected"));
                }
            }
        }
    }


    /// <summary>
    /// Gets any message associated with a failure to connect.
    /// </summary>
    public string DisconnectedReason
    {
        get
        {
            return this.disconnectedReasonField;
        }

        private set
        {
            if (this.disconnectedReasonField != value)
            {
                this.disconnectedReasonField = value;

                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs("DisconnectedReason"));
                }
            }
        }
    }

    /// <summary>
    /// Gets or sets the index number of the image to be shown.
    /// </summary>
    public int Index
    {
        get
        {
            return this.indexField;
        }

        set
        {
            if (this.indexField != value)
            {
                this.indexField = value;

                // Notify world of change to Index and Picture.
                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs("Index"));
                }
            }
        }
    }

    /// <summary>
    /// Gets the previous image displayed.
    /// </summary>
    public BitmapImage PreviousPicture { get; private set; }

    /// <summary>
    /// Gets the current image to be displayed.
    /// </summary>
    public BitmapImage Picture { get; private set; }

    /// <summary>
    /// Gets the next image displayed.
    /// </summary>
    public BitmapImage NextPicture { get; private set; }

    /// <summary>
    /// Get list of files to display as pictures.
    /// </summary>
    /// <returns>Paths to pictures.</returns>
    private static string[] CreatePicturePaths()
    {
        var list = new List<string>();
        var commonPicturesPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
        var newPath = commonPicturesPath + "\\Images";
        list.AddRange(Directory.GetFiles(newPath, "*.jpg", SearchOption.AllDirectories));
        if (list.Count == 0)
        {
            list.AddRange(Directory.GetFiles(commonPicturesPath, "*.png", SearchOption.AllDirectories));
        }

        if (list.Count == 0)
        {
            var myPicturesPath = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
            list.AddRange(Directory.GetFiles(myPicturesPath, "*.jpg", SearchOption.AllDirectories));
            if (list.Count == 0)
            {
                list.AddRange(Directory.GetFiles(commonPicturesPath, "*.png", SearchOption.AllDirectories));
            }
        }
        return list.ToArray();
    }

    /// <summary>
    /// Load the picture with the given index.
    /// </summary>
    /// <param name="index">The index to use.</param>
    /// <returns>Corresponding image.</returns>
    private BitmapImage LoadPicture(int index)
    {
        BitmapImage value;

        if (this.picturePaths.Length != 0)
        {
            var actualIndex = index % this.picturePaths.Length;
            if (actualIndex < 0)
            {
                actualIndex += this.picturePaths.Length;
            }

            Debug.Assert(0 <= actualIndex, "Index used will be non-negative");
            Debug.Assert(actualIndex < this.picturePaths.Length, "Index is within bounds of path array");

            try
            {
                value = new BitmapImage(new Uri(this.picturePaths[actualIndex]));

            }
            catch (NotSupportedException)
            {
                value = null;
            }
        }
        else
        {
            value = null;
        }

        return value;
    }

    /// <summary>
    /// Create a wired-up recognizer for running the slideshow.
    /// </summary>
    /// <returns>The wired-up recognizer.</returns>
    private Recognizer CreateRecognizer()
    {
        // Instantiate a recognizer.
        var recognizer = new Recognizer();

        // Wire-up swipe right to manually advance picture.
        recognizer.SwipeRightDetected += (s, e) =>
        {
            if (e.Skeleton.TrackingId == nearestId)
            {
                Index++;
                Debug.WriteLine("Swiperight. Your gesture is recognised. Congratulations");
                // Setup corresponding picture if pictures are available.
                this.PreviousPicture = this.Picture;
                this.Picture = this.NextPicture;
                this.NextPicture = LoadPicture(Index + 1);

                // Notify world of change to Index and Picture.
                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs("PreviousPicture"));
                    this.PropertyChanged(this, new PropertyChangedEventArgs("Picture"));
                    this.PropertyChanged(this, new PropertyChangedEventArgs("NextPicture"));
                }

                var storyboard = Resources["LeftAnimate"] as Storyboard;
                if (storyboard != null)
                {
                    storyboard.Begin();
                }

                HighlightSkeleton(e.Skeleton);
            }
        };

        // Wire-up swipe left to manually reverse picture.
        recognizer.SwipeLeftDetected += (s, e) =>
        {
            if (e.Skeleton.TrackingId == nearestId)
            {
                Index--;
                Debug.WriteLine("Swipeleft. Your gesture is recognised. Congratulations");
                // Setup corresponding picture if pictures are available.
                this.NextPicture = this.Picture;
                this.Picture = this.PreviousPicture;
                this.PreviousPicture = LoadPicture(Index - 1);

                // Notify world of change to Index and Picture.
                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs("PreviousPicture"));
                    this.PropertyChanged(this, new PropertyChangedEventArgs("Picture"));
                    this.PropertyChanged(this, new PropertyChangedEventArgs("NextPicture"));
                }

                var storyboard = Resources["RightAnimate"] as Storyboard;
                if (storyboard != null)
                {
                    storyboard.Begin();
                }

                HighlightSkeleton(e.Skeleton);
            }
        };

        return recognizer;
    }






    /// <summary>
    ///
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e">Gesture event arguments.</param>
    private void OnGestureRecognized(object sender, GestureEventArgs e)
    {
        Debug.WriteLine(e.GestureType);

        if (e.GestureType == GestureType.ZoomIn)
        {
            Debug.WriteLine(" line has been Detected.");
           // window.Close();
        }

        /*switch (e.GestureType)
        {
            case GestureType.Menu:
                Gesture = "Menu";
                break;
            case GestureType.WaveRight:
                Gesture = "Wave Right";
                break;
            case GestureType.WaveLeft:
                Gesture = "Wave Left";
                break;
            case GestureType.JoinedHands:
                Gesture = "Joined Hands";
                break;
            case GestureType.SwipeLeft:
                Gesture = "Swipe Left";
                break;
            case GestureType.SwipeRight:
                Gesture = "Swipe Right";
                break;
            case GestureType.ZoomIn:
                Gesture = "Zoom In";
                break;
            case GestureType.ZoomOut:
                Gesture = "Zoom Out";
                break;

            default:
                break;
        }*/
    }













    /// <summary>
    /// Handle insertion of Kinect sensor.
    /// </summary>
    private void InitializeNui()
    {
        this.UninitializeNui();

        var index = 0;
        while (this.nui == null && index < KinectSensor.KinectSensors.Count)
        {
            try
            {
                this.nui = KinectSensor.KinectSensors[index];

                this.nui.Start();

                this.IsDisconnected = false;

                this.DisconnectedReason = null;
            }
            catch (IOException ex)
            {
                this.nui = null;

                this.DisconnectedReason = ex.Message;
            }
            catch (InvalidOperationException ex)
            {
                this.nui = null;

                this.DisconnectedReason = ex.Message;
            }

            index++;
        }

        if (this.nui != null)
        {
            this.nui.SkeletonStream.Enable();

            this.nui.SkeletonFrameReady += this.OnSkeletonFrameReady;
        }
    }

    /// <summary>
    /// Handle removal of Kinect sensor.
    /// </summary>
    private void UninitializeNui()
    {
        if (this.nui != null)
        {
            this.nui.SkeletonFrameReady -= this.OnSkeletonFrameReady;

            this.nui.Stop();

            this.nui = null;
        }

        this.IsDisconnected = true;

        this.DisconnectedReason = null;
    }

    /// <summary>
    /// Window loaded actions to initialize Kinect handling.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The event args.</param>
    private void OnMainWindowLoaded(object sender, RoutedEventArgs e)
    {
        // Start the Kinect system, this will cause StatusChanged events to be queued.
        this.InitializeNui();

        // Handle StatusChange events to pick the first sensor that connects.
        KinectSensor.KinectSensors.StatusChanged += (s, ee) =>
        {
            switch (ee.Status)
            {
                case KinectStatus.Connected:
                    if (nui == null)
                    {
                        Debug.WriteLine("New Kinect connected");

                        InitializeNui();
                    }
                   else
                    {
                        Debug.WriteLine("Existing Kinect signalled connection");
                    }

                    break;
                default:
                    if (ee.Sensor == nui)
                    {
                        Debug.WriteLine("Existing Kinect disconnected");

                        UninitializeNui();
                    }
                    else
                    {
                        Debug.WriteLine("Other Kinect event occurred");
                    }

                    break;
            }
        };
    }

    /// <summary>
    /// Handler for skeleton ready handler.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The event args.</param>
    private void OnSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
    {

        using (SkeletonFrame frame = e.OpenSkeletonFrame())
        {
            if (frame == null)
                return;

            // resize the skeletons array if needed
            if (skeletons.Length != frame.SkeletonArrayLength)
                skeletons = new Skeleton[frame.SkeletonArrayLength];

            // get the skeleton data
            frame.CopySkeletonDataTo(skeletons);

            foreach (var skeleton in skeletons)
            {
                // skip the skeleton if it is not being tracked
                if (skeleton.TrackingState != SkeletonTrackingState.Tracked)
                    continue;

                // update the gesture controller
                gestureController.UpdateAllGestures(skeleton);
            }
        }

        // Get the frame.
        using (var frame = e.OpenSkeletonFrame())
        {
            // Ensure we have a frame.
            if (frame != null)
            {
                // Resize the skeletons array if a new size (normally only on first call).
                if (this.skeletons.Length != frame.SkeletonArrayLength)
                {
                    this.skeletons = new Skeleton[frame.SkeletonArrayLength];
                }

                // Get the skeletons.
                frame.CopySkeletonDataTo(this.skeletons);

                // Assume no nearest skeleton and that the nearest skeleton is a long way away.
                var newNearestId = -1;
                var nearestDistance2 = double.MaxValue;

                // Look through the skeletons.
                foreach (var skeleton in this.skeletons)
                {
                    // Only consider tracked skeletons.
                    if (skeleton.TrackingState == SkeletonTrackingState.Tracked)
                    {
                        // Find the distance squared.
                        var distance2 = (skeleton.Position.X * skeleton.Position.X) +
                            (skeleton.Position.Y * skeleton.Position.Y) +
                            (skeleton.Position.Z * skeleton.Position.Z);

                        // Is the new distance squared closer than the nearest so far?
                        if (distance2 < nearestDistance2)
                        {
                            // Use the new values.
                            newNearestId = skeleton.TrackingId;
                            nearestDistance2 = distance2;
                        }
                    }
                }

                if (this.nearestId != newNearestId)
                {
                    this.nearestId = newNearestId;
                }

                // Pass skeletons to recognizer.
                this.activeRecognizer.Recognize(sender, frame, this.skeletons);

                this.DrawStickMen(this.skeletons);
            }
        }
    }

}
}

The XAML code is pasted here:

    <Window x:Name="window" x:Class="Microsoft.Samples.Kinect.Slideshow.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="V'Me v1.0" Height="800" Width="1280" WindowState="Maximized" Background= "#FFD1D6D0">
<Window.Resources>
    <SolidColorBrush x:Key="MediumGreyBrush" Color="#ff6e6e6e"/>
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
    <Storyboard x:Key="LeftAnimate">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="previous">
            <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
            <EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="1"/>
            <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0"/>
        </DoubleAnimationUsingKeyFrames>
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="next">
            <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
        </DoubleAnimationUsingKeyFrames>
        <ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="current">
            <EasingThicknessKeyFrame KeyTime="0" Value="2000,0,-2000,0"/>
            <EasingThicknessKeyFrame KeyTime="0:0:0.5" Value="0"/>
        </ThicknessAnimationUsingKeyFrames>
    </Storyboard>
    <Storyboard x:Key="RightAnimate">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="previous">
            <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
        </DoubleAnimationUsingKeyFrames>
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="next">
            <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
            <EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="1"/>
            <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0"/>
        </DoubleAnimationUsingKeyFrames>
        <ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="current">
            <EasingThicknessKeyFrame KeyTime="0" Value="-2000,0,2000,0"/>
            <EasingThicknessKeyFrame KeyTime="0:0:0.5" Value="0"/>
        </ThicknessAnimationUsingKeyFrames>
    </Storyboard>
    <Style TargetType="{x:Type Image}">
        <Setter Property="SnapsToDevicePixels" Value="True"/>
    </Style>
</Window.Resources>
<Grid DataContext="{Binding ElementName=window}" Margin="10 0 10 0" Height="732" Width="1249">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="20"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <Canvas x:Name="StickMen" Width="200" Height="150" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
    <DockPanel Margin="0,0,0,15" Height="50"></DockPanel>
    <Grid Margin="0,118,0,61" Name="imgBorder" Grid.RowSpan="4" ClipToBounds="True">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="432*" />
            <ColumnDefinition Width="806*" />
        </Grid.ColumnDefinitions>
        <Image x:Name="next" Source="{Binding NextPicture}" StretchDirection="Both" Stretch="Uniform" ClipToBounds="True"
            SnapsToDevicePixels="True" RenderOptions.BitmapScalingMode="HighQuality" RenderTransformOrigin="0.5,0.5" Opacity="0" Grid.ColumnSpan="2" />
        <Image x:Name="previous" Source="{Binding PreviousPicture}" StretchDirection="Both" Stretch="Uniform" ClipToBounds="True"
            SnapsToDevicePixels="True" RenderOptions.BitmapScalingMode="HighQuality" RenderTransformOrigin="0.5,0.5" Opacity="0" Grid.ColumnSpan="2" />
        <Image x:Name="current" Source="{Binding Picture}" StretchDirection="Both" Stretch="Uniform" ClipToBounds="True"
            SnapsToDevicePixels="True" RenderOptions.BitmapScalingMode="HighQuality" RenderTransformOrigin="0.5,0.5" Grid.ColumnSpan="2" />

    </Grid>
    <StatusBar Grid.Row="3" HorizontalAlignment="Stretch" Name="statusBar2" VerticalAlignment="Bottom" Background="White" Foreground="{StaticResource MediumGreyBrush}" FontWeight="UltraBold">
        <StatusBarItem Padding="0 0 0 30" Background="#FFD1D6D0"></StatusBarItem>
    </StatusBar>
    <StatusBar Grid.Row="3" HorizontalAlignment="Stretch" Name="statusBar" VerticalAlignment="Bottom" Background="White" Foreground="Blue" FontSize="14">
        <StatusBarItem Padding="0 0 0 30" Background="#FFD1D6D0"></StatusBarItem>
    </StatusBar>
    <StatusBar Grid.Row="3" Name="statusBar1" VerticalAlignment="Bottom" Background="White" Foreground="{StaticResource MediumGreyBrush}" FontWeight="UltraBold">
        <StatusBarItem Padding="0 0 0 20" Background="#FFD1D6D0"></StatusBarItem>
    </StatusBar>
    <TextBlock Name="statusBarText1" HorizontalAlignment="Center" Text="© Gade Autonomous Systems Pvt. Ltd." Foreground="Black" FontWeight="Normal" TextAlignment="Center" FontStretch="UltraExpanded" Margin="498,74,437,-11" Grid.Row="3" Height="30" Width="303" FontSize="14" />
    <TextBlock Name="statusBarText" HorizontalAlignment="Center" Text="Swipe your right arm to the left to move to next slide, swipe your left arm to the right for previous." Height="23" Width="707" VerticalAlignment="Center" FontSize="16" FontWeight="Normal" Grid.Row="3" Foreground="Blue" Margin="271,52,271,18" />
    <TextBlock Margin="560,49,564,64" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="#FF000001" FontFamily="Cambria" FontSize="30" Text="V'Me v1.0" FontWeight="Light" Height="37" />
</Grid>

Community
  • 1
  • 1
Karan Thakkar
  • 414
  • 2
  • 9
  • 26
  • Cool, I wrote that gesture library (well, adapted it as I point out in the post)! Glad someone is getting use out of it. I'm pondering the question at hand, but just wanted to give a thumbs up to your gesture library of choice. :) – Nicholas Pappas Oct 01 '12 at 15:38
  • @EvilClosetMonkey your library is helping me a lot ;) I just added the XAML code too. So that you can help me customize your idea. – Karan Thakkar Oct 02 '12 at 07:20
  • Can you trim the MainWindow.xaml.cs to the important bits (no need for the gesture or StickMan stuff) to include the XAML? I normally check in here during work breaks, and I can't access mass storage sites from work (security restriction). – Nicholas Pappas Oct 02 '12 at 15:09
  • With the notion of updating the Image (versus the BitmapImage), have you tinkered with the code you pointed to in your original post (by Kelly)? On a quick glance, it looks like that is what you're wanting to do. I'll look at it more closely and see how they might work together. – Nicholas Pappas Oct 03 '12 at 17:18
  • @EvilClosetMonkey, Everything is working perfectly alright now. I can send you the app incase you are interested to check it out ;) Thanks for the help. – Karan Thakkar Oct 04 '12 at 05:28

2 Answers2

0

BitmapImage is the source data for the Image object in your XAML. I believe you want to perform your transformation on the Image object, otherwise you will have to constantly update the data (which really hasn't changed, you're just looking at it differently).

In your XAML you can apply a transformation that is bound to another property. For example, here is a zoom transformation I do when I move the cursor over a control in one of my Kinect enabled apps:

<ctrl:KinectControl.Resources>
    <Style TargetType="{x:Type ctrl:KinectButton}">
        <Setter Property="BorderBrush" Value="White" />
        <Setter Property="RenderTransformOrigin" Value="0.5, 0.5" />
        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="BorderThickness" Value="2" />
                <Setter Property="RenderTransform">
                    <Setter.Value>
                        <ScaleTransform ScaleX="1.1" ScaleY="1.1" />
                    </Setter.Value>
                </Setter>
            </Trigger>
        </Style.Triggers>
    </Style>
</ctrl:KinectControl.Resources>

So, in this XAML, any "KinectButton" controls are increased in size by 1.1x when the cursor is over them. They return to their original size when the cursor is removed.

Nicholas Pappas
  • 10,439
  • 12
  • 54
  • 87
0
 foreach (var skeleton in skeletons)
                {
                    // skip the skeleton if it is not being tracked
                    if (skeleton.TrackingState == SkeletonTrackingState.Tracked)
                    {
                        #region Zoom out
                        //Zoom Out
                        // Right and Left Hand in front of Shoulders
                        if (skeleton.Joints[JointType.HandLeft].Position.Z < skeleton.Joints[JointType.ElbowLeft].Position.Z &&
                            skeleton.Joints[JointType.HandRight].Position.Z < skeleton.Joints[JointType.ElbowRight].Position.Z)
                        {
                            //Debug.WriteLine("Zoom 0 - Right hand in front of right shoudler - PASS");

                            // Hands between shoulder and hip
                            if (skeleton.Joints[JointType.HandRight].Position.Y > skeleton.Joints[JointType.HipCenter].Position.Y &&
                                skeleton.Joints[JointType.HandLeft].Position.Y > skeleton.Joints[JointType.HipCenter].Position.Y)
                            {
                                // Hands between shoulders
                                if (skeleton.Joints[JointType.HandRight].Position.X < skeleton.Joints[JointType.ShoulderRight].Position.X &&
                                    skeleton.Joints[JointType.HandRight].Position.X > skeleton.Joints[JointType.ShoulderLeft].Position.X &&
                                    skeleton.Joints[JointType.HandLeft].Position.X > skeleton.Joints[JointType.ShoulderLeft].Position.X &&
                                    skeleton.Joints[JointType.HandLeft].Position.X < skeleton.Joints[JointType.ShoulderRight].Position.X)
                                {

                                    float distance = Math.Abs(skeleton.Joints[JointType.HandRight].Position.X - skeleton.Joints[JointType.HandLeft].Position.X);
                                    TransformGroup transformGroup = (TransformGroup)current.RenderTransform;
                                    ScaleTransform transform = (ScaleTransform)transformGroup.Children[0];

                                    if (transform.ScaleX != 1)
                                    {
                                        zoom = true;
                                        transform.ScaleX -= 0.02;
                                        transform.ScaleY -= 0.02;
                                    }

                                    else
                                    { zoom = false; }


                                }

                            }

                        }
  • 1
    Code only answers are usually [frowned upon](http://meta.stackoverflow.com/q/258673/2596334). Try adding an [explination or code comments](http://meta.stackoverflow.com/q/269981/2596334). Thanks. – Scott Solmer Sep 18 '14 at 12:26