共用方式為


Windows Server 2008 R2 中的手寫辨識

Windows Server 2008 R2 支援伺服器端手寫辨識。 伺服器端辨識可讓伺服器從網頁上的手寫筆輸入辨識內容。 這在網路上的使用者將會指定使用自訂字典解譯的詞彙時特別有用。 例如,如果您有一個醫療應用程式會查詢伺服器資料庫以取得病患名稱,則這些名稱可能會新增至另一個資料庫,而該資料庫會在從手寫 Silverlight 表單執行搜尋時進行交叉參考。

設定伺服器以進行Server-Side辨識

應遵循下列步驟來設定伺服器端辨識。

  • 安裝筆跡和手寫服務
  • 安裝 Web Server (IIS) 和應用程式伺服器的支援
  • 啟用桌面體驗角色
  • 啟動平板電腦輸入服務

安裝筆跡和手寫服務

若要安裝 Ink 和 Handwriting 服務,請按一下 [快速啟動] 匣中的伺服器管理員圖示,以開啟伺服器管理員。 從 [ 功能] 功能表中,按一下 [ 新增功能]。 請確定您選取 [ 筆跡和手寫服務 ] 核取方塊。 下圖顯示已選取[筆跡和手寫服務] 的 [選取功能] 對話方塊。

已選取筆跡和手寫服務核取方塊的 [選取功能] 對話方塊
已選取筆跡和手寫服務核取方塊的 [選取功能] 對話方塊

Web Server (IIS) 和應用程式伺服器的安裝支援

如同您在第一個步驟中所做的一樣開啟伺服器管理員。 接下來,您必須新增 Web 服務器 (IIS) 和應用程式伺服器角色。 從 [ 角色] 功能表中,按一下 [ 新增角色]。 [新增角色] 精靈隨即出現。 按一下 [下一步] 。 確定已選取 [應用程式伺服器 ] 和 [ Web 服務器] (IIS) 。 下圖顯示 [ 選取伺服器角色 ] 對話方塊,其中已選取 [Web 服務器 (IIS) 應用程式伺服器 角色]。

選取伺服器角色對話方塊,並選取 web 伺服器 (iis) 和應用程式伺服器角色
選取伺服器角色對話方塊,並選取 web 伺服器 (iis) 和應用程式伺服器角色

當您選取 [應用程式伺服器] 時,系統會要求您安裝 ASP.NET 架構。 按一下 [ 新增必要功能 ] 按鈕。 按一下 [ 下一步]之後,您會看到概觀對話方塊;按一下 [下一步]。 [ 選取角色服務 ] 對話方塊現在應該可供使用。 確定已選取 [Web 服務器 (IIS) ]。 下圖顯示 [ 選取角色服務 ] 對話方塊,其中已啟用 Web Server (IIS) 。

選取已啟用 web 伺服器 (iis) 的角色服務對話方塊
選取已啟用 web 伺服器 (iis) 的角色服務對話方塊

按一下 [下一步] 。 [概觀] 對話方塊隨即出現;再次按 [下一步 ]。 您現在會看到網頁伺服器 (IIS) 角色選項的頁面。 按一下 [下一步] 。 在下一個頁面上,[ 安裝 ] 按鈕將會變成作用中。 按一下 [安裝 ],您將安裝 Web Server (IIS) 和應用程式伺服器的支援。

啟用桌面體驗角色

若要啟用桌面體驗,請按一下 [開始],按一下 [系統管理工具],然後按一下[伺服器管理員]。 選取 [新增服務 ],然後選取 桌面體驗 服務。 下圖顯示已安裝桌面體驗專案的 [ 選取功能 ] 對話方塊。

已選取桌面體驗服務的 [選取功能] 對話方塊
已選取桌面體驗服務的 [選取功能] 對話方塊

[下一步] 安裝桌面體驗。

啟動平板電腦服務

安裝桌面體驗服務之後,平板電腦輸入服務會出現在 [ 服務 ] 功能表中。 若要存取 [服務 ] 功能表,請按一下 [ 開始],按一下 [ 系統管理工具],然後按一下 [ 服務]。 若要啟動服務,請以滑鼠右鍵按一下 [平板電腦輸入服務 ],然後按一下 [ 啟動]。 下圖顯示已啟動平板電腦輸入服務的 [服務 ] 功能表。

已啟動平板電腦輸入服務的服務功能表
已啟動平板電腦輸入服務的服務功能表

使用 Silverlight 執行Server-Side辨識

