Saltar al contenido

Hacer captura de pantalla en xamarin.forms

Solución:

Echa un vistazo a esta publicación de blog de Daniel Hindrikes.

Asumiré que usa una PCL para su código compartido.

Deberá crear una interfaz en su PCL. El lo llama IScreenshotManager. La declaración se ve así:

public interface IScreenshotManager
{
   Task<byte[]> CaptureAsync();
}

Ahora todas las plataformas tendrán su propia implementación para ello. Para iOS;

public class ScreenshotManager : IScreenshotManager
{
    public async System.Threading.Tasks.Task<byte[]> CaptureAsync()
    {
        var view = UIApplication.SharedApplication.KeyWindow.RootViewController.View;

        UIGraphics.BeginImageContext(view.Frame.Size);
        view.DrawViewHierarchy(view.Frame, true);
        var image = UIGraphics.GetImageFromCurrentImageContext();
        UIGraphics.EndImageContext();

        using(var imageData = image.AsPNG())
        {
            var bytes = new byte[imageData.Length];
            System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, bytes, 0, Convert.ToInt32(imageData.Length));
            return bytes;
        }

    }
}

Para Android:

public class ScreenshotManager : IScreenshotManager
{
    public static Activity Activity { get; set; }

    public async System.Threading.Tasks.Task<byte[]> CaptureAsync()
    {
        if(Activity == null)
        {
            throw new Exception("You have to set ScreenshotManager.Activity in your Android project");
        }

        var view = Activity.Window.DecorView;
        view.DrawingCacheEnabled = true;

        Bitmap bitmap = view.GetDrawingCache(true);

        byte[] bitmapData;

        using (var stream = new MemoryStream())
        {
            bitmap.Compress(Bitmap.CompressFormat.Png, 0, stream);
            bitmapData = stream.ToArray();
        }

        return bitmapData;
    }
}

Y para Windows Phone:

public class ScreenshotManager : IScreenshotManager
{
    public async Task<byte[]> CaptureAsync()
    {
        var rootFrame = Application.Current.RootVisual as PhoneApplicationFrame;

        var screenImage = new WriteableBitmap((int)rootFrame.ActualWidth, (int)rootFrame.ActualHeight);
        screenImage.Render(rootFrame, new MatrixTransform());
        screenImage.Invalidate();

        using (var stream = new MemoryStream())
        {
            screenImage.SaveJpeg(stream, screenImage.PixelWidth, screenImage.PixelHeight, 0, 100);
            var bytes = stream.ToArray();
            return bytes;
        }
    }
}

No olvide registrar las implementaciones específicas de su plataforma con el atributo que lo registra en el Servicio de Dependencia, así:

[assembly: Xamarin.Forms.Dependency (typeof (ScreenshotManager))]

Va por encima de la declaración del espacio de nombres.

Ahora, a partir de su código compartido, podrá obtener el byte[] de una captura de pantalla con una llamada como esta:

var screenshotBytes = DependencyService.Get<IScreenshotManager>().CaptureAsync();

Probablemente quieras comprobar si DependencyService.Get<IScreenshotManager>() no es null antes de usarlo.

Después de eso, puedes convertir tu byte[] en una imagen y haz lo que quieras con ella!

Implementación para UWP

public async Task<byte[]> CaptureAsync()
{
    //create and capture Window
    var renderTargetBitmap = new RenderTargetBitmap();
    await renderTargetBitmap.RenderAsync(Window.Current.Content);

    var pixelpuffer = await renderTargetBitmap.GetPixelsAsync();
    var logicalDpi = DisplayInformation.GetForCurrentView().LogicalDpi;

    IRandomAccessStream stream = new InMemoryRandomAccessStream();
    BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
    encoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Fant;
    encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, (uint)renderTargetBitmap.PixelWidth, (uint)renderTargetBitmap.PixelHeight, logicalDpi, logicalDpi, pixelpuffer.ToArray());
    await encoder.FlushAsync();
    byte[] resultingBuffer = new byte[stream.Size];

    await stream.ReadAsync(resultingBuffer.AsBuffer(), (uint)resultingBuffer.Length, InputStreamOptions.None);

    return resultingBuffer;

}
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *