图形处理: 使用 .NET Compact Framework 2.0 生成移动图像应用程序 -- MSDN Magazine, December 2006

使用 .NET Compact Framework 2.0 生成移动图像应用程序

Rob Pierrymore ...

打印
E-mail
添加到收藏夹
评价
RSS (Issues)
Add RSS to Any
相关信息
Live Spaces
Digg This
BlogThis!
Slashdot
del.icio.us
Technorati
Explore the code.

Download the code.



本文讨论:移动应用程序的托管代码
使用设备仿真程序测试
支持 .NET Compact Framework 的图形
与 Pocket Outlook 交互
本文使用了以下技术:
.NET Compact Framework 2.0、Windows Mobile 5.0、Visual Studio 2005


Get the sample code for this article.

目录

处理图像
绘制形状和文本
设备仿真程序管理器
使用摄像机
检查系统状态
处理 Pocket Outlook
高级同步概念
总结





通过采用 .NET Compact Framework,Microsoft 将托管代码开发的所有优点引入移动应用程序中。已经熟悉编写 Windows?? 窗体应用程序的开发人员可以快速接手移动设备的编程。Microsoft?? .NET Compact Framework 的 2.0 版现已发布,通过它引入新工具(例如设备仿真程序管理器)和扩大它的覆盖面,使开发工作变得更加容易。特别是,2.0 版为处理图形添加了更多的类和方法以及其他增强功能,包括倾斜文本、自定义笔、图像操作以及与设备的内置摄像机进行交互。本文将讨论这些增强功能,以及可用于 Visual Studio?? 2005 和 .NET Compact Framework 2.0 版的其他新的增强功能。
使用 .NET Compact Framework 为 Windows Mobile?? 5.0 开发应用程序时,主要针对两种类型的设备:Smartphone 和 Pocket PC。虽然为这两种平台开发应用程序的工具可能是相同的,但每个平台的开发经验都已针对它所面向的这种设备进行了自定义。Pocket PC 常常用于可能选择包含电话功能的较大 PDA 设备。另一方面,Smartphone 则是主要用作电话并辅助性地带有 PDA 功能的较小设备。通常,Pocket PC 功能更强大,它可以提供触摸屏、更高的屏幕分辨率、更多内存以及速度更快的处理器。本文集中介绍针对 Pocket PC 的开发。但是一旦您知道如何为 Pocket PC 开发应用程序,针对 Smartphone 的开发工作应当变得很容易。
在开始之前,您需要安装 Windows Mobile 5.0 SDK for Pocket PC。该 SDK 包括 Pocket PC 设备仿真程序、文档和示例。完成安装后,即可开始。
本文将引导您开发一个简单的图像应用程序,该程序支持其上绘制了文本和线条的背景图像。该背景图像可以是从现有图片加载的,也可以是使用设备的内置摄像机拍摄的。这两项任务(打开图片和拍摄图片)将使用对 Compact Framework 2.0 版来说属于新功能的标准对话框。对于覆盖,本文将演示如何使用自定义笔和倾斜文本的新功能,在背景上进行绘制。该应用程序还将允许在完成图片上的绘制后保存图片。另外,我还会介绍如何添加支持功能以通过电子邮件向 Pocket Outlook?? 联系人发送图片。

处理图像

作为基本能力,应用程序必须能够存储背景图像以及文本和线条的前景覆盖,而且它必须能够使这些元素形成单个图像(参见图 1)。在内部,在应用程序保存最终图片之前,图像仍然是独立的元素。这是为了支持基本编辑功能:在保持覆盖的同时替换背景,以及在保持背景的同时清除覆盖。

