Questo post è stato scritto da Fela Ameghino, developer Windows Phone di fama internazionale.
Una delle feature più interessanti di Silverlight per Windows Phone erano sicuramente i Task, che ci permettevano di lanciare alcune app di sistema per fare eseguire all'utente alcune semplici operazioni.
Uno dei Task più utilizzati era il PhotoChooserTask, che con l'avvento del Windows Runtime è stato sostituito dalla classe FileOpenPicker. Quest'ultima ci dà più flessibilità, permettendoci di selezionare altre tipologie di file oltre alle immagini, ma perde una funzionalità molto utile del vecchio Task, cioè la possibilità di far ritagliare l'immagine all'utente per averla delle dimensioni che preferisce
Grazie a Windows 10 troviamo una soluzione al problema, utilizzando la nuova app Foto e il nuovo metodo Launcher.LaunchUriForResults. Se ricordate, già nelle precedenti versioni di Windows e Windows Phone era possibile utilizzare il meccanismo di Protocol Activation per lanciare una determinata app, ma questa nuova versione ci permette anche di ricevere una risposta dalla stessa.
Il protocollo che dobbiamo utilizzare è microsoft.windows.photos.crop: e richiede i seguenti parametri:
CropWidthPixels | int | Larghezza dell'immagine che vogliamo ottenere |
CropHeightPixels | int | Altezza dell'immagine che vogliamo ottenere |
EllipticalCrop | bool | L'indicatore visuale del crop può essere rotondo (Il risultato sarà comunque rettangolare) |
ShowCamera | bool | Ci permette di mostrare un bottone per permettere all'utente di scattare una foto sul momento |
InputToken | string | |
DestinationToken | string |
Dato che l'app Foto non ha la possibilità di prendersi a carico l'immagine ritagliata (visto che per lei è un file temporaneo) siamo noi a doverle dire dove salvare quest'ultima e, non potendo passare direttamente come parametro lo StorageFile dobbiamo usare SharedStorageAccessManager.AddFile. Quest'ultimo ci consente di ottenere un token (riscattabile tramite RedeemTokenForFileAsync) che ci permette di condividere più facilmente il file con altre app. Una volta ottenuto il token dobbiamo passarlo tramite il parametro DestinationToken.
Possiamo usare lo stesso procedimento per il parametro opzionale InputToken, che ci permette di passare direttamente all'app l'immagine da ritagliare. Quest'ultimo può rivelarsi utile se volessimo far scegliere ad esempio l'immagine tramite FileOpenPicker, o la ottenessimo tramite contratto Share.
Una volta passati i parametri e attesa l'interazione dell'utente, l'app ci restituirà un parametro "Status" dal valore "OK" per confermarci il completamento dell'operazione. A questo punto potremo aprire il nostro file per utilizzare l'immagine ottenuta.
Ecco un esempio completo:
private async Task CropImage()
{
// Creo il file di destinazione e ottengo il token per la condivisione
var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("Cropped.jpg", CreationCollisionOption.ReplaceExisting);
var token = SharedStorageAccessManager.AddFile(file);
// Specifico l'app che deve aprirsi tramite LaunchUriForResults
var options = new LauncherOptions();
options.TargetApplicationPackageFamilyName = "Microsoft.Windows.Photos_8wekyb3d8bbwe";
// Specifico tutti i parametri necessari
var parameters = new ValueSet();
parameters.Add("CropWidthPixels", 500);
parameters.Add("CropHeightPixels", 500);
parameters.Add("EllipticalCrop", true);
parameters.Add("ShowCamera", false);
parameters.Add("DestinationToken", token);
// Lancio l'app e attendo la sua risposta
var result = await Launcher.LaunchUriForResultsAsync(new Uri("microsoft.windows.photos.crop:"), options, parameters);
// Verifico che l'utente abbia davvero ritagliato l'immagine
if (result.Status == LaunchUriStatus.Success && result.Result != null)
{
// Carico l'immagine
var stream = await file.OpenReadAsync();
var bitmap = new BitmapImage();
await bitmap.SetSourceAsync(stream);
// E la imposto come Source di un controllo Image
Preview.Source = bitmap;
}
}
read full article