다음을 통해 공유


방법: 분석 힌트를 사용하여 잉크 분석

System.Windows.Ink.AnalysisHintNode는 연결되는 System.Windows.Ink.InkAnalyzer에 대한 힌트를 제공합니다. 힌트는 System.Windows.Ink.AnalysisHintNodeSystem.Windows.Ink.ContextNode.Location%2A 속성에 의해 지정된 영역에 적용되고 잉크 분석기에 추가 컨텍스트를 제공하여 인식 정확도를 개선합니다. System.Windows.Ink.InkAnalyzer는 힌트의 영역 내에서 획득한 잉크를 분석할 때 이 컨텍스트 정보를 적용합니다.

예시

다음 예제는 잉크 입력을 수락하는 양식에서 여러 개의 System.Windows.Ink.AnalysisHintNode 개체를 사용하는 애플리케이션입니다. 애플리케이션은 System.Windows.Ink.AnalysisHintNode.Factoid%2A 속성을 사용하여 양식의 각 항목에 대한 컨텍스트 정보를 제공합니다. 애플리케이션은 배경 분석을 사용하여 잉크를 분석하고 사용자가 잉크 추가를 중지하고 5초가 지나면 모든 잉크의 양식을 지웁니다.

<Window x:Class="FormAnalyzer"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="FormAnalyzer"
      SizeToContent="WidthAndHeight"
    >
    <StackPanel Orientation="Vertical">
    <InkCanvas Name="xaml_writingCanvas" Height="500" Width="840" 
               StrokeCollected="RestartAnalysis" >
            <Grid>
                <Grid.Resources>
                    <Style TargetType="{x:Type Label}">
                        <Setter Property="FontSize" Value="20"/>
                        <Setter Property="FontFamily" Value="Arial"/>
                    </Style>

                    <Style TargetType="{x:Type TextBlock}">
                        <Setter Property="FontSize" Value="18"/>
                        <Setter Property="VerticalAlignment" Value="Center"/>
                    </Style>
                </Grid.Resources>
                
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="100"></ColumnDefinition>
                    <ColumnDefinition Width="160"></ColumnDefinition>
                    <ColumnDefinition Width="160"></ColumnDefinition>
                    <ColumnDefinition Width="100"></ColumnDefinition>
                    <ColumnDefinition Width="160"></ColumnDefinition>
                    <ColumnDefinition Width="160"></ColumnDefinition>
                </Grid.ColumnDefinitions>

                <Grid.RowDefinitions>
                    <RowDefinition Height="100"></RowDefinition>
                    <RowDefinition Height="100"></RowDefinition>
                    <RowDefinition Height="100"></RowDefinition>
                    <RowDefinition Height="100"></RowDefinition>
                    <RowDefinition Height="100"></RowDefinition>
                </Grid.RowDefinitions>

                <Label Grid.Row="0" Grid.Column="0">Title</Label>
                <Label Grid.Row="1" Grid.Column="0">Director</Label>
                <Label Grid.Row="2" Grid.Column="0">Starring</Label>
                <Label Grid.Row="3" Grid.Column="0">Rating</Label>
                <Label Grid.Row="3" Grid.Column="3">Year</Label>
                <Label Grid.Row="4" Grid.Column="0">Genre</Label>

                <TextBlock Name="xaml_blockTitle" 
                   Grid.Row="0" Grid.Column="1" 
                   Grid.ColumnSpan="5"/>
        <TextBlock Name="xaml_blockDirector"
                   Grid.Row="1" Grid.Column="1" 
                   Grid.ColumnSpan="5"/>
                <TextBlock Name="xaml_blockStarring"
                   Grid.Row="2" Grid.Column="1" 
                   Grid.ColumnSpan="5"/>
                <TextBlock Name="xaml_blockRating" 
                   Grid.Row="3" Grid.Column="1" 
                   Grid.ColumnSpan="2"/>
                <TextBlock Name="xaml_blockYear" 
                   Grid.Row="3" Grid.Column="4" 
                   Grid.ColumnSpan="2"/>
                <TextBlock Name="xaml_blockGenre" 
                   Grid.Row="4" Grid.Column="1" 
                   Grid.ColumnSpan="5"/>

                <Line Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="6" 
              StrokeThickness="2" Stroke="Black" 
              X1="0" Y1="100" X2="840" Y2="100" />
                <Line Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="6" 
              StrokeThickness="2" Stroke="Black" 
              X1="0" Y1="100" X2="840" Y2="100" />
                <Line Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="6" 
              StrokeThickness="2" Stroke="Black" 
              X1="0" Y1="100" X2="840" Y2="100" />
                <Line Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="6" 
              StrokeThickness="2" Stroke="Black" 
              X1="0" Y1="100" X2="840" Y2="100" />
                <Line Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="6" 
              StrokeThickness="2" Stroke="Black" 
              X1="420" Y1="0" X2="420" Y2="100" />
            </Grid>
        </InkCanvas>
    </StackPanel>
