Partager via


Exemple de sérialisation d’entrée manuscrite

Cet exemple montre comment sérialiser et désérialiser l’entrée manuscrite dans différents formats. L’application représente un formulaire avec des champs permettant d’insérer le prénom, le nom et la signature. L’utilisateur peut enregistrer ces données au format ISF (Ink Serialized Format), XML (Extensible Markup Language) à l’aide d’UN ISF codé en base64 ou HTML, qui fait référence à l’entrée manuscrite dans une image GIF (Graphics Interchange Format) codée en base64. L’application permet également à l’utilisateur d’ouvrir des fichiers enregistrés au format XML et ISF. Le format ISF utilise des propriétés étendues pour stocker le prénom et le nom, tandis que les formats XML et HTML stockent ces informations dans des attributs personnalisés.

Cet exemple ne prend pas en charge le chargement à partir du format HTML, car le code HTML ne convient pas au stockage de données structurées. Étant donné que les données sont séparées par nom, signature, etc., un format qui préserve cette séparation, tel que XML ou un autre type de format de base de données, est requis.

Html est très utile dans un environnement dans lequel la mise en forme est importante, comme dans un document de traitement de texte. Le code HTML enregistré par cet exemple utilise des GIF fortifiés. Ces gifs contiennent un ISF incorporé, ce qui préserve la fidélité totale de l’entrée manuscrite. Une application de traitement de texte peut enregistrer un document contenant plusieurs types de données, tels que des images, des tableaux, du texte mis en forme et des entrées manuscrites persistantes dans un format HTML. Ce code HTML s’affiche dans les navigateurs qui ne reconnaissent pas l’entrée manuscrite. Toutefois, lors du chargement dans une application qui prend en charge l’entrée manuscrite, la fidélité totale de l’encre d’origine est disponible et peut être rendue, modifiée ou utilisée pour la reconnaissance.

Les fonctionnalités suivantes sont utilisées dans cet exemple :

Collecte d'encre

Tout d’abord, référencez l’API Tablet PC, qui est installée avec le Kit de développement logiciel (SDK) Windows Vista et Windows XP Édition Tablet PC.

using Microsoft.Ink;

Le constructeur crée et active un InkCollector, ic, pour le formulaire.

ic = new InkCollector(Signature.Handle);
ic.Enabled = true;

Enregistrement d’un fichier

La SaveAsMenu_Click méthode gère la boîte de dialogue Enregistrer sous, crée un flux de fichiers dans lequel enregistrer les données manuscrites et appelle la méthode save qui correspond au choix de l’utilisateur.

Enregistrement dans un fichier ISF

Dans la SaveISF méthode, les valeurs de prénom et de nom sont ajoutées à la propriété ExtendedProperties de la propriété InkCollector de l’objet InkCollector, avant que l’encre ne soit sérialisée et écrite dans le fichier. Une fois l’encre sérialisée, les valeurs de prénom et de nom sont supprimées de la propriété ExtendedProperties de l’objet Ink .

byte[] isf;

// This is the ink object which is serialized
ExtendedProperties inkProperties = ic.Ink.ExtendedProperties;

// Store the name fields in the ink object
// These fields roundtrip through the ISF format
// Ignore empty fields since strictly empty strings 
//       cannot be stored in ExtendedProperties.
if (FirstNameBox.Text.Length > 0)
{
    inkProperties.Add(FirstName, FirstNameBox.Text);
}
if (LastNameBox.Text.Length > 0)
{
    inkProperties.Add(LastName, LastNameBox.Text);
}

// Perform the serialization
isf = ic.Ink.Save(PersistenceFormat.InkSerializedFormat);

// If the first and last names were added as extended
// properties to the ink, remove them - these properties
// are only used for the save and there is no need to
// keep them around on the ink object.
if (inkProperties.DoesPropertyExist(FirstName))
{
    inkProperties.Remove(FirstName);
}
if (inkProperties.DoesPropertyExist(LastName))
{
    inkProperties.Remove(LastName);
}

// Write the ISF to the stream
s.Write(isf,0,isf.Length);

Enregistrement dans un fichier XML

Dans la SaveXML méthode , un objet XmlTextWriter est utilisé pour créer et écrire dans un document XML. À l’aide de la méthode Save de l’objet Ink, l’encre est d’abord convertie en un tableau d’octets format sérialisé manuscrit codé en base64, puis le tableau d’octets est converti en chaîne à écrire dans le fichier XML. Les données textuelles du formulaire sont également écrites dans le fichier XML.

// Get the base64 encoded ISF
base64ISF_bytes = ic.Ink.Save(PersistenceFormat.Base64InkSerializedFormat);

// Convert it to a String
base64ISF_string = utf8.GetString(base64ISF_bytes);

// Write the ISF containing node to the XML
xwriter.WriteElementString("Ink", base64ISF_string);

