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

使用 ImageGear for Silverlight 和 Azure 构建多页图像查看器

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2010年8月31日

CPOL

13分钟阅读

viewsIcon

22464

本文将通过开发一个完全在客户端运行的多页图像查看器,对ImageGear for Silverlight工具包进行一次快速的游览。该查看器将通过托管代码实现。一旦查看器构建完成,就可以通过Azure Cloud Service项目部署到Windows Azure云。

随着近十年来富互联网应用(RIA)日益强大的功能和用户体验,RIA技术已变得越来越强大。然而,许多RIA技术因其非同寻常的学习曲线而让许多客户端应用程序开发者望而却步。在众多的RIA技术中,你该从何开始?在很多情况下,并没有“一刀切”的解决方案,因此RIA开发可能会涉及HTML、JavaScript、Adobe Flash,甚至可能还会用到AJAX(仅举几例)。幸运的是,微软已进入RIA框架领域,并凭借Microsoft Silverlight提供了一个平台,该平台可以充分利用现有.NET开发者的技能。

Silverlight包含了许多与.NET Framework相同的基本服务和类型。然而,由于它是一个专门为Web构建的运行时,开发者期望一个强大的平台且包体小巧,因此其桌面兄弟版本中的许多功能都缺失了。例如,Silverlight中的图像类型System.Windows.Media.Imaging.BitmapImage仅支持JPEG和PNG图像文件类型,并且不包含对灰度的支持。这时,第三方工具供应商就成为了Silverlight生态系统的一部分,在市场需求驱动下,他们提供了对基础平台的扩展。在图像领域,Accusoft Pegasus凭借其为Silverlight开发者提供的最全面的图像工具包——ImageGear for Silverlight,继续保持其在图像软件开发工具包(SDK)领域的领导者地位。

本文将通过开发一个完全在客户端运行的多页图像查看器,对ImageGear for Silverlight工具包进行一次快速的游览。该查看器将通过托管代码实现。一旦查看器构建完成,就可以通过Azure Cloud Service项目部署到Windows Azure云。

构建查看器

要开始,请在此处下载ImageGear for Silverlight SDK和示例代码。打开Visual Studio 2010,然后调出“**新建项目**”对话框。在“**Visual C#**”下,选择“**Silverlight**”作为项目类型,然后选择“**Silverlight应用程序**”作为项目模板。输入项目的名称(示例中使用的是MultiPageImageViewer),然后单击“确定”(图1)。

image001.gif

图1:定义Silverlight项目

接下来的屏幕需要稍作解释,特别是对于Silverlight开发新手。Silverlight应用程序的部署单位是XAP包,它部署在HTML网页中,或作为ASP.NET项目的一部分。对于许多Silverlight应用程序来说,使用HTML网页作为宿主是完全可以的。然而,ImageGear for Silverlight使用一个Web服务来验证其SDK许可,调用该Web服务的Silverlight应用程序必须从托管该服务的域名运行。因此,最好避免使用HTML网页选项,而是创建ASP.NET项目。项目向导会为您设置好一切(图2),因此即使是最不经验的Web开发者也能轻松完成。

image002.gif

图2:选择Silverlight宿主

单击“确定”按钮后,将创建一个解决方案,其中包含两个项目——Silverlight应用程序(我们将在其中花费大部分时间)和一个ASP.NET宿主项目(设置为启动项目)。如果您现在编译并运行,应用程序将执行;然而,它会非常无聊——只是IE中一个空白的页面。然而,这个页面并非空白。它运行着一个完整的Silverlight应用程序。我们只需要构建其布局来支持我们的图像查看器。

定义布局

如果您使用过**Windows Presentation Foundation (WPF)**或**Windows Workflow Foundation (WF)**,那么您很可能已经熟悉XAML。XAML不过是一种初始化.NET类型集合的方法,但在微软提供的下一代GUI堆栈中非常受欢迎,这也延伸到了Silverlight。为了定义我们的多页图像查看器的布局,我们将修改生成的XAML,以指定比默认的空白表面更合适的UI。XAML和Silverlight GUI堆栈的完整概述超出了本文的范围,但我们会简要解释我们所做的。

为了帮助我们定位,下面的图3显示了Visual Studio生成的默认视图和XAML。它定义了一个Silverlight **UserControl**,其中包含一个空的**Grid**。

image003.gif

图3:生成的Page.xaml

对于我们的图像查看器,我们希望在**UserControl**中添加几个控件——一个ImageGear.Windows.Controls.PageView类型的实例用于显示图像,以及几个按钮用于支持打开文件和在页面之间导航。在修改XAML之前,我们需要向项目添加一些引用,以确保对ImageGear for Silverlight的调用在编译时能够解析。ImageGear for Silverlight允许开发者仅部署其特定应用程序所需的程序集。这使得开发者能够保持部署包的小巧,同时启用非必要程序集的后台加载。ImageGear for Silverlight程序集的完整列表和描述可以在工具包的文档中找到。现在,只要确保您的引用列表如图4所示即可。您可以在\\Program Files\Accusoft\ImageGear for Silverlight v17\Bin目录中找到ImageGear for Silverlight程序集。

