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






4.81/5 (8投票s)
在本文中,我将描述在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日:初始帖子