</Window>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Ink;
using System.Windows.Threading;

public partial class FormAnalyzer : Window
{
    private InkAnalyzer analyzer;

    private AnalysisHintNode hintNodeTitle;
    private AnalysisHintNode hintNodeDirector;
    private AnalysisHintNode hintNodeStarring;
    private AnalysisHintNode hintNodeRating;
    private AnalysisHintNode hintNodeYear;
    private AnalysisHintNode hintNodeGenre;

    // Timer that raises an event to
    // clear the InkCanvas.
    private DispatcherTimer strokeRemovalTimer;

    private const int CLEAR_STROKES_DELAY = 5;

    public FormAnalyzer()
    {
        InitializeComponent();
    }

    protected override void OnContentRendered(EventArgs e)
    {
        base.OnContentRendered(e);

        // Initialize the Analyzer.
        analyzer = new InkAnalyzer();
        analyzer.ResultsUpdated +=
            new ResultsUpdatedEventHandler(analyzer_ResultsUpdated);

        // Add analysis hints for each form area.
        // Use the absolute Width and Height of the Grid's
        // RowDefinition and ColumnDefinition properties defined in XAML,
        // to calculate the bounds of the AnalysisHintNode objects.
        hintNodeTitle = analyzer.CreateAnalysisHint(
                                    new Rect(100, 0, 740, 100));
        hintNodeDirector = analyzer.CreateAnalysisHint(
                                    new Rect(100, 100, 740, 100));
        hintNodeStarring = analyzer.CreateAnalysisHint(
                                    new Rect(100, 200, 740, 100));
        hintNodeRating = analyzer.CreateAnalysisHint(
                                    new Rect(100, 300, 320, 100));
        hintNodeYear = analyzer.CreateAnalysisHint(
                                    new Rect(520, 300, 320, 100));
        hintNodeGenre = analyzer.CreateAnalysisHint(
                                    new Rect(100, 400, 740, 100));

        //Set the factoids on the hints.
        hintNodeTitle.Factoid = "(!IS_DEFAULT)";
        hintNodeDirector.Factoid = "(!IS_PERSONALNAME_FULLNAME)";
        hintNodeStarring.Factoid = "(!IS_PERSONALNAME_FULLNAME)";
        hintNodeRating.Factoid = "(!IS_DEFAULT)";
        hintNodeYear.Factoid = "(!IS_DATE_YEAR)";
        hintNodeGenre.Factoid = "(!IS_DEFAULT)";
    }