image004.gif

图4:必需的引用

下面的清单1显示了我们图像查看器布局的XAML。清单1中的XAML在原始网格中添加了两行,一行用于容纳图像查看器,另一行用于容纳按钮。ImageGear.Windows.Controls.PageView直接放置在单元格中,因为它将简单地填充其可用空间。然而,按钮需要一些额外的布局容器来确保创建所需的布局。这是通过一个包含两列的第二个**Grid**来实现的。第一列将包含一个我们将用于调用“打开文件”操作的**Button**。第二列将包含两个按钮——“上一页”和“下一页”——因此我们将使用一个**StackPanel**容器并在其中放置两个按钮。我们的XAML中的一个亮点是为每个按钮使用了一个**Style**资源。为了让我们的XAML更简洁高效,按钮的外观被定义了一次,作为一个**Style**。**Style**包含在**UserControl**资源中,并应用于每个按钮。关于Silverlight GUI元素和XAML,有许多优秀的资源,如果您不熟悉这些技术,我鼓励您去了解。您将永远不想再拖放用户控件了!

清单1:多页图像查看器XAML

<UserControl x:Class="MultiPageImageViewer.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:IGSilverlightUI=
		"clr-namespace:ImageGear.Windows.Controls;assembly=ImageGear18.Windows.Controls"
    MinWidth="640" MinHeight="480">

    <UserControl.Resources>
        <Style x:Key="ButtonStyle" TargetType="Button">
            <Setter Property="Width" Value="100"/>
            <Setter Property="Margin" Value="8,4,8,4"/>
        </Style>
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="9*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!-- Primary Image Viewer -->
        <Grid Grid.Row="0" Background="Gray">
            <IGSilverlightUI:PageView Margin="8" 
                x:Name="mPageView" Background="Gray"/>
        </Grid>

        <!-- Button Row -->
        <Grid Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="1*"/>
                <ColumnDefinition Width="2*"/>
            </Grid.ColumnDefinitions>

            <Button x:Name="mOpenButton" Grid.Column="0" Style="{StaticResource ButtonStyle}" 
                    Click="mOpenButton_Click" HorizontalAlignment="Left" IsEnabled="False">
                <TextBlock Text="Open File"/>
            </Button>

            <StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
                <Button x:Name="mPreviousButton" Style="{StaticResource ButtonStyle}" 
                        Click="mPreviousButton_Click" IsEnabled="False">
                    <TextBlock Text="<< Previous"/>
                </Button>
                <Button x:Name="mNextButton" Style="{StaticResource ButtonStyle}" 
                        Click="mNextButton_Click" IsEnabled="False">
                    <TextBlock Text="Next >>"/>
                </Button>
            </StackPanel>
        </Grid>
    </Grid>
</UserControl>

仅凭XAML定义很难形象地展示我们的图像查看器。方便的是,Visual Studio支持分屏视图,因此您可以在进行过程中看到XAML的结果。下面的图5显示了清单1中的XAML生成的布局。

image005.gif

图5:多页图像查看器布局

我们离空白页面已经走了很长一段路,但现在我们需要编写应用程序运行的代码。如果您现在编译并运行,您将面临各种错误(例如缺少点击处理程序),所以让我们来处理这些问题,让我们的图像查看器运行起来!

代码

我们将从构造函数中的初始化代码开始,该代码包含在下面的清单2中。ImageGear for Silverlight需要许可才能运行,并且在您开发应用程序时,它使用Web服务进行验证。[1]ImGearLicense.SetService调用允许您指定此Web服务的位置。许可Web服务需要从与工具包相同的机器上的URL运行。接下来,设置一个匿名委托,以便在LicenseRequest事件触发时运行,稍后将详细介绍。最后,调用ImGearLicense.SetSolutionName,并将评估解决方案名称作为参数传递。

LicenseRequest事件发生时执行的匿名委托是其余初始化的发生地。由于涉及Web服务,因此需要此事件;当向Web服务发出许可请求时,响应不是同步的。因此,我们必须等待请求被授予后再继续。在委托体中,将执行ImageGear.Formats.Common程序集(及其格式)的初始化。虽然工具包需要公共格式才能在PageView中显示图像,但其他所有格式都是可选的。开发者可以自行选择。

清单2:Page构造函数和ImageGear for Silverlight初始化

using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using ImageGear.Core;
using ImageGear.Display;
using ImageGear.Formats;

