Reconhecimento de manuscrito no Windows Server 2008 R2

O Windows Server 2008 R2 dá suporte ao reconhecimento de manuscrito do lado do servidor. O reconhecimento do lado do servidor permite que um servidor reconheça o conteúdo da entrada de caneta em páginas da Web. Isso é particularmente útil quando os usuários em uma rede especificam termos que são interpretados usando um dicionário personalizado. Por exemplo, se você tivesse um aplicativo médico que consultasse um banco de dados de servidor para nomes de pacientes, esses nomes poderiam ser adicionados a outro banco de dados que seria referenciado cruzadamente ao executar pesquisas de um formulário Silverlight manuscrito.

Configurar o servidor para reconhecimento de Server-Side

As etapas a seguir devem ser seguidas para configurar o reconhecimento do lado do servidor.

  • Instalar os Serviços de Tinta e Manuscrito
  • Instalar o Suporte para Servidor Web (IIS) e o Servidor de Aplicativos
  • Habilitar a Função de Experiência da Área de Trabalho
  • Iniciar o Serviço de Entrada do Tablet PC

Instalar os Serviços de Tinta e Manuscrito

Para instalar os serviços de Tinta e Manuscrito, abra o gerenciador do servidor clicando no ícone do gerenciador de servidores na bandeja Início Rápido. No menu Recursos , clique em Adicionar Recursos. Selecione a caixa marcar Serviços de Tinta e Manuscrito. A imagem a seguir mostra a caixa de diálogo Selecionar Recursos com Os Serviços de Tinta e Manuscrito selecionados.

Caixa de diálogo Selecionar recursos com tinta e serviços de manuscrito marcar caixa selecionada
Caixa de diálogo Selecionar recursos com tinta e serviços de manuscrito marcar caixa selecionada

Suporte de instalação para Servidor Web (IIS) e Servidor de Aplicativos

Abra o gerenciador do servidor como você fez na primeira etapa. Em seguida, você precisará adicionar as funções servidor Web (IIS) e Servidor de Aplicativos. No menu Funções , clique em Adicionar Funções. O assistente Adicionar Funções é exibido. Clique em Avançar. Verifique se o Servidor de Aplicativos e o Servidor Web (IIS) estão selecionados. A imagem a seguir mostra a caixa de diálogo Selecionar Funções de Servidor com as funções servidor Web (IIS) e Servidor de Aplicativos selecionadas.

Caixa de diálogo Selecionar funções de servidor com servidor Web (iis) e funções de servidor de aplicativos selecionadas
Caixa de diálogo Selecionar funções de servidor com servidor Web (iis) e funções de servidor de aplicativos selecionadas

Ao selecionar o Servidor de Aplicativos, você será solicitado a instalar a estrutura ASP.NET. Clique no botão Adicionar os Recursos Necessários . Depois de clicar em Avançar, você receberá uma caixa de diálogo de visão geral; clique em Avançar. A caixa de diálogo Selecionar Serviços de Função agora deve estar disponível. Verifique se o Servidor Web (IIS) está selecionado. A imagem a seguir mostra a caixa de diálogo Selecionar Serviços de Função com o Servidor Web (IIS) habilitado.

Caixa de diálogo Selecionar serviços de função com o servidor Web (iis) habilitado
Caixa de diálogo Selecionar serviços de função com o servidor Web (iis) habilitado

Clique em Avançar. Uma caixa de diálogo de visão geral é exibida; clique em Avançar novamente. Agora você receberá uma página oferecendo opções para funções para Servidor Web (IIS). Clique em Avançar. Na próxima página, o botão Instalar ficará ativo. Clique em Instalar e você instalará o suporte para Servidor Web (IIS) e Servidor de Aplicativos.

Habilitar a Função de Experiência da Área de Trabalho

Para habilitar a experiência da área de trabalho, clique em Iniciar, em Ferramentas Administrativas e em Gerenciador do Servidor. Selecione Adicionar Serviços e, em seguida, selecione o serviço Experiência da Área de Trabalho . A imagem a seguir mostra a caixa de diálogo Selecionar Recursos com o item Experiência desktop instalado.