图 1 独立的背景和前景层主窗体加载时,它将创建两个 Bitmap 类实例,一个用于背景(默认为浅灰),一个用于覆盖(默认为透明)。窗体绘制自身时,它将先绘制背景,然后绘制覆盖。
为了支持透明效果,应用程序使用了 ImageAttributes 类。通常,该类可以用于设置要透明的颜色范围,并且用于以其他颜色替换现有颜色,以及执行其他针对位图、画笔、笔和类似项的操作。遗憾的是,在 Compact Framework 中,只支持透明设置。应用程序使用特定颜色来代表透明,然后在绘制窗体时使用 ImageAttributes 阻止该颜色被绘制。在此示例中,您将使用 Color.AliceBlue 作为透明颜色,然后务必禁止用户选择此颜色来绘制文本和线条。由于想将一个准确的颜色范围设置为透明,因此应用程序只需调用 ImageAttributes 实例的 SetColorKey 方法,然后传递两个参数的 Color.AliceBlue。下面是在背景上绘制覆盖的代码:
private void DrawOverlay(Graphics g, Rectangle region)
{
using(ImageAttributes attribs = new ImageAttributes())
{
attribs.SetColorKey(_transparentColor, _transparentColor);
g.DrawImage(_overlay, region, region.X, region.Y,
region.Width, region.Height, GraphicsUnit.Pixel, attribs);
}
}

为简化起见,应用程序将图像大小限制为不超过设备屏幕的可视区域,该区域可通过 ClientRectangle 属性获得。请记住,此值不一定是常量。例如,在配备滑动键盘的设备上,客户端矩形可以不相同,具体取决于键盘是打开的 (320×188) 还是关闭的 (240×268)。为了解决此问题,在应用程序启动时,应用程序将图像大小默认设置为客户端矩形大小。由于仿真程序无法涵盖所有硬件配置,因此,在实际硬件上测试 Windows Mobile 应用程序变得很重要。
虽然不透明的浅灰色背景很好看,但如果用户可以选择自己的图片来用作背景,则会更好。应用程序使用新的 SelectPictureDialog 类完成此操作。图 2 显示了 SelectPictureDialog 的接口。该类包含在 Microsoft.WindowsMobile.Forms 程序集中,如果要使用此对话框,则必须添加对该程序集的引用。该类的属性允许进行如下设置:设置对话框标题 (Title)、控制用户是否可以用内置摄像机拍摄新图片 (CameraAccess)、按文件类型筛选要显示哪些图片 (Filter) 或者它们是否受数字版权管理保护(ShowDrmContent 和 ShowForwardLockedContent)、设置要显示的初始文件夹 (InitialDirectory) 以及禁止用户更改到任何其他文件夹 (LockDirectory)。对话框关闭之后,可以检查 FileName 属性以获得用户所选图片的文件名。

图 2 选择图片
一旦用户选择了图片,应用程序将用所选图片替换当前背景,并调整大小比例以适合屏幕。获取背景图像的 Graphics 对象之后,将使用 DrawImage 方法在背景上绘制新选的图片。第二个参数代表将在其上绘图的目标的矩形(在这里是整个背景)。第三个参数是源图像的矩形(意思是整个源图像),它被映射到目标矩形。此方法非常灵活。现在,系统将根据您的使用方式自动拉伸较小的图片,并缩小更大的图片,以适合背景,但还可以通过将背景矩形传递给两个参数,非常方便地从新图片中正好截取背景大小的区块。
到这里,应用程序已经能够创建和绘制背景和覆盖,而保存任务则非常简单。您不必在窗体上绘图,只需使用 SaveFileDialog 提示用户输入新的文件名。该方法会创建背景副本,然后在它的上面绘制覆盖层。获得了最终图像后,即可使用 Save 方法(Compact Framework 2.0 版中的新功能)以 JPEG 格式将图像写入磁盘。(也支持 BMP、GIF 和 PNG 格式。)下面是生成和保存图像的代码:
using (Bitmap newImage = new Bitmap(_background))
{
using (Graphics g = Graphics.FromImage(newImage))
{
DrawOverlay(g, new Rectangle(
0, 0, _overlay.Width, _overlay.Height));
}
newImage.Save(dlgSave.FileName, ImageFormat.Jpeg);
}



绘制形状和文本

