Handschrifterkennung in Windows Server 2008 R2
Windows Server 2008 R2 unterstützt die serverseitige Handschrifterkennung. Mithilfe der serverseitigen Erkennung kann ein Server Inhalte aus Stifteingaben auf Webseiten erkennen. Dies ist besonders nützlich, wenn Benutzer in einem Netzwerk Begriffe angeben, die mithilfe eines benutzerdefinierten Wörterbuchs interpretiert werden. Wenn Sie beispielsweise über eine medizinische Anwendung verfügen, die eine Serverdatenbank nach Patientennamen abgefragt hat, können diese Namen einer anderen Datenbank hinzugefügt werden, auf die querverweist wird, wenn Suchvorgänge aus einem handschriftlichen Silverlight-Formular ausgeführt werden.
Einrichten ihres Servers für die Server-Side Erkennung
Die folgenden Schritte sollten ausgeführt werden, um die serverseitige Erkennung einzurichten.
- Installieren von Freihand- und Handschriftdienste
- Installieren der Unterstützung für Webserver (IIS) und Anwendungsserver
- Aktivieren der Desktopdarstellungsrolle
- Starten des Tablet PC-Eingabediensts
Installieren von Freihand- und Handschriftdienste
Um Freihand- und Handschriftdienste zu installieren, öffnen Sie den Server-Manager, indem Sie in der Schnellstart Taskleiste auf das Server-Manager-Symbol klicken. Klicken Sie im Menü Features auf Features hinzufügen. Stellen Sie sicher, dass Sie das Kontrollkästchen Freihand- und Handschriftdienste aktivieren. Die folgende Abbildung zeigt das Dialogfeld Features auswählen mit ausgewählter Freihand- und Handschriftdienste.

Dialogfeld "Features auswählen" mit aktivierten Freihand- und Handschriftdiensten
Installationsunterstützung für Webserver (IIS) und Anwendungsserver
Öffnen Sie den Server-Manager wie im ersten Schritt. Als Nächstes müssen Sie die Rollen Webserver (IIS) und Anwendungsserver hinzufügen. Klicken Sie im Menü Rollen auf Rollen hinzufügen. Der Assistent zum Hinzufügen von Rollen wird angezeigt. Klicken Sie auf Weiter. Stellen Sie sicher, dass Anwendungsserver und Webserver (IIS) ausgewählt sind. Die folgende Abbildung zeigt das Dialogfeld Serverrollen auswählen mit den ausgewählten Rollen Webserver (IIS) und Anwendungsserver.

Dialogfeld "Serverrollen auswählen" mit ausgewählten Webserver- und Anwendungsserverrollen
Wenn Sie Anwendungsserver auswählen, werden Sie aufgefordert, das ASP.NET Framework zu installieren. Klicken Sie auf die Schaltfläche Erforderliche Features hinzufügen. Nachdem Sie auf Weiter geklickt haben, wird ein Übersichtsdialogfeld angezeigt. Klicken Sie auf Weiter. Das Dialogfeld Rollendienste auswählen sollte jetzt verfügbar sein. Stellen Sie sicher, dass Webserver (IIS) ausgewählt ist. Die folgende Abbildung zeigt das Dialogfeld Rollendienste auswählen mit aktiviertem Webserver (IIS).

Dialogfeld "Rollendienste auswählen" mit aktiviertem Webserver (IIS)
Klicken Sie auf Weiter. Ein Übersichtsdialogfeld wird angezeigt. Klicken Sie erneut auf Weiter. Ihnen wird nun eine Seite mit Optionen für Rollen für Webserver (IIS) angezeigt. Klicken Sie auf Weiter. Auf der nächsten Seite wird die Schaltfläche Installieren aktiviert. Klicken Sie auf Installieren, und Sie installieren die Unterstützung für Webserver (IIS) und Anwendungsserver.
Aktivieren der Desktopdarstellungsrolle
Um die Desktopdarstellung zu aktivieren, klicken Sie auf Start, auf Verwaltung und dann auf Server-Manager. Wählen Sie Dienste hinzufügen und dann den Dienst Desktopdarstellung aus. Die folgende Abbildung zeigt das Dialogfeld Features auswählen mit installierter Desktopdarstellung.

Dialogfeld "Features auswählen" mit ausgewähltem Desktopdarstellungsdienst
Klicken Sie auf Weiter, um die Desktopdarstellung zu installieren.
Starten des Tablet-Diensts
Nachdem Sie den Desktopdarstellungsdienst installiert haben, wird der Tablet PC-Eingabedienst im Menü Dienste angezeigt. Um auf das Menü Dienste zuzugreifen, klicken Sie auf Start, auf Verwaltung und dann auf Dienste. Klicken Sie zum Starten des Diensts mit der rechten Maustaste auf Tablet PC Input Service , und klicken Sie dann auf Starten. Die folgende Abbildung zeigt das Menü Dienste, in dem der Tablet PC-Eingabedienst gestartet wurde.

Menü "Dienste", in dem der Tablet-PC-Eingabedienst gestartet wurde
Durchführen Server-Side Erkennung mit Silverlight
In diesem Abschnitt wird gezeigt, wie Sie eine Webanwendung erstellen, die Silverlight verwendet, um Handschrifteingaben zu erfassen. Verwenden Sie die folgenden Schritte, um die Erkennung in Visual Studio 2008 zu programmieren.
- Installieren und aktualisieren Sie Visual Studio 2008, um Unterstützung für Silverlight hinzuzufügen.
- Erstellen Sie in Visual Studio 2008 ein neues Silverlight-Projekt.
- Fügen Sie ihrem Projekt die erforderlichen Dienstverweise hinzu.
- Erstellen Sie einen Silverlight-WCF-Dienst für die Ink-Erkennung.
- Fügen Sie den Dienstverweis ihrem Clientprojekt hinzu.
- Fügen Sie die InkCollector-Klasse dem InkRecognition-Projekt hinzu.
- Entfernen sicherer Transportdirektiven aus der Clientkonfiguration
Installieren und Aktualisieren Visual Studio 2008 zum Hinzufügen von Unterstützung für Silverlight
Bevor Sie beginnen, müssen Sie die folgenden Schritte auf dem server Windows Server 2008 R2 ausführen.
- Installieren Sie Visual Studio 2008.
- Installieren Sie Microsoft Visual Studio 2008 Service Pack 1.
- Installieren Sie das Microsoft Silverlight 5 SDK.
Nachdem Sie diese Anwendungen und Updates installiert haben, können Sie ihre serverseitige Erkennungswebanwendung erstellen.
Erstellen eines neuen Silverlight-Web-Project in Visual Studio 2008
Klicken Sie im Menü Datei auf Neues Projekt. Wählen Sie in der Visual C-Projektliste die Silverlight-Anwendungsvorlage # aus. Nennen Sie Ihr Projekt InkRecognition, und klicken Sie auf OK. Die folgende Abbildung zeigt das ausgewählte C # Silverlight-Projekt mit dem Namen InkRecognition.

Ausgewähltes c # silverlight-Projekt mit dem Namen inkrecognition
Nachdem Sie auf OK geklickt haben, werden Sie in einem Dialogfeld aufgefordert, Ihrem Projekt eine Silverlight-Anwendung hinzuzufügen. Wählen Sie Add a new ASP.NET Web project to the solution to host Silverlight (Neue ASP.NET Webprojekt zur Projektmappe zum Hosten von Silverlight hinzufügen) aus, und klicken Sie auf OK. Die folgende Abbildung zeigt, wie Sie das Beispielprojekt einrichten, bevor Sie auf OK klicken.

Dialogfeld mit Aufforderung zum Hinzufügen einer Silverlight-Anwendung zu einem Projekt
Fügen Sie ihrem Project die erforderlichen Dienstverweise hinzu.
Nun haben Sie Ihr generisches Silverlight-Clientprojekt (InkRecognition) mit einem Webprojekt (InkRecognition.Web) in Ihrer Projektmappe eingerichtet. Das Projekt wird mit Page.xaml und Default.aspx geöffnet. Schließen Sie diese Fenster, und fügen Sie die Verweise System.Runtime.Serialization und System.ServiceModel zum InkRecognition-Projekt hinzu, indem Sie mit der rechten Maustaste auf den Ordner verweise im InkRecognition-Projekt klicken und Verweis hinzufügen auswählen. Die folgende Abbildung zeigt das Dialogfeld mit den ausgewählten erforderlichen Verweisen.

Dialogfeld "Verweise hinzufügen", in dem "system.runtime.serialization" und "system.servicemodel" ausgewählt sind
Als Nächstes müssen Sie dem Projekt InkRecognition.Web die Verweise system.ServiceModel und Microsoft.Ink hinzufügen. Der Microsoft.Ink-Verweis wird standardmäßig nicht in den .NET-Verweisen angezeigt. Suchen Sie daher in Ihrem Windows Ordner nach Microsoft.Ink.dll. Nachdem Sie die DLL gefunden haben, fügen Sie die Assembly den Projektverweisen hinzu: Wählen Sie die Registerkarte Durchsuchen aus, wechseln Sie zu dem Ordner, der Microsoft.Ink.dll enthält, wählen Sie Microsoft.Ink.dll aus, und klicken Sie dann auf OK. Die folgende Abbildung zeigt die Projektmappe des Projekts in Windows Explorer mit allen hinzugefügten Verweisassemblys.

