65.9K
CodeProject 正在变化。 阅读更多。
Home

多点触控开发中的图像处理

2010年4月3日

CPOL

3分钟阅读

viewsIcon

64255

downloadIcon

2548

在本文中,我将描述在Windows 7多点触控环境中的图像处理。

引言

Windows 7 带来了许多好东西,包括更好的资源管理、更好的性能、跳转列表管理、多点触控功能等等。在这里,我将讨论如何使用.NET 3.5 SP1开发一个简单的多点触控应用程序。

在做任何事情之前,你必须下载Windows 7多点触控API。你可以从这里下载。将下载的zip文件解压到你的本地硬盘驱动器。确保你正在使用Windows 7,并且你有一个支持多点触控的屏幕来测试它。

使用 ManipulationProcessor

使用Visual Studio 2008创建一个WPF应用程序。这将自动为你添加一个名为Window1.xaml的XAML文件。现在将一张图片添加到你的解决方案目录中,并将其插入到XAML中。现在你的Window1.xaml看起来像这样

<Grid>
<Image Source="images/Hydrangeas.jpg"/>
</Grid>

RenderTransform 添加到图像,以便我们可以正确地缩放或旋转图像。这将产生类似于这样的XAML

<Grid>
<Image Source="images/Hydrangeas.jpg" RenderTransformOrigin="0.5,0.5" Width="400">
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="trScale" ScaleX="1" ScaleY="1"/>
<RotateTransform x:Name="trRotate" Angle="0"/>
<TranslateTransform x:Name="trTranslate" X="0" Y="0"/>
<SkewTransform AngleX="0" AngleY="0"/>
</TransformGroup>
</Image.RenderTransform>
</Image>
</Grid>

当你向变换组添加不同类型的变换时,使用正确的名称。这将使你更容易从后台代码文件中处理它。运行你的应用程序。这将打开你的窗口,里面有一张图片。如果你想拖动或旋转图像,这不起作用,因为我们还没有集成该功能。

添加两个项目引用,即从解压的zip文件夹中添加Windows7.Multitouch & Windows7.Multitouch.WPF到你的解决方案。这些是用于多点触控应用程序开发的托管API代码。

转到你的Window1.xaml.cs,并确保已经包含了以下命名空间。你可能需要添加其中的一些。

using System;
using System.Windows;
using Windows7.Multitouch;
using Windows7.Multitouch.Manipulation;
using Windows7.Multitouch.WPF;

在你的部分类中创建两个private 成员

// object of a .Net Wrapper class for processing multitouch manipulation
private ManipulationProcessor manipulationProcessor = 
		new ManipulationProcessor(ProcessorManipulations.ALL);

// boolean value to check whether you have a multitouch enabled screen
private static bool IsMultitouchEnabled = 
		TouchHandler.DigitizerCapabilities.IsMultiTouchReady;

现在在Window Loaded事件内部,编写以下代码行

// check to see whether multitouch is enabled
if (IsMultitouchEnabled)
{
     // enables stylus events for processor manipulation
     Factory.EnableStylusEvents(this);

     // add the stylus events
     StylusDown += (s, e) => 
     { 
          manipulationProcessor.ProcessDown
		((uint)e.StylusDevice.Id, e.GetPosition(this).ToDrawingPointF()); 
     };
     StylusUp += (s, e) => 
     { 
          manipulationProcessor.ProcessUp
		((uint)e.StylusDevice.Id, e.GetPosition(this).ToDrawingPointF()); 
     };
     StylusMove += (s, e) => 
     { 
          manipulationProcessor.ProcessMove
		((uint)e.StylusDevice.Id, e.GetPosition(this).ToDrawingPointF()); 
     };

     // register the ManipulationDelta event with the manipulation processor
     manipulationProcessor.ManipulationDelta += ProcessManipulationDelta;

     // set the rotation angle for single finger manipulation
     manipulationProcessor.PivotRadius = 2;
}