现在,用户可以通过选择图像来自定义背景,但仍然需要允许用户在覆盖层上进行绘制。Graphics 对象用于绘制形状。该对象有 DrawEllipse、DrawLine 和 DrawRectangle 等方法,它们都以 Pen 为参数。Pen 指示用于绘制形状的颜色和粗细。以前,只能创建指定颜色的笔,但 Compact Framework 2.0 版公开了 Width 属性和另一个构造函数,从而允许同时指定要使用的宽度和颜色。
在应用程序中,SelectPen.cs 实现的窗体让用户选择绘制形状的颜色和宽度。可用颜色在组合框中列出,并且可以通过 NumericUpDown 控件指定宽度。用户进行选择之后,主窗体会将当前笔设置为具有指定颜色和宽度的 Pen 类的新实例。所有后续绘制都将使用此笔。在此窗体中,请记住必须确保不能在组合框中列出用于在覆盖层中表示透明的颜色 (AliceBlue)。否则用户可能不经意地绘制不可见的形状。
在“绘图”菜单下面的“绘制线条”选项中,将显示如何使用当前笔在图像上绘制线条。首先,用户选择线条的两个端点。然后,应用程序获得 Graphics 对象以便在覆盖层上绘制,并使用具有当前笔的 DrawLine 方法来绘制连接两点的线条。
最后一步是以整个 ClientRectangle 作为参数调用 Invalidate。这将导致窗体重新绘制它自身,从而导致在窗体上绘制背景和经过更新的覆盖层。严格地说,只有需要更新的窗体部分才是包含刚才所绘线条的矩形。因此,一个优化措施是只使此矩形无效,而不是使整个客户端区域无效。
查看 Graphics 对象时,您可能已注意到 DrawString 方法。此方法将在指定位置并以指定字体和颜色绘制字符串。由于 Compact Framework 2.0 版支持倾斜文本,因此可以让用户选择两点以定义将沿着它绘制文本的线条,然后提供允许用户输入文本并选择大小的对话框。
通过 LogFont 类可以支持倾斜文本。此名称代表逻辑字体,它是 Windows CE 内部利用的结构,Windows CE 是 Windows Mobile 5.0 所基于的基本操作系统。若要调整文本的角度,可以将角度乘以 10 来设置 LogFont 实例的 Escapement 属性。例如,如果文本从底部到顶部垂直布局,则将 Escapement 设置为 900(与正 x 轴呈 90 度)。
通过 LogFont 创建字体的代码位于文本输入对话框 (TextDialog.cs) 的 GetFont 方法中。在给定两点后,在顶部有少量三角函数用于得出文本的角度。注意,设备的 y 轴发生了颠倒,0 位于屏幕顶部,而不是在底部。一旦调整了这一点,并调整了 arctan 函数的范围,则会得到 Escapement 属性的合适角度。
请记住,在使用 LogFont 时必须始终将 Orientation 属性设置为与 Escapement 相同的值。若要设置 LogFont 的 Height ,需要取得由用户提供的大小,并调整设备的 DPI。(可以使用 Graphics 对象的新 DpiX 和 DpiY 属性来确定 DPI。)如果以负数提供该值,Framework 将选择点大小最接近该属性绝对值的字体。此处还有更多选项,MSDN?? 文档对此进行了解释。图 3 显示用于通过 LogFont 获得字体的代码。
正确设置完 LogFont 后,即可通过调用 Font 类的静态 FromLogFont 方法来创建 Font 实例。有了大小适当的字体、一些文本和点后,就可以很容易地使用 DrawString 方法将它输出到图像。


设备仿真程序管理器