Caixa de diálogo Selecionar recursos com o serviço de experiência da área de trabalho selecionado
Caixa de diálogo Selecionar recursos com o serviço de experiência da área de trabalho selecionado

Clique em Avançar para instalar a Experiência desktop.

Iniciar o Serviço de Tablet

Depois de instalar o serviço Experiência da Área de Trabalho, o serviço de Entrada do Tablet PC aparecerá no menu Serviços . Para acessar o menu Serviços , clique em Iniciar, em Ferramentas Administrativas e em Serviços. Para iniciar o serviço, clique com o botão direito do mouse em Serviço de Entrada do Tablet PC e clique em Iniciar. A imagem a seguir mostra o menu Serviços com o Serviço de Entrada do Tablet PC iniciado.

Menu Serviços com o serviço de entrada do computador tablet iniciado
Menu Serviços com o serviço de entrada do computador tablet iniciado

Executando o reconhecimento de Server-Side usando o Silverlight

Esta seção mostra como criar um aplicativo Web que usa o Silverlight para capturar a entrada de manuscrito. Use as etapas a seguir para programar o reconhecedor no Visual Studio 2008.

  • Instale e atualize o Visual Studio 2008 para adicionar suporte ao Silverlight.
  • Crie um novo projeto silverlight no Visual Studio 2008.
  • Adicione as referências de serviço necessárias ao seu projeto.
  • Crie um Serviço WCF do Silverlight para reconhecimento de tinta.
  • Adicione a referência de serviço ao seu projeto cliente.
  • Adicione a classe InkCollector ao projeto InkRecognition.
  • Remover diretivas de transporte seguro da configuração do cliente

Instalar e atualizar o Visual Studio 2008 para adicionar suporte ao Silverlight

Antes de começar, você deve executar as etapas a seguir no servidor Windows Server 2008 R2.

Depois de instalar esses aplicativos e atualizações, você estará pronto para criar seu aplicativo Web de reconhecimento do lado do servidor.

Criar um novo Projeto Web silverlight no Visual Studio 2008

No menu Arquivo, clique em Novo Projeto. Selecione o modelo Aplicativo Silverlight na lista de projetos do Visual C#. Nomeie seu projeto inkRecognition e clique em OK. A imagem a seguir mostra o projeto Silverlight do C# selecionado e chamado InkRecognition.

c# silverlight project selecionado, com o nome inkrecognition
c# silverlight project selecionado, com o nome inkrecognition

Depois de clicar em OK, uma caixa de diálogo solicitará que você adicione um aplicativo Silverlight ao seu projeto. Selecione Adicionar um novo projeto web ASP.NET à solução para hospedar o Silverlight e clique em OK. A imagem a seguir mostra como configurar o projeto de exemplo antes de clicar em OK.

Caixa de diálogo com prompt para adicionar um aplicativo silverlight a um projeto
Caixa de diálogo com prompt para adicionar um aplicativo silverlight a um projeto

Adicionar as referências de serviço necessárias ao seu projeto

Agora você tem seu projeto de cliente Silverlight genérico (InkRecognition) com um projeto Web (InkRecognition.Web) configurado em sua solução. O projeto será aberto com Page.xaml e Default.aspx abertos. Feche essas janelas e adicione as referências System.Runtime.Serialization e System.ServiceModel ao projeto InkRecognition clicando com o botão direito do mouse na pasta de referências no projeto InkRecognition e selecionando Adicionar Referência. A imagem a seguir mostra a caixa de diálogo com as referências necessárias selecionadas.

Caixa de diálogo Adicionar referências com system.runtime.serialization e system.servicemodel selecionados
Caixa de diálogo Adicionar referências com system.runtime.serialization e system.servicemodel selecionados

Em seguida, você precisa adicionar as referências System.ServiceModel e Microsoft.Ink ao projeto InkRecognition.Web. A referência do Microsoft.Ink não aparecerá nas referências do .NET por padrão, portanto, pesquise Microsoft.Ink.dll na pasta do Windows. Depois de localizar a DLL, adicione o assembly às referências do projeto: selecione a guia Procurar , altere para a pasta que contém Microsoft.Ink.dll, selecione Microsoft.Ink.dll e clique em OK. A imagem a seguir mostra a solução do projeto no Windows Explorer com todos os assemblies de referência adicionados.

