Making screen capture in xamarin.forms

前端 未结 2 1747
盖世英雄少女心
盖世英雄少女心 2020-12-05 21:52

Is there a package that does screen capture in xamarin.forms ?

I need also to capture google maps screen shots

相关标签:
2条回答
  • 2020-12-05 22:36

    Implementation for 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;
    
    }
    
    0 讨论(0)
  • 2020-12-05 22:38

    Check out this blog post by Daniel Hindrikes.

    I'm going to assume that you use a PCL for your shared code.

    You will need to create an interface in your PCL. He calls it IScreenshotManager. The declaration looks like this:

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

    Now all platforms will have their own implementation for it. For 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;
            }
    
        }
    }
    

    For 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;
        }
    }
    

    And for 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;
            }
        }
    }
    

    Don't forget to register your platform specific implementations with the attribute which registers it with the Dependency Service, like this:

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

    It goes above the namespace declaration.

    Now from your shared code you would be able to get the byte[] of a screenshot with a call like this:

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

    You probably want to check if DependencyService.Get<IScreenshotManager>() isn't null before using it.

    After that you can turn your byte[] into an image and do whatever you like with it!

    0 讨论(0)
提交回复
热议问题