public Page()
{
    InitializeComponent();

	// Assuming evaluation mode...see the ImageGear for Silverlight 
   	// documentation for an explanation of evaluation mode
   	ImageGear.Evaluation.EvaluationManager.Initialize();
  	Application.Current.RootVisual = this;

    // ImageGear for Silverlight Development licensing. This licensing
	// requires the sample to be run from a URL hosted on the same machine
	// ImageGear for Silverlight was installed on.
    string webServiceUrl = string.Format("http://{0}/{1}",
        App.Current.Host.Source.DnsSafeHost,
        "ImageGearSilverlight18_WebService/SilverlightWebService.svc");

    ImGearLicense.SetService(webServiceUrl);
    ImGearLicense.LicenseRequest = 
        new ImGearLicense.DelegateLicenseRequest(delegate(Exception error)
		{
			// Initialize format components 
			ImGearCommonFormats.Initialize();			

			// ImageGear Initialized and Licensed; Enable the Open Button
           	this.mOpenButton.IsEnabled = true;
        });

     ImGearLicense.SetSolutionName("AccuSoft 5-44-18");
}

一旦工具包初始化完成,我们就可以为每个按钮编写处理程序,并获取一些图像在应用程序中显示。mOpenButton处理程序(清单3)执行了大部分工作。大部分代码是标准的,对于任何使用过OpenFileDialog类型的人来说都会很熟悉。创建的**Stream**作为参数传递给ImGearFileFormats.LoadDocument进行加载。如果工具包已知与文件类型对应的编解码器(通过上面的初始化),它将加载;否则,将抛出ImGearException

文档加载到ImGearDocument实例后,将创建一个ImGearPageDisplay实例来指定**PageView**的可视化页面。将这些概念联系起来的最简单方法是,将ImGearDocument视为文件的内存表示,将ImGearPresentationPageDisplay视为用于显示的页面的逻辑表示。换句话说,ImGearPresentationPageDisplay类型包含**PageView**正确显示页面的指令。示例可能包括分辨率、裁剪矩形或变换。要显示页面,将ImGearPresentationPageDisplay赋值给PageView.Display属性,并调用PageView.Update以强制重绘。**

清单3:打开按钮处理程序

private ImGearDocument mLoadedDocument = null;
private Int32 mCurrentPage = -1;
private ImGearPresentationPageDisplay mCurrentPageDisplay = null;

			.
			.
			.

private void mOpenButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
    // Prompt the user to select an image file 
    OpenFileDialog ofd = new OpenFileDialog();
    ofd.Filter = 
        "Image files (*.tif;*.jpg;*.png;*.bmp)|*.tif;*.jpg;*.png;*.bmp|All files (*.*)|*.*";
    ofd.FilterIndex = 1;
    bool? result = ofd.ShowDialog();
            
    if (!result.GetValueOrDefault(false))
        return;

    try
    {
        using (Stream f = ofd.File.OpenRead())
        {
            // Open it with ImageGear, showing the first page by default
            this.mLoadedDocument = ImGearFileFormats.LoadDocument(f, 0, -1);
            this.mCurrentPage = 0;

            if (null == this.mCurrentPageDisplay)
            {
                this.mCurrentPageDisplay = 
                   new ImGearPresentationPageDisplay(this.mLoadedDocument.Pages[this.mCurrentPage]);
            }
            else
            {
                this.mCurrentPageDisplay.Page = 
                   this.mLoadedDocument.Pages[this.mCurrentPage];
            }

            mPageView.Display = this.mCurrentPageDisplay;
            mPageView.Update();

            // Update the previous\next buttons depending on page count
            this.UpdateButtonStates();
        }    
    }
    catch (ImGearException)
    {
        MessageBox.Show("The file selected is not supported by this sample.", 
                "MultiPageTiffViewer Control", System.Windows.MessageBoxButton.OK);
    }
}
}

其余代码通过上一页和下一页按钮操作显示的页面,修改由**PageView**类型显示的页面。ImGearDocument中的**Pages**集合允许您选择加载到ImGearPresentationPageDisplay中的页面。请记住,更改页面显示时,请务必调用ImGearSilverlightPageView.Update,否则不会发生重绘。

清单4:上一页和下一页按钮处理程序,UpdateButtonStates方法

private void mPreviousButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
    if (this.mCurrentPage > 0)
    {
        this.mCurrentPageDisplay.Page = this.mLoadedDocument.Pages[--this.mCurrentPage];
        this.mPageView.Update();
    }

    // Update the previous\next buttons depending on page count
    this.UpdateButtonStates();            
}

private void mNextButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
    if (this.mCurrentPage < this.mLoadedDocument.Pages.Count - 1)
    {
        this.mCurrentPageDisplay.Page = this.mLoadedDocument.Pages[++this.mCurrentPage];
        this.mPageView.Update();
    }

    // Update the previous\next buttons depending on page count
    this.UpdateButtonStates();
}

