Guest post: Fare il crop delle immagini usando l’app Foto di Windows 10

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;

}

}