Inkrecognition-Projekt im Windows-Explorer mit allen hinzugefügten Verweisassemblys
Erstellen eines Silverlight-WCF-Diensts für die Ink-Erkennung
Als Nächstes fügen Sie dem Projekt einen WCF-Dienst für die Ink-Erkennung hinzu. Klicken Sie mit der rechten Maustaste auf das Projekt InkRecognition.Web, klicken Sie auf Hinzufügen, und klicken Sie dann auf Neues Element. Wählen Sie die WCF Silverlight-Dienstvorlage aus, ändern Sie den Namen in InkRecogitionService, und klicken Sie dann auf Hinzufügen. Die folgende Abbildung zeigt das Dialogfeld Neues Element hinzufügen, in dem der Silverlight-WCF-Dienst ausgewählt und benannt wurde.

Dialogfeld "Neues Element hinzufügen" mit ausgewähltem und benannten Silverlight-Wcf-Dienst
Nachdem Sie den WCF Silverlight-Dienst hinzugefügt haben, wird der DienstcodeBehind InkRecognitionService.cs geöffnet. Ersetzen Sie den Dienstcode durch den folgenden Code.
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;
}
}
}
Hinzufügen des Dienstverweiss zu Ihrem Client Project
Nachdem Sie nun über Ihren Silverlight-WCF-Dienst für InkRecognition verfügen, nutzen Sie den Dienst aus Ihrer Clientanwendung. Klicken Sie mit der rechten Maustaste auf das InkRecognition-Projekt, und wählen Sie Dienstverweis hinzufügen aus. Wählen Sie im angezeigten Dialogfeld Dienstverweis hinzufügen die Option Ermitteln aus, um Dienste aus der aktuellen Projektmappe zu ermitteln. InkRecognitionService wird im Bereich Dienste angezeigt. Doppelklicken Sie im Bereich Dienste auf InkRecognitionService, ändern Sie den Namespace in InkRecognitionServiceReference, und klicken Sie dann auf OK. Die folgende Abbildung zeigt das Dialogfeld Dienstverweis hinzufügen, in dem InkRecognitionService ausgewählt und der Namespace geändert wurde.

Dialogfeld "Dienstverweis hinzufügen" mit ausgewählter Option "inkrecognitionservice" und geänderten Namespaces
Fügen Sie die InkCollector-Klasse der InkRecognition-Project
Klicken Sie mit der rechten Maustaste auf das InkRecognition-Projekt, klicken Sie auf Hinzufügen, und klicken Sie dann auf Neues Element. Wählen Sie im Visual # C-Menü die Option # C-Klasse aus. Nennen Sie die Klasse InkCollector. Die folgende Abbildung zeigt das Dialogfeld mit # ausgewählter und benannter C-Klasse.

Dialogfeld "Neues Element hinzufügen" mit # ausgewählter und benannter C-Klasse
Nachdem Sie die InkCollector-Klasse hinzugefügt haben, wird die Klassendefinition geöffnet. Ersetzen Sie den Code im Ink Collector durch den folgenden Code.
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();
}
}
Aktualisieren des XAML-Codes für die Standardseite und Hinzufügen eines Code Behind für die Handschrifterkennung
Nachdem Sie nun über eine Klasse verfügen, die Ink sammelt, müssen Sie den XAML-Code in page.xaml mit dem folgenden XAML-Code aktualisieren. Der folgende Code fügt dem Eingabebereich einen gelben Farbverlauf, ein InkCanvas-Steuerelement und eine Schaltfläche hinzu, die die Erkennung auslöst.
<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>
Ersetzen Sie die CodeBehind-Seite Page.xaml.cs durch den folgenden Code, der einen Ereignishandler für die Schaltfläche Erkennen hinzufüge.
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;
}
}
Entfernen sicherer Transportdirektiven aus der Clientkonfiguration
Bevor Sie den WCF-Dienst nutzen können, müssen Sie alle sicheren Transportoptionen aus der Dienstkonfiguration entfernen, da sichere Transporte in Silverlight 2.0 WCF-Diensten derzeit nicht unterstützt werden. Aktualisieren Sie im Projekt InkRecognition die Sicherheitseinstellungen in ServiceReferences.ClientConfig. Ändern der Sicherheits-XML von
<security mode="None">
<transport>
<extendedProtectionPolicy policyEnforcement="WhenSupported" />
</transport>
</security>
zu
<security mode="None"/>
Nun sollte Ihre Anwendung ausgeführt werden. Die folgende Abbildung zeigt, wie die Anwendung auf einerWebseite aussieht, in der eine Handschrift in das Erkennungsfeld eingegeben wurde.

Anwendung in einerWebseite mit handschriftlichem Text, der in das Erkennungsfeld eingegeben wurde
Die folgende Abbildung zeigt den erkannten Text in der Dropdownliste Ergebnis.

Anwendung in einerWebseite mit erkanntem Text in der Ergebnis-Dropdownliste