Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Le app di Windows che supportano Windows Ink possono serializzare e deserializzare i tratti di inchiostro in un file ISF (Ink Serialized Format). Il file ISF è un'immagine GIF con metadati aggiuntivi per tutte le proprietà e i comportamenti del tratto input penna. Le applicazioni non abilitate all'input penna possono visualizzare l'immagine GIF statica, compresa la trasparenza dello sfondo attraverso il canale alfa.
Annotazioni
ISF è la rappresentazione persistente più compatta dell'inchiostro. Può essere incorporato in un formato di documento binario, ad esempio un file GIF, o posizionato direttamente negli Appunti.
La specifica ISF (Ink Serialized Format) può essere scaricata dal Microsoft Download Center .
API importanti: InkCanvas, Windows.UI.Input.Inking
Salvare i tratti di inchiostro in un file
** Qui, dimostriamo come salvare i tratti di inchiostro disegnati su un controllo InkCanvas .
Scaricare questo esempio da Salvare e caricare tratti d'inchiostro da un file ISF (Ink Serialized Format)
Prima di tutto, impostiamo l'interfaccia utente.
L'interfaccia utente include i pulsanti "Salva", "Carica" e "Cancella" e il 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>
Verranno quindi impostati alcuni comportamenti di input di inchiostro di base.
Il InkPresenter
è configurato per interpretare i dati di input sia da penna che da mouse come tratti di inchiostro ( ), e i listener per gli eventi di clic sui pulsanti sono dichiarati.InputDeviceTypes
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;
}
Infine, salviamo l'inchiostro digitale nel gestore dell'evento di click del pulsante Salva.
Un FileSavePicker consente all'utente di selezionare il file e il percorso in cui vengono salvati i dati dell'inchiostro.
Dopo aver selezionato un file, si apre un flusso IRandomAccessStream impostato su ReadWrite.
Chiamiamo quindi SaveAsync per serializzare i tratti di inchiostro gestiti dal InkStrokeContainer nel flusso.
// 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.
}
}
}
Annotazioni
GIF è l'unico formato di file supportato per il salvataggio dei dati di inchiostro. Tuttavia, il metodo LoadAsync (illustrato nella sezione successiva) supporta formati aggiuntivi per la compatibilità con le versioni precedenti.
Caricare tratti di inchiostro da un file
In questo caso viene illustrato come caricare i tratti di inchiostro da un file e renderli su un controllo InkCanvas .
Scaricare questo esempio da Salvare e caricare tratti d'inchiostro da un file ISF (Ink Serialized Format)
Prima di tutto, impostiamo l'interfaccia utente.
L'interfaccia utente include i pulsanti "Salva", "Carica" e "Cancella" e il 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>
Verranno quindi impostati alcuni comportamenti di input di inchiostro di base.
Il InkPresenter
è configurato per interpretare i dati di input sia da penna che da mouse come tratti di inchiostro ( ), e i listener per gli eventi di clic sui pulsanti sono dichiarati.InputDeviceTypes
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;
}
Infine, carichiamo l'inchiostro nel gestore dell'evento click del pulsante Load.
Un FileOpenPicker consente all'utente di selezionare sia il file che il percorso da cui recuperare i dati dell'input penna salvati.
Dopo aver selezionato un file, si apre un flusso di IRandomAccessStream impostato su Read.
Viene quindi chiamata la funzione LoadAsync per leggere, deserializzare e caricare i tratti di inchiostro salvati nel InkStrokeContainer. Il caricamento dei tratti nel InkStrokeContainer
fa sì che l’InkPresenter esegua immediatamente il rendering dei tratti sul .InkCanvas Annotazioni
Tutti i tratti esistenti in InkStrokeContainer vengono cancellati prima del caricamento di nuovi tratti.
// 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.
}
}
Annotazioni
GIF è l'unico formato di file supportato per il salvataggio dei dati di inchiostro. Tuttavia, il metodo LoadAsync supporta i formati seguenti per la compatibilità con le versioni precedenti.
Formato | Descrizione |
---|---|
InkSerializedFormat | Specifica l'inchiostro che viene mantenuto tramite ISF. Questa è la rappresentazione persistente più compatta dell'inchiostro. Può essere incorporato all'interno di un formato di documento binario o posizionato direttamente sulla clipboard. |
Base64InkSerializedFormat | Specifica l'inchiostro che è reso persistente tramite la codifica dell'ISF come flusso base64. Questo formato viene fornito in modo che l'inchiostro possa essere codificato direttamente in un file XML o HTML. |
Gif | Specifica l'inchiostro persistente utilizzando un file GIF che contiene ISF come metadati incorporati. Questo consente di visualizzare l'inchiostro nelle applicazioni non abilitate per l'inchiostro e di mantenere la piena fedeltà dell'inchiostro quando ritorna in un'applicazione abilitata per l'inchiostro. Questo formato è ideale per il trasporto del contenuto inchiostro all'interno di un file HTML e per renderlo utilizzabile sia dalle applicazioni di inchiostro sia da quelle non di inchiostro. |
Base64Gif | Specifica l'inchiostro che viene conservato utilizzando una GIF codificata base64 potenziata. Questo formato è fornito quando l'inchiostro deve essere codificato direttamente in un file XML o HTML per una conversione successiva in un'immagine. Un possibile utilizzo di questo è in un formato XML generato per contenere tutte le informazioni sugli inchiostri e utilizzato per generare codice HTML tramite Extensible Stylesheet Language Transformations (XSLT). |
Copiare e incollare i tratti di inchiostro con la clipboard
In questo caso viene illustrato come usare la clipboard per trasferire tratti di inchiostro tra app.
Per supportare la funzionalità degli Appunti, i comandi incorporati InkStrokeContainer taglia e copia richiedono la selezione di uno o più tratti di penna.
Per questo esempio, la selezione del tratto viene abilitata quando l'input è modificato con un pulsante del barilotto della penna (o il pulsante destro del mouse). Per un esempio completo di come implementare la selezione del tratto, vedere Input pass-through per l'elaborazione avanzata nelle interazioni con penna e stilo .
Scaricare questo esempio da Salvare e caricare tratti input penna dagli Appunti
Prima di tutto, impostiamo l'interfaccia utente.
L'interfaccia utente include i pulsanti "Taglia", "Copia", "Incolla" e "Cancella", insieme a InkCanvas e a un'area di selezione.
<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>
Verranno quindi impostati alcuni comportamenti di input di inchiostro di base.
Il InkPresenter è configurato per interpretare i dati di input sia dalla penna che dal mouse come tratti di inchiostro (InputDeviceTypes). I listener per gli eventi clic sui pulsanti, nonché per gli eventi di puntamento e tratto relativi alla funzione di selezione, vengono dichiarati qui.
Per un esempio completo di come implementare la selezione del tratto, vedere Input pass-through per l'elaborazione avanzata nelle interazioni con penna e stilo .
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;
}
Infine, dopo aver aggiunto il supporto per la selezione dei tratti, implementiamo la funzionalità degli appunti nei gestori degli eventi di click dei pulsanti Taglia, Copiae Incolla.
Per il comando 'cut', chiamiamo prima CopySelectedToClipboard sul InkStrokeContainer del InkPresenter.
Chiamiamo quindi DeleteSelected per rimuovere i tratti dall'area di disegno a inchiostro.
Infine, eliminiamo tutti i tratti di selezione dalla tela di selezione.
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;
}
}
Per la copia, è sufficiente chiamare CopySelectedToClipboard sul InkStrokeContainer del InkPresenter.
private void btnCopy_Click(object sender, RoutedEventArgs e)
{
inkCanvas.InkPresenter.StrokeContainer.CopySelectedToClipboard();
}
Per l'incolla, chiamiamo CanPasteFromClipboard per assicurarci che il contenuto negli Appunti possa essere incollato sulla tela di inchiostro.
In tal caso, utilizziamo PasteFromClipboard per inserire i tratti di inchiostro dagli Appunti nel InkStrokeContainer del InkPresenter, che quindi renderizza i tratti nell'area di disegno dell'inchiostro.
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.
}
}
Articoli correlati
Esempi di argomenti
- Salvare e caricare tratti di inchiostro da un file di formato ISF (Ink Serialized Format)
- Salvare e caricare tratti di inchiostro dagli appunti
Altri esempi