在操作事件处理程序实现块中编写你的逻辑。在这里,我将对图像进行旋转、缩放和定位。这是我的代码

private void ProcessManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
     trTranslate.X += e.TranslationDelta.Width;
     trTranslate.Y += e.TranslationDelta.Height;

     trRotate.Angle += e.RotationDelta * 180 / Math.PI;

     trScale.ScaleX *= e.ScaleDelta;
     trScale.ScaleY *= e.ScaleDelta;
}

ManipulationDeltaEventArgs,你可以获得各种值,并根据这些值,你可以在此块中实现你的功能。TranslateTransform 将定位图像,RotateTransform 将进行旋转,而ScaleTransform 将调整图像大小。运行你的项目来测试你的第一个多点触控应用程序。

使用 Stylus

在这里,我将向你展示如何分别管理所有图像的多点触控事件。查看一个这样的图像处理演示这里

为此,我们必须为屏幕上的每个手指分配一个唯一的触控ID。只要手指触摸屏幕,相关的触控ID将保持不变,对于该特定手指来说。如果用户松开他的手指,系统将释放触控ID,并且该ID可以在下次触摸时由系统自动再次分配。那么,我们如何获得触控ID呢?你可以从StylusEventArgs (即args.StylusDevice.Id) 中获取它。手写笔设备将自动为每次触摸生成此ID;唯一的事情是,你必须将其分配给相应的手指触摸。

首先,我们将创建一个用户控件,它将包含单个图像及其RenderTransform的XAML代码。这与我们在之前的文章中所做的相同,它在Window内部,但是在这里,它将在用户控件(Picture类)内部。创建一个DependencyProperty来动态地分配ImageLocation

<UserControl x:Class="Windows7MultitouchDemo.Picture"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Image Source="{Binding Path=ImageLocation}" Stretch="Fill" Width="Auto"
           Height="Auto"  RenderTransformOrigin="0.5, 0.5">
        <Image.RenderTransform>
            <TransformGroup>
                <RotateTransform x:Name="trRotate"/>
                <ScaleTransform x:Name="trScale"/>
                <TranslateTransform x:Name="trTranslate"/>
            </TransformGroup>
        </Image.RenderTransform>
    </Image>
</UserControl>

为了同时跟踪上述“Picture”用户控件的多点触控,你可以使用Windows 7培训工具包附带的PictureTracker类。你可以从Microsoft网站下载它。它看起来类似于这样

/// <summary>
/// Track a single picture
/// </summary>
public class PictureTracker
{
   private Point _prevLocation;
   public Picture Picture { get; set; }
   public void ProcessDown(Point location)
   {
       _prevLocation = location;
   }
   public void ProcessMove(Point location)
   {
       Picture.X += location.X - _prevLocation.X;
       Picture.Y += location.Y - _prevLocation.Y;
       _prevLocation = location;
   }
   public void ProcessUp(Point location)
   {
       //Do Nothing, We might have another touch-id that is
       //still down
   }
}

现在,我们必须存储与PictureTracker类关联的所有活动触控ID。因此,我们将为此使用一个Dictionary。我们将使用同样来自Windows 7培训工具包的PictureTrackerManager类。

private readonly Dictionary<int, PictureTracker> _pictureTrackerMap;

在你的Window1.xaml.cs中创建一个PictureTrackerManager类的实例,并将笔事件注册到PictureTrackerManager事件。因此,现在,每当在Picture上发生触摸时,PictureTrackerManager将首先找到相关实例的关联触控ID,并引发一个事件来处理它。

//Register for stylus (touch) events
StylusDown += _pictureTrackerManager.ProcessDown;
StylusUp += _pictureTrackerManager.ProcessUp;
StylusMove += _pictureTrackerManager.ProcessMove;

参考

历史

  • 2010年4月3日:初始帖子
© . All rights reserved.