Reconocimiento de escritura a mano en Windows Server 2008 R2
Windows Server 2008 R2 admite el reconocimiento de escritura a mano del lado servidor. El reconocimiento del lado servidor permite a un servidor reconocer el contenido de la entrada manuscrita en páginas web. Esto resulta especialmente útil cuando los usuarios de una red especificarán términos que se interpretan mediante un diccionario personalizado. Por ejemplo, si tuviera una aplicación médica que consultara una base de datos de servidor para nombres de pacientes, esos nombres podrían agregarse a otra base de datos a la que se haría referencia cruzada al realizar búsquedas desde un formulario de Silverlight manuscrito.
Configurar el servidor para Server-Side Recognition
Se deben seguir los pasos siguientes para configurar el reconocimiento del lado servidor.
- Instalar servicios de escritura a mano y de entrada de lápiz
- Instalar compatibilidad con el servidor web (IIS) y el servidor de aplicaciones
- Habilitación del rol de experiencia de escritorio
- Iniciar el servicio de entrada de pc tableta
Instalar servicios de escritura a mano y de entrada de lápiz
Para instalar los servicios ink y handwriting, abra el administrador del servidor haciendo clic en el icono administrador del servidor desde la bandeja inicio rápido. En el menú Características , haga clic en Agregar características. Asegúrese de activar la casilla Ink and Handwriting Services (Servicios de tinta y escritura a mano ). En la imagen siguiente se muestra el cuadro de diálogo Seleccionar características con Servicios de escritura a mano y ink seleccionados.
Cuadro de diálogo Seleccionar características con servicios de escritura a mano y de entrada manuscrita activada
Compatibilidad con la instalación para el servidor web (IIS) y el servidor de aplicaciones
Abra el administrador del servidor como hizo para el primer paso. A continuación, deberá agregar los roles Servidor web (IIS) y Servidor de aplicaciones. En el menú Roles , haga clic en Agregar roles. Aparece el Asistente para agregar roles. Haga clic en Next. Asegúrese de que el servidor de aplicaciones y el servidor web (IIS) están seleccionados. En la imagen siguiente se muestra el cuadro de diálogo Seleccionar roles de servidor con los roles Servidor web (IIS) y Servidor de aplicaciones seleccionados.
Cuadro de diálogo Seleccionar roles de servidor con roles de servidor web (iis) y de servidor de aplicaciones seleccionados
Al seleccionar Servidor de aplicaciones, se le pedirá que instale el marco de ASP.NET. Haga clic en el botón Agregar las características necesarias . Después de hacer clic en Siguiente, aparecerá un cuadro de diálogo de información general; Haga clic en Siguiente. El cuadro de diálogo Seleccionar servicios de rol ahora debe estar disponible. Asegúrese de que servidor web (IIS) está seleccionado. En la imagen siguiente se muestra el cuadro de diálogo Seleccionar servicios de rol con servidor web (IIS) habilitado.
Cuadro de diálogo Seleccionar servicios de rol con el servidor web (iis) habilitado
Haga clic en Next. Aparece un cuadro de diálogo de información general; Vuelva a hacer clic en Siguiente . Ahora se le presentará una página que ofrece opciones para roles para el servidor web (IIS). Haga clic en Next. En la página siguiente, el botón Instalar se activará. Haga clic en Instalar y instalará la compatibilidad con el servidor web (IIS) y el servidor de aplicaciones.
Habilitación del rol de experiencia de escritorio
Para habilitar la experiencia de escritorio, haga clic en Inicio, herramientas administrativas y, a continuación, haga clic en Administrador del servidor. Seleccione Agregar servicios y, a continuación, seleccione el servicio Experiencia de escritorio . En la imagen siguiente se muestra el cuadro de diálogo Seleccionar características con el elemento Experiencia de escritorio instalado.
Cuadro de diálogo Seleccionar características con el servicio de experiencia de escritorio seleccionado
Haga clic en Siguiente para instalar la experiencia de escritorio.
Iniciar el servicio de tableta
Después de instalar el servicio Experiencia de escritorio, el servicio De entrada de PC tableta aparecerá en el menú Servicios . Para acceder al menú Servicios , haga clic en Inicio, Herramientas administrativas y, a continuación, haga clic en Servicios. Para iniciar el servicio, haga clic con el botón derecho en Servicio de entrada de pc tableta y, a continuación, haga clic en Iniciar. En la imagen siguiente se muestra el menú Servicios con el servicio de entrada de pc tableta iniciado.
Menú servicios con el servicio de entrada de pc tableta iniciado
Realización del reconocimiento de Server-Side mediante Silverlight
En esta sección se muestra cómo crear una aplicación web que usa Silverlight para capturar la entrada de escritura a mano. Siga estos pasos para programar el reconocedor en Visual Studio 2008.
- Instale y actualice Visual Studio 2008 para agregar compatibilidad con Silverlight.
- Cree un proyecto de Silverlight en Visual Studio 2008.
- Agregue las referencias de servicio necesarias al proyecto.
- Cree un servicio WCF de Silverlight para el reconocimiento de entrada de lápiz.
- Agregue la referencia de servicio al proyecto cliente.
- Agregue la clase InkCollector al proyecto InkRecognition.
- Eliminación de directivas de transporte seguras de la configuración del cliente
Instalación y actualización de Visual Studio 2008 para agregar compatibilidad con Silverlight
Antes de comenzar, debe realizar los pasos siguientes en el servidor de Windows Server 2008 R2.
- Instale Visual Studio 2008.
- Instale Microsoft Visual Studio 2008 Service Pack 1.
- Instale el SDK de Microsoft Silverlight 5.
Después de instalar estas aplicaciones y actualizaciones, está listo para crear la aplicación web de reconocimiento del lado servidor.
Creación de un nuevo proyecto web de Silverlight en Visual Studio 2008
En el menú Archivo, haga clic en Nuevo proyecto. Seleccione la plantilla Aplicación de Silverlight en la lista de proyectos de Visual C#. Asigne al proyecto el nombre InkRecognition y haga clic en Aceptar. En la imagen siguiente se muestra el proyecto de Silverlight de C# seleccionado y denominado InkRecognition.
Proyecto de silverlight de c# seleccionado, con el nombre inkrecognition
Después de hacer clic en Aceptar, un cuadro de diálogo le pedirá que agregue una aplicación de Silverlight al proyecto. Seleccione Agregar un nuevo proyecto web de ASP.NET a la solución para hospedar Silverlight y haga clic en Aceptar. En la imagen siguiente se muestra cómo configurar el proyecto de ejemplo antes de hacer clic en Aceptar.
Cuadro de diálogo con solicitud para agregar una aplicación silverlight a un proyecto
Agregar las referencias de servicio necesarias al proyecto
Ahora tiene el proyecto de cliente genérico de Silverlight (InkRecognition) con un proyecto web (InkRecognition.Web) configurado en la solución. El proyecto se abrirá con Page.xaml y Default.aspx abiertos. Cierre estas ventanas y agregue las referencias System.Runtime.Serialization y System.ServiceModel al proyecto InkRecognition haciendo clic con el botón derecho en la carpeta de referencias del proyecto InkRecognition y seleccionando Agregar referencia. En la imagen siguiente se muestra el cuadro de diálogo con las referencias necesarias seleccionadas.
Cuadro de diálogo Agregar referencias con system.runtime.serialization y system.servicemodel seleccionados
A continuación, debe agregar las referencias System.ServiceModel y Microsoft.Ink al proyecto InkRecognition.Web. La referencia de Microsoft.Ink no aparecerá en las referencias de .NET de forma predeterminada, por lo que busque la carpeta windows para Microsoft.Ink.dll. Una vez que haya localizado el archivo DLL, agregue el ensamblado a las referencias del proyecto: seleccione la pestaña Examinar , cambie a la carpeta que contiene Microsoft.Ink.dll, seleccione Microsoft.Ink.dll y, a continuación, haga clic en Aceptar. En la imagen siguiente se muestra la solución del proyecto en el Explorador de Windows con todos los ensamblados de referencia agregados.
Proyecto inkrecognition en el Explorador de Windows con todos los ensamblados de referencia agregados
Creación de un servicio WCF de Silverlight para el reconocimiento de entrada de lápiz
A continuación, agregará un servicio WCF para el reconocimiento de entrada de lápiz al proyecto. Haga clic con el botón derecho en el proyecto InkRecognition.Web, haga clic en Agregar y, a continuación, haga clic en Nuevo elemento. Seleccione la plantilla Servicio de Silverlight de WCF, cambie el nombre a InkRecogitionService y, a continuación, haga clic en Agregar. En la imagen siguiente se muestra el cuadro de diálogo Agregar nuevo elemento con el servicio WCF de Silverlight seleccionado y denominado.
Cuadro de diálogo Agregar nuevo elemento con el servicio wcf de Silverlight seleccionado y denominado
Después de agregar el servicio WCF Silverlight, se abrirá el código de servicio subyacente, InkRecognitionService.cs. Reemplace el código de servicio por el código siguiente.
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;
}
}
}
Agregar la referencia de servicio al proyecto de cliente
Ahora que tiene el servicio WCF de Silverlight para InkRecognition, consumirá el servicio de la aplicación cliente. Haga clic con el botón derecho en el proyecto InkRecognition y seleccione Agregar referencia de servicio. En el cuadro de diálogo Agregar referencia de servicio que aparece, seleccione Detectar para detectar servicios de la solución actual. InkRecognitionService aparecerá en el panel Servicios. Haga doble clic en InkRecognitionService en el panel Servicios, cambie el espacio de nombres a InkRecognitionServiceReference y, a continuación, haga clic en Aceptar. En la imagen siguiente se muestra el cuadro de diálogo Agregar referencia de servicio con InkRecognitionService seleccionado y el espacio de nombres cambiado.
Cuadro de diálogo Agregar referencia de servicio con inkrecognitionservice seleccionado y cambiado el espacio de nombres
Agregar la clase InkCollector al proyecto InkRecognition
Haga clic con el botón derecho en el proyecto InkRecognition, haga clic en Agregar y, a continuación, haga clic en Nuevo elemento. En el menú de Visual C# , seleccione Clase de C#. Asigne un nombre a la clase InkCollector. En la imagen siguiente se muestra el cuadro de diálogo con la clase de C# seleccionada y con nombre.
Cuadro de diálogo Agregar nuevo elemento con la clase c# seleccionada y con nombre
Después de agregar la clase InkCollector, se abrirá la definición de clase. Reemplace el código del recopilador de tinta por el código siguiente.
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();
}
}
Actualizar el XAML para la página predeterminada y agregar un código subyacente para el reconocimiento de escritura a mano
Ahora que tienes una clase que recopila tinta, tendrás que actualizar el XAML en page.xaml con el siguiente XAML. El código siguiente agrega un degradado amarillo al área de entrada, un control InkCanvas y un botón que desencadenará el reconocimiento.
<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>
Reemplace la página de código subyacente, Page.xaml.cs, por el código siguiente que agregará un controlador de eventos para el botón Reconocer .
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;
}
}
Eliminación de directivas de transporte seguro de la configuración del cliente
Para poder consumir el servicio WCF, debe quitar todas las opciones de transporte seguras de la configuración del servicio porque los transportes seguros no se admiten actualmente en los servicios WCF de Silverlight 2.0. En el proyecto InkRecognition, actualice la configuración de seguridad en ServiceReferences.ClientConfig. Cambiar el XML de seguridad de
<security mode="None">
<transport>
<extendedProtectionPolicy policyEnforcement="WhenSupported" />
</transport>
</security>
to
<security mode="None"/>
Ahora, la aplicación debe ejecutarse. En la imagen siguiente se muestra cómo se ve la aplicación dentro de awebpage con alguna escritura a mano escrita en el cuadro de reconocimiento.
Aplicación dentro de awebpage con alguna escritura a mano escrita en el cuadro de reconocimiento
En la imagen siguiente se muestra el texto reconocido en la lista desplegable Resultado .
Aplicación dentro de awebpagewith texto reconocido en la lista desplegable de resultados