本節說明如何建立使用 Silverlight 來擷取手寫輸入的 Web 應用程式。 使用下列步驟在 Visual Studio 2008 中設計辨識器。

  • 安裝及更新 Visual Studio 2008 以新增 Silverlight 的支援。
  • 在 Visual Studio 2008 中建立新的 Silverlight 專案。
  • 將必要的服務參考新增至您的專案。
  • 建立 Silverlight WCF 服務以進行筆跡辨識。
  • 將服務參考新增至您的用戶端專案。
  • 將 InkCollector 類別新增至 InkRecognition 專案。
  • 從用戶端設定中移除安全傳輸指示詞

安裝及更新 Visual Studio 2008 以新增 Silverlight 支援

開始之前,您必須在 Windows Server 2008 R2 伺服器上執行下列步驟。

安裝這些應用程式和更新之後,您就可以開始建立伺服器端辨識 Web 應用程式。

在 Visual Studio 2008 中建立新的 Silverlight Web 專案

從 [檔案] 功能表,按一下 [新增專案]。 從 Visual C# 專案清單中選取 Silverlight 應用程式範本。 將專案命名為 InkRecognition,然後按一下 [ 確定]。 下圖顯示已選取並命名為 InkRecognition 的 C# Silverlight 專案。

已選取 c# silverlight 專案,名稱為 inkrecognition
已選取 c# silverlight 專案,名稱為 inkrecognition