projeto inkrecognition no Windows Explorer com todos os assemblies de referência adicionados
projeto inkrecognition no Windows Explorer com todos os assemblies de referência adicionados

Criar um serviço WCF silverlight para reconhecimento de tinta

Em seguida, você adicionará um serviço WCF para reconhecimento de tinta ao projeto. Clique com o botão direito do mouse em seu projeto InkRecognition.Web, clique em Adicionar e clique em Novo Item. Selecione o modelo WCF Silverlight Service, altere o nome para InkRecogitionService e clique em Adicionar. A imagem a seguir mostra a caixa de diálogo Adicionar Novo Item com o serviço WCF silverlight selecionado e nomeado.

Caixa de diálogo Adicionar novo item com o serviço wcf silverlight selecionado e nomeado
Caixa de diálogo Adicionar novo item com o serviço wcf silverlight selecionado e nomeado

Depois de adicionar o serviço Silverlight do WCF, o código de serviço por trás, InkRecognitionService.cs, será aberto. Substitua o código de serviço pelo código a seguir.

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;
        }
    }
}

Adicionar a referência de serviço ao seu projeto cliente

Agora que você tem o serviço WCF do Silverlight para InkRecognition, você consumirá o serviço do aplicativo cliente. Clique com o botão direito do mouse no projeto InkRecognition e selecione Adicionar Referência de Serviço. Na caixa de diálogo Adicionar Referência de Serviço exibida, selecione Descobrir para descobrir serviços na solução atual. InkRecognitionService será exibido no painel Serviços. Clique duas vezes em InkRecognitionService no painel Serviços, altere o namespace para InkRecognitionServiceReference e clique em OK. A imagem a seguir mostra a caixa de diálogo Adicionar Referência de Serviço com InkRecognitionService selecionado e o namespace alterado.

Caixa de diálogo Adicionar referência de serviço com inkrecognitionservice selecionado e namespace alterado
Caixa de diálogo Adicionar referência de serviço com inkrecognitionservice selecionado e namespace alterado

Adicionar a classe InkCollector ao Projeto InkRecognition

Clique com o botão direito do mouse no projeto InkRecognition, clique em Adicionar e clique em Novo Item. No menu Visual C# , selecione Classe C#. Nomeie a classe InkCollector. A imagem a seguir mostra a caixa de diálogo com a classe C# selecionada e nomeada.

Caixa de diálogo Adicionar novo item com a classe c# selecionada e nomeada
Caixa de diálogo Adicionar novo item com a classe c# selecionada e nomeada

Depois de adicionar a classe InkCollector, a definição de classe será aberta. Substitua o código no Coletor de Tinta pelo código a seguir.

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();
    }
}

Atualizar o XAML para a página padrão e adicionar um code behind para reconhecimento de manuscrito

Agora que você tem uma classe que coleta tinta, será necessário atualizar o XAML em page.xaml com o XAML a seguir. O código a seguir adiciona um gradiente amarelo à área de entrada, um controle InkCanvas e um botão que disparará o reconhecimento.

<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>

Substitua a página code-behind, Page.xaml.cs, pelo código a seguir que adicionará um manipulador de eventos para o botão Reconhecer .

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;
    }
}

Remover diretivas de transporte seguro da configuração do cliente

Antes de consumir o serviço WCF, você deve remover todas as opções de transporte seguro da configuração de serviço porque os transportes seguros não têm suporte atualmente nos serviços do WCF do Silverlight 2.0. No projeto InkRecognition, atualize as configurações de segurança em ServiceReferences.ClientConfig. Alterar o XML de segurança de

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

como

       <security mode="None"/>

Agora, seu aplicativo deve ser executado. A imagem a seguir mostra a aparência do aplicativo em awebpage com alguma manuscrito inserida na caixa de reconhecimento.

Aplicativo dentro de awebpagecom alguma manuscrito inserida na caixa de reconhecimento
Aplicativo dentro de awebpagecom alguma manuscrito inserida na caixa de reconhecimento

A imagem a seguir mostra o texto reconhecido na lista suspensa Resultado .

Aplicativo dentro de awebpagewith recognized text in result drop-down list
Aplicativo dentro de awebpagewith recognized text in result drop-down list