Распознавание рукописного ввода в Windows Server 2008 R2
Windows Server 2008 R2 поддерживает распознавание рукописного ввода на стороне сервера. Распознавание на стороне сервера позволяет серверу распознавать содержимое из входных данных пером на веб-страницах. Это особенно полезно, когда пользователи в сети указывают термины, интерпретируемые с помощью пользовательского словаря. Например, если у вас есть медицинское приложение, которое запрашивало у серверной базы данных имена пациентов, эти имена можно было бы добавить в другую базу данных, на которую будут ссылаться перекрестные ссылки при выполнении поиска из рукописной формы Silverlight.
Настройка сервера для распознавания Server-Side
Чтобы настроить распознавание на стороне сервера, необходимо выполнить следующие действия.
- Установка служб рукописного ввода и рукописного ввода
- Установка поддержки веб-сервера (IIS) и сервера приложений
- Включение роли "Возможности рабочего стола"
- Запуск службы ввода планшетного компьютера
Установка служб рукописного ввода и рукописного ввода
Чтобы установить службы рукописного ввода и рукописного ввода, откройте диспетчер серверов, щелкнув значок диспетчера серверов на панели быстрого запуска. В меню Компоненты щелкните Добавить компоненты. Убедитесь, что выбрано поле Службы рукописного ввода и рукописного ввода проверка. На следующем рисунке показано диалоговое окно Выбор компонентов с выбранными службами рукописного ввода и рукописного ввода .
Диалоговое окно "Выбор компонентов" с выбранным полем рукописного ввода и рукописного ввода проверка
Поддержка установки для веб-сервера (IIS) и сервера приложений
Откройте диспетчер сервера так же, как и на первом шаге. Затем необходимо добавить роли веб-сервера (IIS) и сервера приложений. В меню Роли щелкните Добавить роли. Откроется мастер добавления ролей. Щелкните Далее. Убедитесь, что выбраны сервер приложений и веб-сервер (IIS). На следующем рисунке показано диалоговое окно Выбор ролей сервера с выбранными ролями веб-сервера (IIS) и сервера приложений .
Диалоговое окно "Выбор ролей сервера" с выбранными ролями веб-сервера (IIS) и сервера приложений
При выборе сервера приложений вам будет предложено установить платформу ASP.NET. Нажмите кнопку Добавить необходимые компоненты . После нажатия кнопки Далее откроется диалоговое окно обзора. Нажмите кнопку Далее. Теперь должно появиться диалоговое окно Выбор служб ролей . Убедитесь, что выбран веб-сервер (IIS). На следующем рисунке показано диалоговое окно Выбор служб ролей с включенным веб-сервером (IIS).
Диалоговое окно "Выбор служб ролей" с включенным веб-сервером (IIS)
Щелкните Далее. Откроется диалоговое окно "Обзор"; Нажмите кнопку Далее еще раз. Теперь вы увидите страницу с вариантами ролей для веб-сервера (IIS). Щелкните Далее. На следующей странице кнопка Установить станет активной. Нажмите кнопку Установить , и вы установите поддержку веб-сервера (IIS) и сервера приложений.
Включение роли "Возможности рабочего стола"
Чтобы включить возможности рабочего стола, нажмите кнопку Пуск, выберите пункт Администрирование, а затем диспетчер сервера. Щелкните Добавить службы , а затем выберите службу "Возможности рабочего стола ". На следующем рисунке показано диалоговое окно "Выбор компонентов " с установленным элементом "Возможности рабочего стола".
Диалоговое окно "Выбор компонентов" с выбранной службой возможностей рабочего стола
Нажмите кнопку Далее , чтобы установить возможности рабочего стола.
Запуск службы планшетов
После установки службы "Возможности рабочего стола" в меню Службы появится служба ввода для планшетного компьютера. Чтобы открыть меню Службы , нажмите кнопку Пуск, выберите пункт Администрирование, а затем — Службы. Чтобы запустить службу, щелкните правой кнопкой мыши службу ввода планшетного компьютера и выберите пункт Пуск. На следующем рисунке показано меню Службы с запущенной службой ввода планшетного компьютера.
Меню "Службы" с запущенной службой ввода планшетного компьютера
Выполнение распознавания Server-Side с помощью Silverlight
В этом разделе показано, как создать веб-приложение, которое использует Silverlight для записи рукописного ввода. Выполните следующие действия, чтобы запрограммировать распознаватель в Visual Studio 2008.
- Установите и обновите Visual Studio 2008, чтобы добавить поддержку Silverlight.
- Создайте проект Silverlight в Visual Studio 2008.
- Добавьте необходимые ссылки на службы в проект.
- Создайте службу WCF Silverlight для распознавания рукописного ввода.
- Добавьте ссылку на службу в клиентский проект.
- Добавьте класс InkCollector в проект InkRecognition.
- Удаление директив безопасного транспорта из конфигурации клиента
Установка и обновление Visual Studio 2008 для добавления поддержки Silverlight
Перед началом работы необходимо выполнить следующие действия на сервере Windows Server 2008 R2.
- Установите Visual Studio 2008.
- Установите Microsoft Visual Studio 2008 с пакетом обновления 1 (SP1).
- Установите пакет SDK Microsoft Silverlight 5.
После установки этих приложений и обновлений можно приступать к созданию веб-приложения распознавания на стороне сервера.
Создание веб-проекта Silverlight в Visual Studio 2008
В меню Файл выберите Новый проект. Выберите шаблон Приложение Silverlight из списка проектов Visual C#. Присвойте проекту имя InkRecognition и нажмите кнопку ОК. На следующем рисунке показан выбранный проект C# Silverlight с именем InkRecognition.
Выбран проект c# silverlight с именем inkrecognition
После нажатия кнопки ОК появится диалоговое окно с предложением добавить приложение Silverlight в проект. Выберите Добавить новый веб-проект ASP.NET в решение для размещения Silverlight и нажмите кнопку ОК. На следующем рисунке показано, как настроить пример проекта перед нажатием кнопки ОК.
Диалоговое окно с запросом на добавление приложения silverlight в проект
Добавление необходимых ссылок на службы в проект
Теперь у вас есть универсальный клиентский проект Silverlight (InkRecognition) с веб-проектом (InkRecognition.Web) в решении. Проект откроется с открытыми файлами Page.xaml и Default.aspx. Закройте эти окна и добавьте ссылки System.Runtime.Serialization и System.ServiceModel в проект InkRecognition, щелкнув правой кнопкой мыши папку references в проекте InkRecognition и выбрав команду Добавить ссылку. На следующем рисунке показано диалоговое окно с выбранными необходимыми ссылками.
Диалоговое окно "Добавление ссылок" с выбранными параметрами system.runtime.serialization и system.servicemodel
Затем необходимо добавить ссылки System.ServiceModel и Microsoft.Ink в проект InkRecognition.Web. Ссылка Microsoft.Ink не будет отображаться в ссылках .NET по умолчанию, поэтому найдите Microsoft.Ink.dll в папке Windows. Найдя библиотеку DLL, добавьте сборку в ссылки проекта: перейдите на вкладку Обзор , перейдите в папку, содержащую Microsoft.Ink.dll, выберите Microsoft.Ink.dll и нажмите кнопку ОК. На следующем рисунке показано решение проекта в Windows Обозреватель со всеми добавленными эталонными сборками.
Проект inkrecognition в проводнике Windows со всеми добавленными ссылочными сборками
Создание службы WCF Silverlight для распознавания рукописного ввода
Затем вы добавите в проект службу WCF для распознавания рукописного ввода. Щелкните правой кнопкой мыши проект InkRecognition.Web, выберите команду Добавить, а затем — Создать элемент. Выберите шаблон WCF Silverlight Service, измените имя на InkRecogitionService и нажмите кнопку Добавить. На следующем рисунке показано диалоговое окно Добавление нового элемента с выбранной службой WCF Silverlight.
Диалоговое окно "Добавление нового элемента" с выбранным и именем службы WCF silverlight
После добавления службы 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;
}
}
}
Добавление ссылки на службу в клиентский проект
Теперь, когда у вас есть служба WCF Silverlight для InkRecognition, вы будете использовать службу из клиентского приложения. Щелкните правой кнопкой мыши проект InkRecognition и выберите Добавить ссылку на службу. В появившемся диалоговом окне Добавление ссылки на службу выберите Обнаружение , чтобы обнаружить службы из текущего решения. InkRecognitionService появится в области Службы. Дважды щелкните InkRecognitionService на панели Службы, измените пространство имен на InkRecognitionServiceReference и нажмите кнопку ОК. На следующем рисунке показано диалоговое окно Добавление ссылки на службу с выбранным параметром InkRecognitionService и измененным пространством имен.
Диалоговое окно "Добавление ссылки на службу" с выбранным inkrecognitionservice и измененным пространством имен
Добавление класса InkCollector в проект InkRecognition
Щелкните правой кнопкой мыши проект InkRecognition, выберите команду Добавить, а затем — Создать элемент. В меню Visual C# выберите класс C#. Назовите класс InkCollector. На следующем рисунке показано диалоговое окно с выбранным и именованным классом C#.
Диалоговое окно "Добавление нового элемента" с выбранным классом c# и именем
После добавления класса InkCollector откроется определение класса. Замените код в сборщике рукописного ввода следующим кодом.
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, необходимо удалить все параметры безопасного транспорта из конфигурации службы, так как безопасные транспорты в настоящее время не поддерживаются в службах WCF Silverlight 2.0. В проекте InkRecognition обновите параметры безопасности в ServiceReferences.ClientConfig. Изменение XML-кода безопасности с
<security mode="None">
<transport>
<extendedProtectionPolicy policyEnforcement="WhenSupported" />
</transport>
</security>
значение
<security mode="None"/>
Теперь приложение должно запуститься. На следующем рисунке показано, как приложение выглядит в веб-page с некоторыми рукописными вводами, введенными в поле распознавания.
Приложение в веб-page с некоторым рукописным вводом в поле распознавания
На следующем рисунке показан распознанный текст в раскрывающемся списке Результат .
Приложение в awebpage с распознаваемым текстом в раскрывающемся списке результатов