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.
Windows-apps die Ondersteuning bieden voor Windows Ink, kunnen inktstreken serialiseren en deserialiseren naar een ISF-bestand (Ink Serialized Format). Het ISF-bestand is een GIF-afbeelding met extra metagegevens voor alle eigenschappen en gedrag van pennenstreken. Apps die niet voor inkt zijn ingeschakeld, kunnen de statische GIF-afbeelding bekijken, inclusief achtergrondtransparantie in het alfakanaal.
Opmerking
ISF is de meest compacte permanente weergave van inkt. Het kan worden ingesloten in een binaire documentindeling, zoals een GIF-bestand, of rechtstreeks op het Klembord worden geplaatst.
De Inktserialisatie Specificatie (ISF) kan worden gedownload vanuit het Microsoft Download Center.
Belangrijke API's: InkCanvas, Windows.UI.Input.Inking
Pennenstreken opslaan in een bestand
Hier laten we zien hoe u pennenstreken kunt opslaan die zijn getekend op een InkCanvas-besturingselement .
Download dit voorbeeld uit Pennenstreken opslaan en laden vanuit een ISF-bestand (Serialized Format)
Eerst hebben we de gebruikersinterface ingesteld.
De gebruikersinterface bevat knoppen voor "Opslaan", "Laden" en "Wissen", evenals de InkCanvas.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="HeaderPanel" Orientation="Horizontal" Grid.Row="0">
<TextBlock x:Name="Header"
Text="Basic ink store sample"
Style="{ThemeResource HeaderTextBlockStyle}"
Margin="10,0,0,0" />
<Button x:Name="btnSave"
Content="Save"
Margin="50,0,10,0"/>
<Button x:Name="btnLoad"
Content="Load"
Margin="50,0,10,0"/>
<Button x:Name="btnClear"
Content="Clear"
Margin="50,0,10,0"/>
</StackPanel>
<Grid Grid.Row="1">
<InkCanvas x:Name="inkCanvas" />
</Grid>
</Grid>
Vervolgens stellen we een eenvoudig invoergedrag voor inkt in.
De InkPresenter is geconfigureerd voor het interpreteren van invoergegevens van zowel pen als muis als pennenstreken (InputDeviceTypes) en listeners voor de klikgebeurtenissen op de knoppen worden gedeclareerd.
public MainPage()
{
this.InitializeComponent();
// Set supported inking device types.
inkCanvas.InkPresenter.InputDeviceTypes =
Windows.UI.Core.CoreInputDeviceTypes.Mouse |
Windows.UI.Core.CoreInputDeviceTypes.Pen;
// Listen for button click to initiate save.
btnSave.Click += btnSave_Click;
// Listen for button click to initiate load.
btnLoad.Click += btnLoad_Click;
// Listen for button click to clear ink canvas.
btnClear.Click += btnClear_Click;
}
Ten slotte slaan we de inkt op in de klik-gebeurtenishandler van de knop Opslaan .
Met Een FileSavePicker kan de gebruiker zowel het bestand als de locatie selecteren waar de inktgegevens worden opgeslagen.
Zodra een bestand is geselecteerd, openen we een IRandomAccessStream-stream die is ingesteld op ReadWrite.
Vervolgens roepen we SaveAsync aan om de pennenstreken te serialiseren die worden beheerd door de InkStrokeContainer naar de stream.
// Save ink data to a file.
private async void btnSave_Click(object sender, RoutedEventArgs e)
{
// Get all strokes on the InkCanvas.
IReadOnlyList<InkStroke> currentStrokes = inkCanvas.InkPresenter.StrokeContainer.GetStrokes();
// Strokes present on ink canvas.
if (currentStrokes.Count > 0)
{
// Let users choose their ink file using a file picker.
// Initialize the picker.
Windows.Storage.Pickers.FileSavePicker savePicker =
new Windows.Storage.Pickers.FileSavePicker();
savePicker.SuggestedStartLocation =
Windows.Storage.Pickers.PickerLocationId.DocumentsLibrary;
savePicker.FileTypeChoices.Add(
"GIF with embedded ISF",
new List<string>() { ".gif" });
savePicker.DefaultFileExtension = ".gif";
savePicker.SuggestedFileName = "InkSample";
// Show the file picker.
Windows.Storage.StorageFile file =
await savePicker.PickSaveFileAsync();
// When chosen, picker returns a reference to the selected file.
if (file != null)
{
// Prevent updates to the file until updates are
// finalized with call to CompleteUpdatesAsync.
Windows.Storage.CachedFileManager.DeferUpdates(file);
// Open a file stream for writing.
IRandomAccessStream stream = await file.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite);
// Write the ink strokes to the output stream.
using (IOutputStream outputStream = stream.GetOutputStreamAt(0))
{
await inkCanvas.InkPresenter.StrokeContainer.SaveAsync(outputStream);
await outputStream.FlushAsync();
}
stream.Dispose();
// Finalize write so other apps can update file.
Windows.Storage.Provider.FileUpdateStatus status =
await Windows.Storage.CachedFileManager.CompleteUpdatesAsync(file);
if (status == Windows.Storage.Provider.FileUpdateStatus.Complete)
{
// File saved.
}
else
{
// File couldn't be saved.
}
}
// User selects Cancel and picker returns null.
else
{
// Operation cancelled.
}
}
}
Opmerking
GIF is de enige bestandsindeling die wordt ondersteund voor het opslaan van inktgegevens. De LoadAsync-methode (gedemonstreerd in de volgende sectie) biedt echter wel ondersteuning voor aanvullende indelingen voor achterwaartse compatibiliteit.
Pennenstreken uit een bestand laden
Hier laten we zien hoe u pennenstreken uit een bestand laadt en weergeeft op een InkCanvas-besturingselement .
Download dit voorbeeld van pennenstreken opslaan en laden uit een Ink Serialized Format (ISF)-bestand
Eerst hebben we de gebruikersinterface ingesteld.
De UI bevat de knoppen "Opslaan", "Laden", "Wissen" en de InkCanvas.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="HeaderPanel" Orientation="Horizontal" Grid.Row="0">
<TextBlock x:Name="Header"
Text="Basic ink store sample"
Style="{ThemeResource HeaderTextBlockStyle}"
Margin="10,0,0,0" />
<Button x:Name="btnSave"
Content="Save"
Margin="50,0,10,0"/>
<Button x:Name="btnLoad"
Content="Load"
Margin="50,0,10,0"/>
<Button x:Name="btnClear"
Content="Clear"
Margin="50,0,10,0"/>
</StackPanel>
<Grid Grid.Row="1">
<InkCanvas x:Name="inkCanvas" />
</Grid>
</Grid>
Vervolgens stellen we enkele basisinvoergedragingen voor inkt in.
De InkPresenter is geconfigureerd voor het interpreteren van invoergegevens van zowel pen als muis als pennenstreken (InputDeviceTypes) en listeners voor de klikgebeurtenissen op de knoppen worden gedeclareerd.
public MainPage()
{
this.InitializeComponent();
// Set supported inking device types.
inkCanvas.InkPresenter.InputDeviceTypes =
Windows.UI.Core.CoreInputDeviceTypes.Mouse |
Windows.UI.Core.CoreInputDeviceTypes.Pen;
// Listen for button click to initiate save.
btnSave.Click += btnSave_Click;
// Listen for button click to initiate load.
btnLoad.Click += btnLoad_Click;
// Listen for button click to clear ink canvas.
btnClear.Click += btnClear_Click;
}
Ten slotte laden we de inkt in de klik-gebeurtenishandler van de knop Laden .
Met Een FileOpenPicker kan de gebruiker zowel het bestand als de locatie selecteren van waaruit de opgeslagen inktgegevens moeten worden opgehaald.
Zodra een bestand is geselecteerd, openen we een IRandomAccessStream-stream die is ingesteld op Lezen.
Vervolgens roepen we LoadAsync aan om de opgeslagen pennenstreken te lezen, de-serialiseren en te laden in de InkStrokeContainer. Als de pennenstreken in de InkStrokeContainer worden geladen, zorgt de InkPresenter ervoor dat ze onmiddellijk op de InkCanvas worden weergegeven.
Opmerking
Alle bestaande streken in de InkStrokeContainer worden gewist voordat nieuwe streken worden geladen.
// Load ink data from a file.
private async void btnLoad_Click(object sender, RoutedEventArgs e)
{
// Let users choose their ink file using a file picker.
// Initialize the picker.
Windows.Storage.Pickers.FileOpenPicker openPicker =
new Windows.Storage.Pickers.FileOpenPicker();
openPicker.SuggestedStartLocation =
Windows.Storage.Pickers.PickerLocationId.DocumentsLibrary;
openPicker.FileTypeFilter.Add(".gif");
// Show the file picker.
Windows.Storage.StorageFile file = await openPicker.PickSingleFileAsync();
// User selects a file and picker returns a reference to the selected file.
if (file != null)
{
// Open a file stream for reading.
IRandomAccessStream stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
// Read from file.
using (var inputStream = stream.GetInputStreamAt(0))
{
await inkCanvas.InkPresenter.StrokeContainer.LoadAsync(inputStream);
}
stream.Dispose();
}
// User selects Cancel and picker returns null.
else
{
// Operation cancelled.
}
}
Opmerking
GIF is de enige bestandsindeling die wordt ondersteund voor het opslaan van inktgegevens. De methode LoadAsync biedt echter wel ondersteuning voor de volgende indelingen voor compatibiliteit met eerdere versies.
| Formaat | Description |
|---|---|
| InkSerializedFormat | Hiermee wordt aangegeven dat inkt die met ISF wordt opgeslagen behouden blijft. Dit is de meest compacte permanente weergave van inkt. Het kan worden ingesloten in een binaire documentindeling of rechtstreeks op het Klembord worden geplaatst. |
| Base64InkSerializedFormat | Hiermee geeft u inkt op die behouden blijft door de ISF te coderen als een base64-stream. Deze indeling wordt opgegeven, zodat inkt rechtstreeks in een XML- of HTML-bestand kan worden gecodeerd. |
| Gif | Hiermee geeft u inkt op die behouden blijft met behulp van een GIF-bestand dat ISF bevat als metagegevens die zijn ingesloten in het bestand. Hierdoor kan inkt worden weergegeven in toepassingen die niet met inkt zijn ingeschakeld en de volledige inktkwaliteit behouden wanneer deze terugkeert naar een toepassing met inkt. Deze indeling is ideaal bij het transporteren van inktinhoud in een HTML-bestand en voor het gebruik ervan door inkt- en niet-inkttoepassingen. |
| Base64Gif | Hiermee specificeert u inkt die wordt gepreserveerd met behulp van een base64-gecodeerde versterkte GIF. Deze indeling wordt opgegeven wanneer inkt rechtstreeks in een XML- of HTML-bestand moet worden gecodeerd voor latere conversie naar een afbeelding. Een mogelijk gebruik hiervan is een XML-indeling die wordt gegenereerd om alle inktgegevens te bevatten en wordt gebruikt om HTML te genereren via Extensible Stylesheet Language Transformations (XSLT). |
Pennenstreken kopiëren en plakken met het Klembord
Hier laten we zien hoe u het Klembord kunt gebruiken om pennenstreken tussen apps over te dragen.
Om de functionaliteit van het klembord te ondersteunen, vereisen de ingebouwde knip- en kopieeropdrachten van InkStrokeContainer dat er een of meer pennenstreken zijn geselecteerd.
Wanneer de invoer is gemodificeerd met een penknop (of de rechtermuisknop), schakelen we in dit voorbeeld de selectie van pennenstreken in. Zie Doorstuurinvoer voor geavanceerde verwerking in pen- en stylusinteracties voor een volledig voorbeeld van hoe u streepselectie kunt implementeren.
Download dit voorbeeld van Pennenstreken opslaan en laden vanaf het klembord
Eerst hebben we de gebruikersinterface ingesteld.
De gebruikersinterface bevat de knoppen Knippen, Kopiëren, Plakken en Wissen, samen met de InkCanvas en een selectiecanvas.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="HeaderPanel" Orientation="Horizontal" Grid.Row="0">
<TextBlock x:Name="tbHeader"
Text="Basic ink store sample"
Style="{ThemeResource HeaderTextBlockStyle}"
Margin="10,0,0,0" />
<Button x:Name="btnCut"
Content="Cut"
Margin="20,0,10,0"/>
<Button x:Name="btnCopy"
Content="Copy"
Margin="20,0,10,0"/>
<Button x:Name="btnPaste"
Content="Paste"
Margin="20,0,10,0"/>
<Button x:Name="btnClear"
Content="Clear"
Margin="20,0,10,0"/>
</StackPanel>
<Grid x:Name="gridCanvas" Grid.Row="1">
<!-- Canvas for displaying selection UI. -->
<Canvas x:Name="selectionCanvas"/>
<!-- Inking area -->
<InkCanvas x:Name="inkCanvas"/>
</Grid>
</Grid>
Vervolgens stellen we enkele basisinvoergedragingen voor inkt in.
De InkPresenter is geconfigureerd voor het interpreteren van invoergegevens van zowel pen als muis als pennenstreken (InputDeviceTypes). Listeners voor de klikgebeurtenissen op de knoppen, evenals aanwijzer- en tekengebeurtenissen voor selectiefunctionaliteit, worden hier gedeclareerd.
Zie Doorgifte-invoer voor geavanceerde verwerking in pen- en stylusinteracties voor een volledig voorbeeld van het implementeren van streekselectie.
public MainPage()
{
this.InitializeComponent();
// Set supported inking device types.
inkCanvas.InkPresenter.InputDeviceTypes =
Windows.UI.Core.CoreInputDeviceTypes.Mouse |
Windows.UI.Core.CoreInputDeviceTypes.Pen;
// Listen for button click to cut ink strokes.
btnCut.Click += btnCut_Click;
// Listen for button click to copy ink strokes.
btnCopy.Click += btnCopy_Click;
// Listen for button click to paste ink strokes.
btnPaste.Click += btnPaste_Click;
// Listen for button click to clear ink canvas.
btnClear.Click += btnClear_Click;
// By default, the InkPresenter processes input modified by
// a secondary affordance (pen barrel button, right mouse
// button, or similar) as ink.
// To pass through modified input to the app for custom processing
// on the app UI thread instead of the background ink thread, set
// InputProcessingConfiguration.RightDragAction to LeaveUnprocessed.
inkCanvas.InkPresenter.InputProcessingConfiguration.RightDragAction =
InkInputRightDragAction.LeaveUnprocessed;
// Listen for unprocessed pointer events from modified input.
// The input is used to provide selection functionality.
inkCanvas.InkPresenter.UnprocessedInput.PointerPressed +=
UnprocessedInput_PointerPressed;
inkCanvas.InkPresenter.UnprocessedInput.PointerMoved +=
UnprocessedInput_PointerMoved;
inkCanvas.InkPresenter.UnprocessedInput.PointerReleased +=
UnprocessedInput_PointerReleased;
// Listen for new ink or erase strokes to clean up selection UI.
inkCanvas.InkPresenter.StrokeInput.StrokeStarted +=
StrokeInput_StrokeStarted;
inkCanvas.InkPresenter.StrokesErased +=
InkPresenter_StrokesErased;
}
Ten slotte implementeren we na het toevoegen van ondersteuning voor pennenstreken de klembordfunctionaliteit in de klik-gebeurtenishandlers van de knoppen Knippen, Kopiëren en Plakken .
Voor knippen roepen we CopySelectedToClipboard eerst aan op de InkStrokeContainer van de InkPresenter.
Vervolgens wordt DeleteSelected aangeroepen om de pennenstreken van het inktcanvas te verwijderen.
Ten slotte verwijderen we alle selectiestreken van het selectiecanvas.
private void btnCut_Click(object sender, RoutedEventArgs e)
{
inkCanvas.InkPresenter.StrokeContainer.CopySelectedToClipboard();
inkCanvas.InkPresenter.StrokeContainer.DeleteSelected();
ClearSelection();
}
// Clean up selection UI.
private void ClearSelection()
{
var strokes = inkCanvas.InkPresenter.StrokeContainer.GetStrokes();
foreach (var stroke in strokes)
{
stroke.Selected = false;
}
ClearDrawnBoundingRect();
}
private void ClearDrawnBoundingRect()
{
if (selectionCanvas.Children.Any())
{
selectionCanvas.Children.Clear();
boundingRect = Rect.Empty;
}
}
Voor kopiëren roepen we CopySelectedToClipboard aan op de InkStrokeContainer van de InkPresenter.
private void btnCopy_Click(object sender, RoutedEventArgs e)
{
inkCanvas.InkPresenter.StrokeContainer.CopySelectedToClipboard();
}
Voor plakken roepen we CanPasteFromClipboard aan om ervoor te zorgen dat de inhoud op het klembord kan worden geplakt op het inktcanvas.
Zo ja, dan roepen we PasteFromClipboard aan om de pennenstreken van het Klembord in te voegen in de InkStrokeContainer van InkPresenter, waardoor de pennenstreken vervolgens worden weergegeven op het inktcanvas.
private void btnPaste_Click(object sender, RoutedEventArgs e)
{
if (inkCanvas.InkPresenter.StrokeContainer.CanPasteFromClipboard())
{
inkCanvas.InkPresenter.StrokeContainer.PasteFromClipboard(
new Point(0, 0));
}
else
{
// Cannot paste from clipboard.
}
}
Verwante artikelen
Onderwerpvoorbeelden
- Pennenstreken opslaan en laden vanuit een ISF-bestand (Ink Serialized Format)
- Pennenstreken vanaf het klembord opslaan en laden
Andere voorbeelden
Windows developer