// Write the text data from the form
// Note that the names are stored as XML fields, rather
// than custom properties, so that these properties can 
// be most easily accessible if the XML is saved in a database.
xwriter.WriteElementString("FirstName",FirstNameBox.Text);
xwriter.WriteElementString("LastName",LastNameBox.Text);

Enregistrement dans un fichier HTML

La méthode SaveHTML utilise le cadre englobant de la collection Strokes pour tester la présence d’une signature. Si la signature existe, elle est convertie au format GIF renforcé à l’aide de la méthode Save de l’objet d’entrée manuscrite et écrite dans un fichier. Le fichier GIF est ensuite référencé dans le fichier HTML.

if (ic.Ink.Strokes.GetBoundingBox().IsEmpty)
{
   MessageBox.Show("Unable to save empty ink in HTML persistence format.");
}
else
{
    FileStream gifFile;
    byte[] fortifiedGif = null;
    ...

    // Create a directory to store the fortified GIF which also contains ISF
    // and open the file for writing
    Directory.CreateDirectory(nameBase + "_files");
    using (FileStream gifFile = File.OpenWrite(nameBase + "_files\\signature.gif"))
    {

        // Generate the fortified GIF represenation of the ink
        fortifiedGif = ic.Ink.Save(PersistenceFormat.Gif);

        // Write and close the gif file
        gifFile.Write(fortifiedGif, 0, fortifiedGif.Length);
    }

Chargement d’un fichier

La OpenMenu_Click méthode gère la boîte de dialogue Ouvrir, ouvre le fichier et appelle la méthode de chargement qui correspond au choix de l’utilisateur.

Chargement d’un fichier ISF

La LoadISF méthode lit le fichier créé précédemment et convertit le tableau d’octets en entrée manuscrite avec la méthode Load de l’objet Ink. Le collecteur d’encre est temporairement désactivé pour lui affecter l’objet Ink. La LoadISF méthode vérifie ensuite la propriété ExtendedProperties de l’objet Ink pour les chaînes de prénom et de nom.

Ink loadedInk = new Ink();
byte[] isfBytes = new byte[s.Length];

// read in the ISF
s.Read(isfBytes, 0, (int) s.Length);

// load the ink into a new ink object
// After an ink object has been "dirtied" it can never load ink again
loadedInk.Load(isfBytes);

// temporarily disable the ink collector and swap ink objects
ic.Enabled = false;
ic.Ink = loadedInk;
ic.Enabled = true;

// Repaint the inkable region
Signature.Invalidate();

ExtendedProperties inkProperties = ic.Ink.ExtendedProperties;

// Get the raw data out of this stroke's extended
// properties list, using the previously defined 
// Guid as a key to the extended property.
// Since the save method stored the first and last
// name information as extended properties, this
// information can be remove now that the load is complete.
if (inkProperties.DoesPropertyExist(FirstName))
{
    FirstNameBox.Text = (String) inkProperties[FirstName].Data;
    inkProperties.Remove(FirstName);
}
else
{
    FirstNameBox.Text = String.Empty;
}

if (inkProperties.DoesPropertyExist(LastName))
{
    LastNameBox.Text = (String) inkProperties[LastName].Data;
    inkProperties.Remove(LastName);
}
else
{
    LastNameBox.Text = String.Empty;
}

Chargement d’un fichier XML

La LoadXML méthode charge un fichier XML créé précédemment, récupère les données du nœud Ink et convertit les données du nœud en encre à l’aide de la méthode Load de l’objet Ink. InkCollector est temporairement désactivé pour lui affecter l’objet Ink. La zone de signature est invalidée et les informations de prénom et de nom sont récupérées à partir du document XML.

// This object encodes our byte data to a UTF8 string
UTF8Encoding utf8 = new UTF8Encoding();

XmlDocument xd = new XmlDocument();
XmlNodeList nodes;
Ink loadedInk = new Ink();

// Load the XML data into a DOM
xd.Load(s);

// Get the data in the ink node
nodes = xd.GetElementsByTagName("Ink");

// load the ink into a new ink object
// After an ink object has been "dirtied" it can never load ink again
if (0 != nodes.Count)
    loadedInk.Load(utf8.GetBytes(nodes[0].InnerXml));

// temporarily disable the ink collector and swap ink objects
ic.Enabled = false;
ic.Ink = loadedInk;
ic.Enabled = true;

// Repaint the inkable region
Signature.Invalidate();

// Get the data in the FirstName node
nodes = xd.GetElementsByTagName("FirstName");
if (0 != nodes.Count)
{
    FirstNameBox.Text = nodes[0].InnerXml;
}
else
{
    FirstNameBox.Text = String.Empty;
}

// Get the data in the LastName node
nodes = xd.GetElementsByTagName("LastName");
if (0 != nodes.Count)
{
    LastNameBox.Text = nodes[0].InnerXml;
}
else
{
    LastNameBox.Text = String.Empty;
}

Fermeture du formulaire

La méthode Dispose du formulaire supprime l’objet InkCollector .