Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Dit voorbeeld is gebaseerd op het voorbeeld van inktverzameling. Het laat zien hoe u het Divider-object gebruikt om inktinvoer te analyseren.
Zie The Divider Objectvoor gedetailleerde conceptuele informatie over Divider.
Wanneer het formulier wordt bijgewerkt, tekent het voorbeeld een begrenzingsrechthoek rond elke geanalyseerde eenheid, onderverdeeld in woorden, regels, alinea's en tekeningen. Naast het gebruik van verschillende kleuren worden deze rechthoeken vergroot door verschillende bedragen om ervoor te zorgen dat geen van de rechthoeken door anderen wordt bedekt. In de volgende tabel wordt de kleur en uitbreiding voor elke geanalyseerde eenheid opgegeven.
geanalyseerde eenheid | Kleur | Pixelvergroting |
---|---|---|
Woord |
Groen |
1 |
Lijn |
Magenta |
3 |
Alinea |
Blauw |
5 |
Tekening |
Rood |
1 |
Het formulier instellen
Wanneer het formulier wordt geladen, wordt een Divider-object gemaakt. Er wordt een InkOverlay--object gemaakt en gekoppeld aan een deelvenster in het formulier. Vervolgens worden gebeurtenis-handlers gekoppeld aan het InkOverlay-object om bij te houden wanneer er stroken worden toegevoegd en verwijderd. Als er vervolgens recognizers beschikbaar zijn, wordt er een RecognizerContext--object toegewezen aan de Divider. Vervolgens wordt de eigenschap LineHeight van Divider ingesteld en wordt de verzameling Strokes van InkOverlay toegewezen aan Divider. Ten slotte is het InkOverlay-object ingeschakeld.
// Create the ink overlay and associate it with the form
myInkOverlay = new Microsoft.Ink.InkOverlay(DrawArea.Handle);
// Set the erasing mode to stroke erase.
myInkOverlay.EraserMode = InkOverlayEraserMode.StrokeErase;
// Hook event handler for the Stroke event to myInkOverlay_Stroke.
// This is necessary since the application needs to pass the strokes
// to the ink divider.
myInkOverlay.Stroke += new InkCollectorStrokeEventHandler(myInkOverlay_Stroke);
// Hook the event handler for StrokeDeleting event to myInkOverlay_StrokeDeleting.
// This is necessary as the application needs to remove the strokes from
// ink divider object as well.
myInkOverlay.StrokesDeleting += new InkOverlayStrokesDeletingEventHandler(myInkOverlay_StrokeDeleting);
// Hook the event handler for StrokeDeleted event to myInkOverlay_StrokeDeleted.
// This is necessary to update the layout analysis result when automatic layout analysis
// option is selected.
myInkOverlay.StrokesDeleted += new InkOverlayStrokesDeletedEventHandler(myInkOverlay_StrokeDeleted);
// Create the ink divider object
myInkDivider = new Divider();
// Add a default recognizer context to the divider object
// without adding the recognizer context, the divider would
// not use a recognizer to do its word segmentation and would
// have less accurate results.
// Adding the recognizer context slows down the call to
// myInkDivider.Divide though.
// It is possible that there is no recognizer installed on the
// machine for this language. In that case the divider does
// not use a recognizer to improve its accuracy.
// Get the default recognizer if any
try
{
Recognizers recognizers = new Recognizers();
myInkDivider.RecognizerContext = recognizers.GetDefaultRecognizer().CreateRecognizerContext();
}
catch (InvalidOperationException)
{
//We are in the case where no default recognizers can be found
}
// The LineHeight property helps the InkDivider distinguish between
// drawing and handwriting. The value should be the expected height
// of the user's handwriting in ink space units (0.01mm).
// Here we set the LineHeight to 840, which is about 1/3 of an inch.
myInkDivider.LineHeight = 840;
// Assign ink overlay's strokes collection to the ink divider
// This strokes collection is updated in the event handler
myInkDivider.Strokes = myInkOverlay.Ink.Strokes;
// Enable ink collection
myInkOverlay.Enabled = true;
De verzameling penslagen van het Divider object moet gesynchroniseerd worden gehouden met de verzameling penslagen van het InkOverlay object (toegankelijk via de eigenschap Ink van het InkOverlay-object). Om ervoor te zorgen dat dit gebeurt, wordt de Stroke event handler voor het InkOverlay-object als volgt geschreven. Houd er rekening mee dat de gebeurtenishandler eerst controleert of de EditingMode is ingesteld op Inkt, om gumstreken uit te filteren. Als de gebruiker automatische indelingsanalyse heeft aangevraagd, roept de toepassing de DivideInk-methode van het formulier aan en vernieuwt het tekengebied.
private void myInkOverlay_Stroke(object sender, InkCollectorStrokeEventArgs e )
{
// Filter out the eraser stroke.
if(InkOverlayEditingMode.Ink == myInkOverlay.EditingMode)
{
// Add the new stroke to the ink divider's strokes collection
myInkDivider.Strokes.Add(e.Stroke);
if(miAutomaticLayoutAnalysis.Checked)
{
// Call DivideInk
DivideInk();
// Repaint the screen to reflect the change
DrawArea.Refresh();
}
}
}
De inkt delen
Wanneer de gebruiker op Delen klikt in het menu Bestand, wordt de methode Divide aangeroepen op het Divider-object. De standaardherkenning wordt gebruikt, indien beschikbaar.
DivisionResult divResult = myInkDivider.Divide();
Het resulterende DivisionResult-object waarnaar wordt verwezen door de variabele divResult
, wordt doorgegeven aan een hulpprogrammafunctie, getUnitBBBoxes()
. De hulpprogrammafunctie retourneert een array van rechthoeken voor welk type verdeling ook wordt aangevraagd: segmenten, lijnen, alinea's of tekeningen.
myWordBoundingBoxes = getUnitBBoxes(divResult, InkDivisionType.Segment, 1);
myLineBoundingBoxes = getUnitBBoxes(divResult, InkDivisionType.Line, 3);
myParagraphBoundingBoxes = getUnitBBoxes(divResult, InkDivisionType.Paragraph, 5);
myDrawingBoundingBoxes = getUnitBBoxes(divResult, InkDivisionType.Drawing, 1);
Ten slotte wordt het formuliervenster gedwongen opnieuw te tekenen, zodat de begrenzingsrechthoeken worden weergegeven.
DrawArea.Refresh();
Resultaten van inktanalyse
In de hulpprogrammafunctie wordt het DivisionResult--object opgevraagd voor de resultaten met behulp van de ResultByType-methode, op basis van het divisietype dat door de aanroeper is aangevraagd. De methode ResultByType retourneert een verzameling DivisionUnits. Elke DivisionUnit in de verzameling vertegenwoordigt een tekening, één herkenningssegment van handschrift, een handschriftregel of een handschriftblok, afhankelijk van wat is opgegeven toen de functie van het hulpprogramma werd aangeroepen.
DivisionUnits units = divResult.ResultByType(divType);
Als er ten minste één DivisionUnitis, wordt er een matrix met rechthoeken gemaakt die één begrenzingsrechthoek per eenheid bevatten. (De rechthoeken worden vergroot door verschillende bedragen voor elk type eenheid, die in de variabele inflate worden opgeslagen, om overlapping te voorkomen.)
// If there is at least one unit, we construct the rectangles
if((null != units) && (0 < units.Count))
{
// We need to convert rectangles from ink units to
// pixel units. For that, we need Graphics object
// to pass to InkRenderer.InkSpaceToPixel method
using (Graphics g = DrawArea.CreateGraphics())
{
// InkSpace to Pixel Space conversion setup done here.
// Not shown for brevity.
// Iterate through the collection of division units to obtain the bounding boxes
foreach(DivisionUnit unit in units)
{
// Get the bounding box of the strokes of the division unit
divRects[i] = unit.Strokes.GetBoundingBox();
// Div unit rect Ink space to Pixel space conversion done here.
// Not shown for brevity.
// Inflate the rectangle by inflate pixels in both directions
divRects[i].Inflate(inflate, inflate);
// Increment the index
++i;
}
} // Relinquish the Graphics object
}
Het formulier opnieuw tekenen
Wanneer de hertekening hierboven wordt afgedwongen, wordt de volgende code uitgevoerd om de begrenzingsvakken te schilderen voor elke DivisionUnit op het formulier rond de inkt.
private void DrawArea_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
// Create the Pen used to draw bounding boxes.
// First set of bounding boxes drawn here are
// the bounding boxes of paragraphs.
// These boxes are drawn with Blue pen.
Pen penBox = new Pen(Color.Blue, 2);
// First, draw the bounding boxes for Paragraphs
if(null != myParagraphBoundingBoxes)
{
// Draw bounding boxes for Paragraphs
e.Graphics.DrawRectangles(penBox, myParagraphBoundingBoxes);
}
// Next, draw the bounding boxes for Lines
if(null != myLineBoundingBoxes)
{
// Color is Magenta pen
penBox.Color = Color.Magenta;
// Draw the bounding boxes for Lines
e.Graphics.DrawRectangles(penBox, myLineBoundingBoxes);
}
// Then, draw the bounding boxes for Words
if(null != myWordBoundingBoxes)
{
// Color is Green
penBox.Color = Color.Green;
// Draw bounding boxes for Words
e.Graphics.DrawRectangles(penBox, myWordBoundingBoxes);
}
// Finally, draw the boxes for Drawings
if(null != myDrawingBoundingBoxes)
{
// Color is Red pen
penBox.Color = Color.Red;
// Draw bounding boxes for Drawings
e.Graphics.DrawRectangles(penBox, myDrawingBoundingBoxes);
}
}
Het formulier sluiten
De methode Dispose van het formulier verwijdert de InkOverlay-, Divider, RecognizerContext-objecten en de verzameling Strokes die in het voorbeeld worden gebruikt.