private void UpdateButtonStates()
{
    this.mPreviousButton.IsEnabled = 
        (this.mCurrentPage > 0 && mLoadedDocument.Pages.Count > 1) ? true : false;           
            
    this.mNextButton.IsEnabled = 
        ((this.mCurrentPage < (this.mLoadedDocument.Pages.Count - 1) && 
        mLoadedDocument.Pages.Count > 1)) ? true : false;
}

至此,我们已经有了Silverlight的多页图像查看器!下面的图6显示了最终产品。借助ImageGear for Silverlight,我们扩展了基础平台以支持TIFF文件的加载,并且我们拥有一个适合文档图像显示的 RIA。最棒的是,这一切都是用XAML和C#等当前.NET技术,利用生态系统中的工具完成的。当然,一个功能齐全的查看器可以做得更多,而ImageGear for Silverlight将帮助您实现这一目标。

image006.gif

图6:多页图像查看器

为多页图像查看器构建Azure Cloud Service

随着Microsoft Windows Azure今年早些时候的商业化发布,Silverlight应用程序的开发者现在拥有了一种可扩展的部署方法。借助Windows Azure SDK,微软简化了云服务的开发,包括一个丰富的模拟环境,无需购买生产云中的计算实例即可进行开发。为了演示入门云的便捷性,我们将创建一个Azure Cloud Service来托管多页图像查看器,并在Azure模拟环境中运行它。

在Visual Studio 2010中打开上面创建的**MultiPageImageViewer**解决方案,然后调出“**添加新项目**”对话框。在“**Visual C#**”下,选择“**Cloud**”作为项目类型,然后选择“**Windows Azure Cloud Service**”作为项目模板。如果**Windows Azure Cloud Service**不可用,Visual Studio 2010会提示您安装。完成安装后,请按照这些说明创建服务。为项目输入一个名称,然后单击“确定”(图7)。

image007.gif

图7:创建Azure Cloud Service项目

接下来的屏幕(图8)将提示您创建一个新的Cloud Service项目。目前,只需单击“确定”关闭对话框。我们稍后会回来处理它。

image008.gif

图8:新Cloud Service项目对话框

此时,解决方案中存在一个Azure服务外壳,但该服务没有任何功能。实际上,如果您构建解决方案,将会产生一个错误。这是因为Azure服务必须定义一个或多个角色。目前有两种角色类型——Web角色和工作者角色。每个角色封装工作单元,这些工作单元可以跨一台或多台计算机进行复制,以实现Azure服务公开的功能。有关角色和Windows Azure服务体系结构的完整描述可在MSDN上找到[2]

下一步是为服务定义一个角色。在我们的例子中,需要一个Web角色,因为服务公开的功能是托管Silverlight应用程序。我们在构建查看器时定义了一个ASP.NET项目,我们将重用该项目作为我们Web角​​色的源。要做到这一点,请选择**CloudService**项目中的**Roles**文件夹。从**Project**菜单中,选择**Add | Web Role Project in solution**,然后将显示下面的图9所示的对话框。

image009.gif

图9:关联角色项目对话框

选择MultiPageImageViewer.Web项目,然后单击“确定”。此时,一个功能齐全的Azure服务已创建。如果您构建并运行解决方案,Azure模拟项目将启动,应用程序将运行,如图10所示。

image010.gif

图10:Azure模拟环境中的多页图像查看器

乍一看,这与上面图6中显示的查看器非常相似。然而,有一个重要的区别。请检查URL。图10中的查看器正在从http://127.0.0.1:81运行,这是Azure模拟环境的默认地址。

Windows Azure还有更多内容,包括服务配置、部署和存储,希望这个简单的例子表明,通过Azure,Silverlight应用程序的部署得到了极大的简化。Azure提供了一种可扩展的方式将Silverlight应用程序推向市场,而无需前期基础设施的投入。

下载和评估

在我们的网站www.accusoft.com/ig-silverlight.htm上下载产品或查看ImageGear for Silverlight功能的完整列表。

如有更多信息,请联系info@accusoft.com或support@accusoft.com。

关于 Accusoft Pegasus

Accusoft Pegasus成立于1991年,公司名称为Pegasus Imaging,总部位于佛罗里达州坦帕,是图像软件开发工具包(SDK)和图像查看器的最大供应商。图像技术解决方案包括条形码、压缩、DICOM、编辑、表单处理、OCR、PDF、扫描、视频和查看。技术适用于Microsoft .NET、ActiveX、Silverlight、AJAX、ASP.NET、Windows Workflow和Java环境。支持多个32位和64位平台,包括Windows、Windows Mobile、Linux、Sun Solaris、Mac OSX和IBM AIX。访问www.accusoft.com了解更多信息。

参考文献

使用ImageGear for Silverlight和Azure构建多页图像查看器 - CodeProject - 代码之家
© . All rights reserved.