按一下 [ 確定] 之後,對話方塊會提示您將 Silverlight 應用程式新增至專案。 選取 [將新的 ASP.NET Web 專案新增至方案以裝載 Silverlight ,然後按一下 [ 確定]。 下圖顯示如何在按一下 [ 確定] 之前設定範例專案。

對話方塊,提示將 silverlight 應用程式新增至專案
對話方塊,提示將 silverlight 應用程式新增至專案

將必要的服務參考新增至您的專案

現在,您已將一般 Silverlight 用戶端專案 (InkRecognition) ,並將 Web 專案 (InkRecognition.Web) 在您的方案中設定。 專案會開啟,並開啟 Page.xaml 和 Default.aspx。 關閉這些視窗,然後以滑鼠右鍵按一下 InkRecognition 專案中的 references 資料夾,然後選取 [ 新增參考],將 System.Runtime.Serialization 和 System.ServiceModel 參考新增至 InkRecognition 專案。 下圖顯示已選取必要參考的對話方塊。

已選取 system.runtime.serialization 和 system.servicemodel 的 [新增參考] 對話方塊
已選取 system.runtime.serialization 和 system.servicemodel 的 [新增參考] 對話方塊

接下來,您必須將 System.ServiceModel 和 Microsoft.Ink 參考新增至 InkRecognition.Web 專案。 Microsoft.Ink 參考預設不會出現在 .NET 參考中,因此請在 Windows 資料夾中搜尋Microsoft.Ink.dll。 找到 DLL 之後,請將元件新增至專案參考:選取 [ 流覽 ] 索引標籤、變更包含Microsoft.Ink.dll的資料夾、選取 [Microsoft.Ink.dll],然後按一下 [ 確定]。 下圖顯示 Windows 檔案總管中已新增所有參考元件的專案方案。

Windows 檔案總管中已新增所有參考元件的 inkrecognition 專案
Windows 檔案總管中已新增所有參考元件的 inkrecognition 專案

建立適用于筆跡辨識的 Silverlight WCF 服務

接下來,您會將用於筆跡辨識的 WCF 服務新增至專案。 以滑鼠右鍵按一下 InkRecognition.Web 專案,按一下 [ 新增],然後按一下 [ 新增專案]。 選取 WCF Silverlight 服務範本,將名稱變更為 InkRecogitionService,然後按一下 [ 新增]。 下圖顯示 [ 新增專案 ] 對話方塊,其中已選取 Silverlight WCF 服務並命名。

已選取 silverlight wcf 服務並命名為 [新增專案] 對話方塊
已選取 silverlight wcf 服務並命名為 [新增專案] 對話方塊

新增 WCF Silverlight 服務之後,InkRecognitionService.cs 後置的服務程式代碼將會開啟。 以下列程式碼取代服務程式代碼。

using System;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Collections.Generic;
using System.Text;
using Microsoft.Ink;

namespace InkRecognition.Web
{
    [ServiceContract(Namespace = "")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class InkRecognitionService
    {
        [OperationContract]
        public string[] Recognize(int[][] packets)
        {
            // Deserialize ink.
            Ink ink = new Ink();
            Tablet tablet = new Tablets().DefaultTablet;
            TabletPropertyDescriptionCollection desc = new TabletPropertyDescriptionCollection();
            desc.Add(new TabletPropertyDescription(PacketProperty.X, tablet.GetPropertyMetrics(PacketProperty.X)));
            desc.Add(new TabletPropertyDescription(PacketProperty.Y, tablet.GetPropertyMetrics(PacketProperty.Y)));
            int numOfStrokes = packets.GetUpperBound(0) + 1;
            for (int i = 0; i < numOfStrokes; i++)
            {
                ink.CreateStroke(packets[i], desc);
            }

            // Recognize ink.
            RecognitionStatus recoStatus;
            RecognizerContext recoContext = new RecognizerContext();
            recoContext.RecognitionFlags = RecognitionModes.LineMode | RecognitionModes.TopInkBreaksOnly;
            recoContext.Strokes = ink.Strokes;
            RecognitionResult recoResult = recoContext.Recognize(out recoStatus);
            RecognitionAlternates alternates = recoResult.GetAlternatesFromSelection();
            string[] results = new string[alternates.Count];
            for (int i = 0; i < alternates.Count; i++)
            {
                results[i] = alternates[i].ToString();
            }

            // Send results to client.
            return results;
        }
    }
}

將服務參考新增至您的用戶端專案

既然您有適用于 InkRecognition 的 Silverlight WCF 服務,您將會從用戶端應用程式取用服務。 以滑鼠右鍵按一下 InkRecognition 專案,然後選取 [ 新增服務參考]。 從出現的 [ 新增服務參考] 對話方塊中,選取 [ 探索 ] 以從目前的解決方案探索服務。 InkRecognitionService 會出現在 [服務] 窗格中。 按兩下 [服務] 窗格中的 InkRecognitionService,將命名空間變更為 InkRecognitionServiceReference,然後按一下 [ 確定]。 下圖顯示已選取 InkRecognitionService 且命名空間已變更的 [新增服務參考 ] 對話方塊。

已選取 inkrecognitionservice 且命名空間已變更的 [新增服務參考] 對話方塊
已選取 inkrecognitionservice 且命名空間已變更的 [新增服務參考] 對話方塊

將 InkCollector 類別新增至 InkRecognition 專案

以滑鼠右鍵按一下 InkRecognition 專案,按一下 [ 新增],然後按一下 [ 新增專案]。 從 [Visual C#] 功能表中,選取 [C# 類別]。 將類別命名為 InkCollector。 下圖顯示已選取並命名 C# 類別的對話方塊。

已選取並命名 c# 類別的新增專案對話方塊
已選取並命名 c# 類別的新增專案對話方塊

新增 InkCollector 類別之後,類別定義將會開啟。 以下列程式碼取代 Ink Collector 中的程式碼。

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace InkRecognition
{
    public class InkCollector : IDisposable
    {
        public InkCollector(InkPresenter presenter)
        {
            _presenter = presenter;
            _presenter.Cursor = Cursors.Stylus;
            _presenter.MouseLeftButtonDown += new MouseButtonEventHandler(_presenter_MouseLeftButtonDown);
            _presenter.MouseMove += new MouseEventHandler(_presenter_MouseMove);
            _presenter.MouseLeftButtonUp += new MouseButtonEventHandler(_presenter_MouseLeftButtonUp);
        }

        void _presenter_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            _presenter.CaptureMouse();
            if (!e.StylusDevice.Inverted)
            {
                _presenter.Cursor = Cursors.Stylus;
                _stroke = new Stroke(e.StylusDevice.GetStylusPoints(_presenter));
                _stroke.DrawingAttributes = _drawingAttributes;
                _presenter.Strokes.Add(_stroke);
            }
            else
            {
                _presenter.Cursor = Cursors.Eraser;
                _erasePoints = e.StylusDevice.GetStylusPoints(_presenter);
            }
        }

        void _presenter_MouseMove(object sender, MouseEventArgs e)
        {
            if (!e.StylusDevice.Inverted)
            {
                _presenter.Cursor = Cursors.Stylus;
            }
            else
            {
                _presenter.Cursor = Cursors.Eraser;
            }
            if (_stroke != null)
            {
                _stroke.StylusPoints.Add(e.StylusDevice.GetStylusPoints(_presenter));
            }
            else if (_erasePoints != null)
            {
                _erasePoints.Add(e.StylusDevice.GetStylusPoints(_presenter));
                StrokeCollection hitStrokes = _presenter.Strokes.HitTest(_erasePoints);
                if (hitStrokes.Count > 0)
                {
                    foreach (Stroke hitStroke in hitStrokes)
                    {
                        _presenter.Strokes.Remove(hitStroke);
                    }
                }
            }
        }

        void _presenter_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            _presenter.ReleaseMouseCapture();
            if (_stroke != null)
            {
                _stroke.StylusPoints.Add(e.StylusDevice.GetStylusPoints(_presenter));
            }
            _stroke = null;
            _erasePoints = null;
        }

        public DrawingAttributes DefaultDrawingAttributes
        {
            get { return _drawingAttributes; }
            set { _drawingAttributes = value; }
        }

        public void Dispose()
        {
            _presenter.MouseLeftButtonDown -= new MouseButtonEventHandler(_presenter_MouseLeftButtonDown);
            _presenter.MouseMove -= new MouseEventHandler(_presenter_MouseMove);
            _presenter.MouseLeftButtonUp -= new MouseButtonEventHandler(_presenter_MouseLeftButtonUp);
            _presenter = null;
        }

        private InkPresenter _presenter = null;
        private Stroke _stroke = null;
        private StylusPointCollection _erasePoints = null;
        private DrawingAttributes _drawingAttributes = new DrawingAttributes();
    }
}

更新預設頁面的 XAML,並新增手寫辨識的程式碼後置

既然您已擁有收集筆跡的類別,您必須使用下列 XAML 更新 page.xaml 中的 XAML。 下列程式碼會將黃色漸層新增至輸入區域、InkCanvas 控制項,以及將觸發辨識的按鈕。

<UserControl x:Class="InkRecognition.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Border Margin="5" Grid.Row="0" BorderThickness="4" BorderBrush="Black" CornerRadius="5" Height="200">
            <Grid>
                <InkPresenter x:Name="inkCanvas">
                    <InkPresenter.Background>
                        <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                            <GradientStop Offset="0" Color="Yellow"/>
                            <GradientStop Offset="1" Color="LightYellow"/>
                        </LinearGradientBrush>
                    </InkPresenter.Background>
                </InkPresenter>
                <Button Grid.Row="0" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="10" Content="Recognize" Click="RecoButton_Click"/>
            </Grid>
        </Border>
        <Grid Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0" FontSize="28" Text="Result: "/>
            <ComboBox x:Name="results" Grid.Column="1" FontSize="28"/>
        </Grid>
    </Grid>
</UserControl>

以下列程式碼取代 Page.xaml.cs 頁面後置程式碼,以新增 [辨識 ] 按鈕的事件處理常式。

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using InkRecognition.InkRecognitionServiceReference;

namespace InkRecognition
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();
            inkCol = new InkCollector(inkCanvas);
            recoClient = new InkRecognitionServiceClient();
            recoClient.RecognizeCompleted += new EventHandler<RecognizeCompletedEventArgs>(recoClient_RecognizeCompleted);
        }

        private void RecoButton_Click(object sender, RoutedEventArgs e)
        {
            // Serialize the ink into an array on ints.
            ObservableCollection<ObservableCollection<int>> packets = new ObservableCollection<ObservableCollection<int>>();
            double pixelToHimetricMultiplier = 2540d / 96d;

            foreach (Stroke stroke in inkCanvas.Strokes)
            {
                packets.Add(new ObservableCollection<int>());
                int index = inkCanvas.Strokes.IndexOf(stroke);
                for (int i = 0; i < stroke.StylusPoints.Count; i += 2)
                {
                    packets[index].Add(Convert.ToInt32(stroke.StylusPoints[i].X * pixelToHimetricMultiplier));
                    packets[index].Add(Convert.ToInt32(stroke.StylusPoints[i].Y * pixelToHimetricMultiplier));
                }
            }

            // Call the Web service.
            recoClient.RecognizeAsync(packets);
        }

        void recoClient_RecognizeCompleted(object sender, RecognizeCompletedEventArgs e)
        {
            // We have received results from the server, now display them.
            results.ItemsSource = e.Result;
            UpdateLayout();
            results.SelectedIndex = 0;
            inkCanvas.Strokes.Clear();
        }

        private InkRecognitionServiceClient recoClient = null;
        private InkCollector inkCol = null;
    }
}

從用戶端組態移除安全傳輸指示詞

您必須先從服務設定中移除所有安全傳輸選項,才能取用 WCF 服務,因為 Silverlight 2.0 WCF 服務目前不支援安全傳輸。 從 InkRecognition 專案,更新 ServiceReferences.ClientConfig 中的安全性設定。 從變更安全性 XML

          <security mode="None">
            <transport>
              <extendedProtectionPolicy policyEnforcement="WhenSupported" />
            </transport>
          </security>

to

       <security mode="None"/>

現在,您的應用程式應該執行。 下圖顯示應用程式在 awebpage 內的外觀,以及輸入到辨識方塊中的一些手寫。

awebpage 內的應用程式,其中已輸入一些手寫到辨識方塊中
awebpage 內的應用程式,其中已輸入一些手寫到辨識方塊中

下圖顯示 [ 結果 ] 下拉式清單中的辨識文字。

應用程式在 awebpage 內,在結果下拉式清單中具有辨識的文字
應用程式在 awebpage 內,在結果下拉式清單中具有辨識的文字