    /// <summary>
    /// InkCanvas.StrokeCollected event handler.  Begins
    /// ink analysis and starts the timer to clear the strokes.
    /// If five seconds pass without a Stroke being added,
    /// the strokes on the InkCanvas will be cleared.
    /// </summary>
    /// <par    am name="sender">InkCanvas that raises the
    /// StrokeCollected event.</param>
    /// <param name="args">Contains the event data.</param>
    private void RestartAnalysis(object sender,
                    InkCanvasStrokeCollectedEventArgs args)
    {

        // If strokeRemovalTimer is enabled, stop it.
        if (strokeRemovalTimer != null && strokeRemovalTimer.IsEnabled)
        {
            strokeRemovalTimer.Stop();
        }

        // Restart the timer to clear the strokes in five seconds
        strokeRemovalTimer = new DispatcherTimer(
                             TimeSpan.FromSeconds(CLEAR_STROKES_DELAY),
                             DispatcherPriority.Normal,
                             ClearCanvas,
                             Dispatcher.CurrentDispatcher);

        // Add the new stroke to the InkAnalyzer and
        // begin background analysis.
        analyzer.AddStroke(args.Stroke);
        analyzer.BackgroundAnalyze();
    }

    /// <summary>
    /// Analyzer.ResultsUpdated event handler.
    /// </summary>
    /// <param name="sender">InkAnalyzer that raises the
    /// event.</param>
    /// <param name="e">Event data</param>
    /// <remarks>This method checks each AnalysisHint for
    /// analyzed ink and then populated the TextBlock that
    /// corresponds to the area on the form.</remarks>
    void analyzer_ResultsUpdated(object sender, ResultsUpdatedEventArgs e)
    {
        string recoText;

        recoText = hintNodeTitle.GetRecognizedString();
        if (recoText != "") xaml_blockTitle.Text = recoText;

        recoText = hintNodeDirector.GetRecognizedString();
        if (recoText != "") xaml_blockDirector.Text = recoText;

        recoText = hintNodeStarring.GetRecognizedString();
        if (recoText != "") xaml_blockStarring.Text = recoText;

        recoText = hintNodeRating.GetRecognizedString();
        if (recoText != "") xaml_blockRating.Text = recoText;

        recoText = hintNodeYear.GetRecognizedString();
        if (recoText != "") xaml_blockYear.Text = recoText;

        recoText = hintNodeGenre.GetRecognizedString();
        if (recoText != "") xaml_blockGenre.Text = recoText;
    }

    //Clear the canvas, but leave the current strokes in the analyzer.
    private void ClearCanvas(object sender, EventArgs args)
    {
        strokeRemovalTimer.Stop();

        xaml_writingCanvas.Strokes.Clear();
    }
}
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Ink
Imports System.Windows.Threading