如果您曾经用 Visual Studio 进行过任何移动开发,则可能已熟悉设备仿真程序。该仿真程序的外观和操作很像 Pocket PC,这样就可以模拟在真实移动设备上运行程序。可以将仿真程序配置成多种屏幕大小、内存配置和可用端口。甚至可以配置它模拟电话功能。
在 Visual Studio 2005 中,需要通过设备仿真程序管理器来处理仿真程序,该管理器位于“工具”菜单中。设备仿真程序管理器启动时,它将列出所有可用的仿真程序,并按目标操作系统进行分组。请注意,在 Windows Mobile 5.0 Pocket PC SDK 下面列出了几个选项,其中包括基本仿真程序、有电话功能的仿真程序和具有 VGA (640x480) 分辨率屏幕的仿真程序。
通过右键单击仿真程序并选择“连接”选项,可以启动仿真程序。然后,设备仿真程序管理器将在仿真程序旁边显示绿色箭头。图 4 显示正在运行仿真程序的设备仿真程序管理器。

图 4 正在运行仿真程序的设备仿真程序管理器 (单击该图像获得较小视图)
图 4 正在运行仿真程序的设备仿真程序管理器 (单击该图像获得较大视图)
Visual Studio 2005 和 ActiveSync?? 4.0 的一项新功能是能够在桌面计算机和仿真程序之间创建合作关系,就好像它是实际的设备。要这样做,请打开 ActiveSync,并选择“文件”|“连接设置”。确保选中“允许连接到以下其中一个端口”,并从下拉列表选择“DMA”(仿真程序通过 DMA 与 ActiveSync 通话)。按“确定”。现在,在设备仿真程序管理器中,右键单击正在运行的仿真程序(旁边有绿色箭头的那个),并选择“插入底座”。ActiveSync 将激活,然后提示您创建与新设备的合作关系。设备仿真程序管理器会将绿色箭头更改为其他图标,以指示设备已插入底座。要使仿真程序与 ActiveSync 断开,只需在设备仿真程序管理器列表中右键单击仿真程序,并选择“移除底座”。
尽管在 Visual Studio 2005 中设备仿真程序管理器已使仿真程序变得更强大,但仿真程序并非不受限制。前面我提到过,仿真程序目前不模拟具有滑动键盘的设备。如果开始添加对通过设备的摄像机来捕获背景的支持,则会有另一个重要限制。目前仿真程序根本不支持摄像机功能。如果尝试在仿真程序运行的同时访问摄像机对话框,将遇到 Invalid-OperationException 消息。


使用摄像机

现在可以让用户拍照以充当背景。要运行应用程序的此部分功能,需要有配备摄像机的 Windows Mobile 5.0 Pocket PC。一旦将设备连接到了计算机,并在 ActiveSync 中可以选择地创建配置文件,请在设备工具栏的下拉列表中将目标设备从 Windows Mobile 5.0 Pocket PC 仿真程序更改为 Windows Mobile 5.0 Pocket PC 设备,然后照常运行项目。(注意,部署到真实设备时,断点和调试将像在仿真程序中进行调试一样继续工作。)
用户从“文件”菜单中选择“新建背景”时,应用程序将创建并显示新的 CameraCaptureDialog 实例。该实例与 SelectPictureDialog 在相同的程序集 Microsoft.WindowsMobile.Forms 中。该对话框允许完整配置摄像机的初始设置,尽管用户仍然可以通过常规选项菜单调整它们。Mode 属性指定用户是否只能拍摄单张照片 (CameraCaptureMode.Still)、视频 (CameraCaptureMode.VideoOnly) 或带音频的视频 (CameraCaptureMode.VideoWithAudio)。由于希望拍摄背景图像,因此需要让应用程序将对话框设置为静止图片模式,并且让静止图像使用最高质量(使用 StillQuality 属性)。还可以设置指示视频长度的可选时间限制的属性 (VideoTimeLimit),以及确保视频适合以多媒体邮件发送的属性 (VideoTypes)。
也可以设置 Resolution 属性以控制所拍图片的大小。通常,不支持任意值。而应当使用设备可接受的值(例如,640×480 或 1280×1024)。由于需要缩小图片以适应屏幕,因此请保留 Resolution 的默认值。
一旦用户拍摄了图片,ShowDialog 方法将返回 DialogResult.OK 作为结果。现在,若要加载新拍摄的图片,可以使用前面用过的相同缩放技术,将现有图像调整到背景大小。由于只替换背景图像,因此用户已绘制的任何线条或文本将保持不变。一旦图片绘制到背景上,即可对整个客户端矩形调用 Invalidate,这将导致用现在显示为背景的新图片重绘屏幕。


