Xamarin Android截屏

时间:2016-04-03 12:05:53

标签: c# android xamarin

我正在制作一个绘图的项目。

我不使用axml,因为我在一个名为filledpolygon的类中绘制并在MainActivity中调用该函数。我只想在我的项目中截取屏幕截图。有没有任何基本功能,我可以在onCreate方法中调用它?因此,当程序运行时,它将自动截取屏幕截图。除了Xamarin平台,我找到了答案。

2 个答案:

答案 0 :(得分:0)

在您的视图中,您可以运行以下代码,该代码将截取屏幕截图。我之前没有尝试在OnCreate()中运行它,因此您可能需要对其进行测试以确保视图已完全呈现。

*修改:根据this post,您可能无法在OnCreate()中运行此代码,因此您需要找到更好的地方。我无法弄清楚用户在他发布的链接中指的是什么帖子。

*编辑#2:刚发现Compress()未考虑质量参数(下面列为0),因为PNG无损,但如果您将格式更改为JPEG例如,您可能想要调高质量参数,因为您的图像看起来像垃圾。

public byte[] SaveImage() {

    DrawingCacheEnabled = true;                  //Enable cache for the next method below
    Bitmap bitmap       = GetDrawingCache(true); //Gets the image from the cache

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

    return bitmapData;
}

答案 1 :(得分:0)

由于不推荐使用Android 28 DrawingCacheEnabled,因此如果不使用它,我们将迫使视图在自定义画布上重绘,这会导致自定义控件和渲染器出现伪像,并且屏幕截图版本可能与我们在屏幕上看到的有所不同

在简单情况下仍可使用的旧代码是:

  public byte[] CaptureScreenshot()
    {
        var rootView =
            Xamarin.Essentials.Platform.CurrentActivity.Window.DecorView.RootView;

        rootView.DrawingCacheEnabled = true;

        using (var screenshot = Bitmap.CreateBitmap(
            rootView.Width,
            rootView.Height,
            Bitmap.Config.Argb8888))
        {
            var canvas = new Canvas(screenshot);


            rootView.Draw(canvas);

            using (var stream = new MemoryStream())
            {
                screenshot.Compress(Bitmap.CompressFormat.Png, 90, stream);
                return stream.ToArray();
            }
        }

        rootView.DrawingCacheEnabled = false;

    }

DrawingCacheEnabled过时的警告使我们重定向到使用PixelCopy。此方法与回调一起起作用,因此同步使用它可以提供一些帮助:

用法:

    public byte[] CaptureScreenshot()
    {
        using var helper = new ScreenshotHelper(
            Xamarin.Essentials.Platform.CurrentActivity.Window.DecorView.RootView,
            Xamarin.Essentials.Platform.CurrentActivity);

        byte[] buffer = null;
        bool wait = true;

        Task.Run(async () =>
        {
            helper.Capture((Bitmap bitmap) =>
            {
                try
                {

                    if (!helper.Error)
                    {
                        using (var stream = new MemoryStream())
                        {
                            bitmap.Compress(Bitmap.CompressFormat.Png, 90, stream);
                            buffer = stream.ToArray();
                        }
                    }

                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
                finally
                {
                    wait = false;
                }
            });

        }).ConfigureAwait(false);


        while (wait)
        {
            Task.Delay(10).Wait();
        }

        return buffer;
    }

助手:

    public class ScreenshotHelper : Java.Lang.Object, PixelCopy.IOnPixelCopyFinishedListener
    {


        public void OnPixelCopyFinished(int copyResult)
        {
            var stop = true;
            if (copyResult == (int) PixelCopyResult.Success)
            {
                Error = false;
                //todo CallbackGotScreenshot();
                _callback(_bitmap);
            }
            else
            {
                Error = true;
            }

            _callback(_bitmap);

        }

        public bool Error { get; protected set; }

        public ScreenshotHelper(Android.Views.View view, Activity activity)
        {
            _view = view;
            _activity = activity;

            _bitmap = Bitmap.CreateBitmap(
                _view.Width,
                _view.Height,
                Bitmap.Config.Argb8888);
        }

        // Starts a background thread and its {@link Handler}.
        private void StartBackgroundThread()
        {
            _BackgroundThread = new HandlerThread("ScreeshotMakerBackground");
            _BackgroundThread.Start();
            _BackgroundHandler = new Handler(_BackgroundThread.Looper);
        }

        // Stops the background thread and its {@link Handler}.
        private void StopBackgroundThread()
        {
            try
            {
                _BackgroundThread.QuitSafely();
                _BackgroundThread.Join();
                _BackgroundThread = null;
                _BackgroundHandler = null;
            }
            catch (Exception e)
            {
                //e.PrintStackTrace();
            }
        }

        public void Capture(Action<Bitmap> callback)
        {
            //var locationOfViewInWindow = new int[2];
            //_view.GetLocationInWindow(locationOfViewInWindow);
            _callback = callback;

            try
            {
                StartBackgroundThread();
                //todo could create-use background handler
                PixelCopy.Request(_activity.Window, _bitmap, this,
                    _BackgroundHandler);


            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
            finally
            {
                Task.Run(StopBackgroundThread);
            }
        }

        private Android.Views.View _view;
        private Activity _activity;
        private Bitmap _bitmap;
        private HandlerThread _BackgroundThread;
        private Handler _BackgroundHandler;
        private Action<Bitmap> _callback;


        public new void Dispose()
        {
            _bitmap?.Dispose();
            _bitmap= null;
            _activity = null;
            _view = null;
            _callback = null;

            base.Dispose();
        }

    }