/ c#

How to: Obtener imágenes desde elementos de XAML

Saben hace algún tiempo tuve la necesidad de agregar información a una imagen así que buscando en MSDN me he encontrado con la clase RenderTargetBitMap, esta clase nos permite obtener imágenes a partir de controles XAML especialmente útiles cuando deseamos generar thumbnail o para compartir una imagen de estos controles con otras aplicaciones. RenderTargetBitMap nos permite generar estas imágenes a través de su método RenderAsync.

Veamos un ejemplo sencillo en el cual agregaremos datos adicionales a una imagen obtenida por la cámara. Como primer paso crearemos una interfaz de usuario que nos permitirá conectarnos a la cámara, mostrará la imagen y agregar la fecha y hora.

RenderTargetBitMap

Una vez hemos realizado esto agregaremos dos botones a la interfaz de usuario, el primero para tomar una foto y el segundo para guardar la imagen resultante, para esto haremos uso del evento clic del  primer botón y agregaremos el siguiente código.

private async void btnTakePhoto_Click(object sender, RoutedEventArgs e) 
{ 
CameraCaptureUI cameraUi = new CameraCaptureUI(); cameraUi.PhotoSettings.AllowCropping = false; cameraUi.PhotoSettings.MaxResolution = CameraCaptureUIMaxPhotoResolution.MediumXga; 
Windows.Storage.StorageFile capturedMedia = await cameraUi.CaptureFileAsync(CameraCaptureUIMode.Photo); 

using (var streamCamera = await capturedMedia.OpenAsync(FileAccessMode.Read)) 
{ 
BitmapImage bitmapCamera = new BitmapImage(); bitmapCamera.SetSource(streamCamera); imgSource.Source = bitmapCamera; txtDate.Text = DateTime.Now.ToString("D"); 
}
}

En el segundo botón agregaremos el siguiente código que nos va a permitir crear nuestra imagen a partir de nuestros controles para posteriormente guardarlos.

private async void btnSave_Click(object sender, RoutedEventArgs e) 
{
 FileSavePicker picker = new FileSavePicker(); 
picker.FileTypeChoices.Add("JPG File", new List<string>() { ".jpg" });
 StorageFile file = await picker.PickSaveFileAsync(); if (file != null) 
{ 
RenderTargetBitmap renderTargetBitMap = new RenderTargetBitmap(); 
//With this method we can make our XAML elements in an image. await renderTargetBitMap.RenderAsync(grdRender, (int)grdRender.Width, (int)grdRender.Height); var pixels = await renderTargetBitMap.GetPixelsAsync(); 

using (IRandomAccessStream randomAccessStream = await file.OpenAsync(FileAccessMode.ReadWrite))
 { 
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, randomAccessStream); 
byte[] bytes = pixels.ToArray(); 
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint)renderTargetBitMap.PixelWidth, (uint)renderTargetBitMap.PixelHeight, 96, 96, bytes); await encoder.FlushAsync(); 
}
}
}

Con esto obtendremos el siguiente resultado y de una forma bastante sencilla habremos logrado nuestro objetivo.

Albert

La solución como ya es costumbre se las dejo en github, espero te resulte útil, nos vemos en el siguiente post, ¡saludos!

Saturnino Pimentel

Saturnino Pimentel

Microsoft MVP, consultor, blogger y conferencista. Saturnino es el cofundador de la comunidad de programadores c# y el meetup de c# de la ciudad de México además de participar con otras comunidades.

Read More

Suscríbete a la lista de correos :)

* indicates required