检查系统状态

您可以显示 CameraCaptureDialog,然后,如果设备没有摄像机,则引发 InvalidOperationException。但是,更好的做法是提早确定摄像机功能是否存在,然后,如果设备不提供摄像机功能,只需禁用该菜单选项。可以通过查询设备的常规配置并监视实时属性的更改情况来执行此任务。
有关设备的信息可通过 SystemState 类进行公开,该类在 Microsoft.WindowsMobile.Status 程序集中。通过添加对该程序集及其依赖项 Microsoft.WindowsMobile 的引用,可以在应用程序中使用此信息。SystemState 类有许多静态属性,通过它们可以确定固定配置信息和实时信息,例如当前日期和时间或电池剩余电量。
应用程序只需在启动时检查一次 CameraPresent 属性,然后,如果摄像机不可用,应用程序就可以禁用“新建背景”菜单选项。但是,SystemState 类公开您可以处理的 Changed 事件,以便在请求状态发生更改时得到通知。这样,不必使用静态属性,就可以创建 SystemState 实例,并将要监视的特定系统属性传递到构造函数中,然后只需添加 Changed 事件的处理程序。例如,可以扩展应用程序以监视 DisplayRotation 系统属性,以便当应用程序在用户滑出设备的键盘以及显示设备从纵向更改到横向时得到通知。或者,应用程序可以监视 ActiveSyncStatus 属性,以便有可能在设备正在执行同步时执行某些操作。
在引发 Changed 事件之前,SystemState 类还会考虑 ComparisonType 和 ComparisonValue 属性。默认情况下,受监视属性中的所有更改都会引发 Changed 事件。但是,如果(例如)将 ComparisonType 属性设置为 ComparisonType.Greater 并将 ComparisonValue 属性设置为 2,则只有当正在监视的系统属性更改为大于 2 的值,才会引发 Changed 事件。通过使用其他比较类型(比如 Equals、Contains 或 StartsWith),您将能够对应用程序处理哪些事件进行很细致的控制。
SystemState 的主要限制是,当状态发生更改时,应用程序必须正在运行,才能使它得到通知。还需要确保将您正在处理其 Changed 事件的 SystemState 实例声明为类级别的字段,而不是局部方法变量,以便它不会被垃圾收集,从而导致丢失事件。


处理 Pocket Outlook

Windows Mobile 5.0 提供了新程序集 Microsoft.WindowsMobile.PocketOutlook,用于与存储在设备上的邮件帐户、任务、日历项目和联系人进行交互。可以在应用程序中使用此程序集,以便用户可以选择拥有电子邮件地址的联系人,然后向此联系人发送图片。
通过使用新的 ChooseContactDialog,可以提示用户选择整个联系人或特定联系人的特定属性(如图 5 所示)。此对话框的最有用的功能之一是能够筛选可用联系人列表。由于该功能的设计目的是将图片通过电子邮件发送给联系人,因此对于此应用程序,只显示拥有电子邮件地址的联系人。对话框的 RequiredProperties 属性包含用于控制筛选的 ContactProperty 枚举值数组。应用程序使用一个值为 ContactProperty.Email1Address 的 ContactProperty 来指示只有拥有有效电子邮件地址的联系人才应当显示。此枚举值包含联系人的所有属性,例如,Birthday、BusinessAddress 和 HomeTelephoneNumber。通过使用 RequiredProperties,可以方便地筛选联系人列表,以获得与将在此应用程序中使用联系人的方式相关的可管理列表。