Class FormAnalyzer
    Inherits Window

    Private analyzer As InkAnalyzer
    
    Private hintNodeTitle As AnalysisHintNode
    Private hintNodeDirector As AnalysisHintNode
    Private hintNodeStarring As AnalysisHintNode
    Private hintNodeRating As AnalysisHintNode
    Private hintNodeYear As AnalysisHintNode
    Private hintNodeGenre As AnalysisHintNode
    
    ' Timer that raises an event to
    ' clear the InkCanvas.
    Private strokeRemovalTimer As DispatcherTimer
    
    Private Const CLEAR_STROKES_DELAY As Integer = 5
        
    Public Sub New() 

        InitializeComponent()
    
    End Sub
    
    Protected Overrides Sub OnContentRendered(ByVal e As EventArgs) 
        MyBase.OnContentRendered(e)
        
        ' Initialize the Analyzer.
        analyzer = New InkAnalyzer()
        AddHandler analyzer.ResultsUpdated, AddressOf analyzer_ResultsUpdated
        
        ' Add analysis hints for each form area.
        ' Use the absolute Width and Height of the Grid's
        ' RowDefinition and ColumnDefinition properties defined in XAML, 
        ' to calculate the bounds of the AnalysisHintNode objects.
        hintNodeTitle = analyzer.CreateAnalysisHint(New Rect(100, 0, 740, 100))
        hintNodeDirector = analyzer.CreateAnalysisHint(New Rect(100, 100, 740, 100))
        hintNodeStarring = analyzer.CreateAnalysisHint(New Rect(100, 200, 740, 100))
        hintNodeRating = analyzer.CreateAnalysisHint(New Rect(100, 300, 320, 100))
        hintNodeYear = analyzer.CreateAnalysisHint(New Rect(520, 300, 320, 100))
        hintNodeGenre = analyzer.CreateAnalysisHint(New Rect(100, 400, 740, 100))
        
        'Set the factoids on the hints.
        hintNodeTitle.Factoid = "(!IS_DEFAULT)"
        hintNodeDirector.Factoid = "(!IS_PERSONALNAME_FULLNAME)"
        hintNodeStarring.Factoid = "(!IS_PERSONALNAME_FULLNAME)"
        hintNodeRating.Factoid = "(!IS_DEFAULT)"
        hintNodeYear.Factoid = "(!IS_DATE_YEAR)"
        hintNodeGenre.Factoid = "(!IS_DEFAULT)"
    
    End Sub

    ' InkCanvas.StrokeCollected event handler.  Begins 
    ' ink analysis and starts the timer to clear the strokes.
    ' If five seconds pass without a Stroke being added,
    ' the strokes on the InkCanvas will be cleared.
    ' <param name="sender">InkCanvas that raises the
    ' StrokeCollected event.</param>
    ' <param name="args">Contains the event data.</param>
    Private Sub RestartAnalysis(ByVal sender As Object, ByVal args As InkCanvasStrokeCollectedEventArgs) 
        
        ' If strokeRemovalTimer is enabled, stop it.
        If Not (strokeRemovalTimer Is Nothing) AndAlso strokeRemovalTimer.IsEnabled Then
            strokeRemovalTimer.Stop()
        End If
        
        ' Restart the timer to clear the strokes in five seconds
        strokeRemovalTimer = New DispatcherTimer( _
                             TimeSpan.FromSeconds(CLEAR_STROKES_DELAY), _
                             DispatcherPriority.Normal, _
                             AddressOf ClearCanvas, _
                             System.Windows.Threading.Dispatcher.CurrentDispatcher)
        
        ' Add the new stroke to the InkAnalyzer and
        ' begin background analysis.
        analyzer.AddStroke(args.Stroke)
        analyzer.BackgroundAnalyze()
    
    End Sub
    
    ' Analyzer.ResultsUpdated event handler.
    ' <param name="sender">InkAnalyzer that raises the
    ' event.</param>
    ' <param name="e">Event data</param>
    ' <remarks>This method checks each AnalysisHint for 
    ' analyzed ink and then populated the TextBlock that 
    ' corresponds to the area on the form.</remarks>
    Private Sub analyzer_ResultsUpdated(ByVal sender As Object, ByVal e As ResultsUpdatedEventArgs)

        Dim recoText As String

        recoText = hintNodeTitle.GetRecognizedString()
        If recoText <> "" Then
            xaml_blockTitle.Text = recoText
        End If

        recoText = hintNodeDirector.GetRecognizedString()
        If recoText <> "" Then
            xaml_blockDirector.Text = recoText
        End If

        recoText = hintNodeStarring.GetRecognizedString()
        If recoText <> "" Then
            xaml_blockStarring.Text = recoText
        End If

        recoText = hintNodeRating.GetRecognizedString()
        If recoText <> "" Then
            xaml_blockRating.Text = recoText
        End If

        recoText = hintNodeYear.GetRecognizedString()
        If recoText <> "" Then
            xaml_blockYear.Text = recoText
        End If

        recoText = hintNodeGenre.GetRecognizedString()
        If recoText <> "" Then
            xaml_blockGenre.Text = recoText
        End If

    End Sub
     
    'Clear the canvas, but leave the current strokes in the analyzer.
    Private Sub ClearCanvas(ByVal sender As Object, ByVal args As EventArgs) 

        strokeRemovalTimer.Stop()
        
        xaml_writingCanvas.Strokes.Clear()
    
    End Sub
End Class