图 5 选择联系人
使用 EmailMessage 类的实例可以实际发送邮件。只需在 To 属性的集合中添加新的 Recipient(这将设置 Subject 和 Body 属性),然后将图像添加到 Attachments 集合中。与所有邮件帐户、日历和其他 Outlook 功能的主要交互过程都是通过 OutlookSession 来完成的。一旦创建了 OutlookSession 实例,即可使用 EmailAccounts 属性来取得第一个电子邮件帐户,并发送邮件。基于设备的状态和设置,电子邮件会立即发送,或是在下一次用户有网络连接并且启动发送操作时发送。图 6 显示了用于发送电子邮件的代码。


高级同步概念

尽管在简化示例中发送电子邮件工作得很好,但它不一定是传输数据的正确选择。当需要在设备和桌面计算机之间移动数据时,对于更复杂的方案,ActiveSync 会更合适。即使 Microsoft 已在版本 2.0 中极大地扩展了 Compact Framework 的覆盖面,但某些区域仍然在托管代码能涉及到的范围以外。从桌面计算机与 ActiveSync 交互和与设备通信仍然需要使用非托管代码。但可以在不必编写非托管代码的情况下入手。
ActiveSync 通过合作关系和各种服务提供程序(例如,用于同步邮件和日历信息的 Outlook 提供程序)在移动设备和桌面计算机之间同步数据。每个提供程序均由一组实现特定 COM 接口的 DLL(一个在设备上,一个在桌面计算机上)组成。这些提供程序的功能非常强大,但对开发来说仍然很复杂。但是,对于很少关注复杂同步的基本方案来说,当移动设备已连接或断开而未执行服务提供程序时,可用很容易的方式来获得通知。
在注册表中,有一个在设备连接或断开时自动运行的程序所组成的列表。这些项位于 HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows CE Services/AutoStartOnConnect 和 /AutoStartOnDisconnect 中。要使用这些项,只需创建一个有唯一名称并且包含指向要运行的可执行文件的路径的字符串值。例如,如果在 AutoStartOnConnect 中添加一个名称为 NotepadTest 并且值为 notepad 的字符串,则每次设备连接到系统时都将启动记事本。如果要向程序传递命令行参数,请将程序名放在双引号内。值 "notepad" c:/test.txt 将启动记事本,并且其中包含当设备连接时的 test.txt 的内容。另外,Windows Mobile 5.0 允许您通过非托管函数 ActiveSyncStart 和 ActiveSyncStop,以编程方式从设备启动和停止 ActiveSync 进程。
既然知道如何在设备连接后立即启动桌面计算机上的应用程序,那么下一步是与设备通信,这是通过远程应用程序编程接口 (RAPI) 来完成的。.NET Framework 目前不包括托管版本的 RAPI。由于 RAPI 只是本机 API,因此 .NET 支持通过平台调用来调用它所包含的函数。如果要处理在移动设备和桌面计算机之间往返传输的移动数据,一种简便方法是创建使用此 API 并且能够在设备连接时自动启动的基于 .NET 的应用程序。


总结

Compact Framework 2.0 版(随 Visual Studio 2005 一起提供)建立在第一个版本所获成功的基础之上,它可以使开发移动应用程序变得更容易。而且,您开发的应用程序的功能将更加强大。由于开发人员在开发移动应用程序时可以使用与开发其他托管代码应用程序相同的工具和类,因此更多开发人员可以更快地参与编写功能强大的移动应用程序的工作。
同时,新的 API 允许开发人员更完整地利用功能日益强大的移动设备的所有功能。他们编写的应用程序可以与设备的摄像机交互,还可以包含与其他设备通信的功能。最终,开发人员可以创建满足需要的最合适的解决方案,从而利用相应设备的相应功能,而不必担心开发工作量和成本会增加。


NEW: Explore the sample code online! - or - 代码下载位置: PocketPC2006_12.exe (157KB)

本文转自
http://msdn.microsoft.com/msdnmag/issues/06/12/CompactFramework/Default.aspx?loc=zh#S2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值