File: Screenshot\Screenshot.shared.cs
Web Access
Project: src\src\Essentials\src\Essentials.csproj (Microsoft.Maui.Essentials)
#nullable enable
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Maui.ApplicationModel;
 
namespace Microsoft.Maui.Media
{
	/// <summary>
	/// The Screenshot API lets you take a capture of the current displayed screen of the app.
	/// </summary>
	public interface IScreenshot
	{
		/// <summary>
		/// Gets a value indicating whether capturing screenshots is supported on this device.
		/// </summary>
		bool IsCaptureSupported { get; }
 
		/// <summary>
		/// Captures a screenshot of the current screen of the running application.
		/// </summary>
		/// <returns>An instance of <see cref="IScreenshotResult"/> with information about the captured screenshot.</returns>
		Task<IScreenshotResult> CaptureAsync();
	}
 
	/// <summary>
	/// Provides abstractions for the platform screenshot methods when using Screenshot.
	/// </summary>
	public interface IPlatformScreenshot : IScreenshot
	{
#if ANDROID
		/// <summary>
		/// Captures a screenshot of the specified activity.
		/// </summary>
		/// <param name="activity">The activity to capture.</param>
		/// <returns>An instance of <see cref="IScreenshotResult"/> with information about the captured screenshot.</returns>
		Task<IScreenshotResult> CaptureAsync(Android.App.Activity activity);
 
		/// <summary>
		/// Captures a screenshot of the specified view.
		/// </summary>
		/// <param name="view">The view to capture.</param>
		/// <returns>An instance of <see cref="IScreenshotResult"/> with information about the captured screenshot.</returns>
		Task<IScreenshotResult?> CaptureAsync(Android.Views.View view);
#elif IOS || MACCATALYST
		/// <summary>
		/// Captures a screenshot of the specified window.
		/// </summary>
		/// <param name="window">The window to capture.</param>
		/// <returns>An instance of <see cref="IScreenshotResult"/> with information about the captured screenshot.</returns>
		Task<IScreenshotResult> CaptureAsync(UIKit.UIWindow window);
 
		/// <summary>
		/// Captures a screenshot of the specified view.
		/// </summary>
		/// <param name="view">The view to capture.</param>
		/// <returns>An instance of <see cref="IScreenshotResult"/> with information about the captured screenshot.</returns>
		Task<IScreenshotResult?> CaptureAsync(UIKit.UIView view);
 
		/// <summary>
		/// Captures a screenshot of the specified layer.
		/// </summary>
		/// <param name="layer">The layer to capture.</param>
		/// <param name="skipChildren">Specifies whether to include the child layers or not.</param>
		/// <returns>An instance of <see cref="IScreenshotResult"/> with information about the captured screenshot.</returns>
		Task<IScreenshotResult?> CaptureAsync(CoreAnimation.CALayer layer, bool skipChildren);
#elif WINDOWS
		/// <summary>
		/// Captures a screenshot of the specified window.
		/// </summary>
		/// <param name="window">The window to capture.</param>
		/// <returns>An instance of <see cref="IScreenshotResult"/> with information about the captured screenshot.</returns>
		Task<IScreenshotResult> CaptureAsync(UI.Xaml.Window window);
 
		/// <summary>
		/// Captures a screenshot of the specified user-interface element.
		/// </summary>
		/// <param name="element">The user-interface element to capture.</param>
		/// <returns>An instance of <see cref="IScreenshotResult"/> with information about the captured screenshot.</returns>
		Task<IScreenshotResult?> CaptureAsync(UI.Xaml.UIElement element);
#elif TIZEN

		/// <summary>
		/// Captures a screenshot of the specified window.
		/// </summary>
		/// <param name="window">The window to capture.</param>
		/// <returns>An instance of <see cref="IScreenshotResult"/> with information about the captured screenshot.</returns>
		Task<IScreenshotResult> CaptureAsync(Tizen.NUI.Window window);
 
		/// <summary>
		/// Captures a screenshot of the specified view.
		/// </summary>
		/// <param name="view">The view to capture.</param>
		/// <returns>An instance of <see cref="IScreenshotResult"/> with information about the captured screenshot.</returns>
		Task<IScreenshotResult?> CaptureAsync(Tizen.NUI.BaseComponents.View view);
#endif
	}
 
	/// <summary>
	/// A representation of a screenshot, as a result of a screenshot captured by the user.
	/// </summary>
	public interface IScreenshotResult
	{
		/// <summary>
		/// The width of this screenshot in pixels.
		/// </summary>
		int Width { get; }
 
		/// <summary>
		/// The height of this screenshot in pixels.
		/// </summary>
		int Height { get; }
 
		/// <summary>
		/// Opens a <see cref="Stream"/> to the corresponding screenshot file on the filesystem.
		/// </summary>
		/// <param name="format">The image format used to read this screenshot.</param>
		/// <param name="quality">The quality used to read this screenshot. Quality only applies when <see cref="ScreenshotFormat.Jpeg"/> is used.</param>
		/// <returns>A <see cref="Stream"/> containing the screenshot file data.</returns>
		Task<Stream> OpenReadAsync(ScreenshotFormat format = ScreenshotFormat.Png, int quality = 100);
 
		/// <summary>
		/// 
		/// </summary>
		/// <param name="destination">The destination <see cref="Stream"/> to copy the screenshot file data to.</param>
		/// <param name="format">The image format used to copy this screenshot.</param>
		/// <param name="quality">The quality used to copy this screenshot. Quality only applies when <see cref="ScreenshotFormat.Jpeg"/> is used.</param>
		/// <returns>A <see cref="Task"/> object with the current status of the asynchronous operation.</returns>
		Task CopyToAsync(Stream destination, ScreenshotFormat format = ScreenshotFormat.Png, int quality = 100);
	}
 
	/// <summary>
	/// The Screenshot API lets you take a capture of the current displayed screen of the app.
	/// </summary>
	public static partial class Screenshot
	{
		/// <summary>
		/// Gets a value indicating whether capturing screenshots is supported on this device.
		/// </summary>
		public static bool IsCaptureSupported
			=> Default.IsCaptureSupported;
 
		/// <summary>
		/// Captures a screenshot of the current screen of the running application.
		/// </summary>
		/// <returns>An instance of <see cref="IScreenshotResult"/> with information about the captured screenshot.</returns>
		/// <exception cref="FeatureNotSupportedException">Thrown when <see cref="IsCaptureSupported"/> is <see langword="false"/>.</exception>
		public static Task<IScreenshotResult> CaptureAsync()
		{
			if (!IsCaptureSupported)
				throw new FeatureNotSupportedException();
 
			return Default.CaptureAsync();
		}
 
		static IScreenshot? defaultImplementation;
 
		/// <summary>
		/// Provides the default implementation for static usage of this API.
		/// </summary>
		public static IScreenshot Default =>
			defaultImplementation ??= new ScreenshotImplementation();
 
		internal static void SetDefault(IScreenshot? implementation) =>
			defaultImplementation = implementation;
	}
 
	/// <summary>
	/// This class contains static extension methods for use with <see cref="IScreenshot"/>.
	/// </summary>
	public static class ScreenshotExtensions
	{
		static IPlatformScreenshot AsPlatform(this IScreenshot screenshot)
		{
			if (screenshot is not IPlatformScreenshot platform)
				throw new PlatformNotSupportedException("This implementation of IScreenshot does not implement IPlatformScreenshot.");
 
			return platform;
		}
 
#if ANDROID
		/// <summary>
		/// Captures a screenshot of the specified activity.
		/// </summary>
		/// <param name="screenshot">The object this method is invoked on.</param>
		/// <param name="activity">The activity to capture.</param>
		/// <returns>An instance of <see cref="IScreenshotResult"/> with information about the captured screenshot.</returns>
		public static Task<IScreenshotResult> CaptureAsync(this IScreenshot screenshot, Android.App.Activity activity) =>
			screenshot.AsPlatform().CaptureAsync(activity);
 
		/// <summary>
		/// Captures a screenshot of the specified view.
		/// </summary>
		/// <param name="screenshot">The object this method is invoked on.</param>
		/// <param name="view">The view to capture.</param>
		/// <returns>An instance of <see cref="IScreenshotResult"/> with information about the captured screenshot.</returns>
		public static Task<IScreenshotResult?> CaptureAsync(this IScreenshot screenshot, Android.Views.View view) =>
			screenshot.AsPlatform().CaptureAsync(view);
 
#elif IOS || MACCATALYST
		/// <summary>
		/// Captures a screenshot of the specified window.
		/// </summary>
		/// <param name="screenshot">The object this method is invoked on.</param>
		/// <param name="window">The window to capture.</param>
		/// <returns>An instance of <see cref="IScreenshotResult"/> with information about the captured screenshot.</returns>
		public static Task<IScreenshotResult> CaptureAsync(this IScreenshot screenshot, UIKit.UIWindow window) =>
			screenshot.AsPlatform().CaptureAsync(window);
 
		/// <summary>
		/// Captures a screenshot of the specified view.
		/// </summary>
		/// <param name="screenshot">The object this method is invoked on.</param>
		/// <param name="view">The view to capture.</param>
		/// <returns>An instance of <see cref="IScreenshotResult"/> with information about the captured screenshot.</returns>
		public static Task<IScreenshotResult?> CaptureAsync(this IScreenshot screenshot, UIKit.UIView view) =>
			screenshot.AsPlatform().CaptureAsync(view);
 
		/// <summary>
		/// Captures a screenshot of the specified layer.
		/// </summary>
		/// <param name="screenshot">The object this method is invoked on.</param>
		/// <param name="layer">The layer to capture.</param>
		/// <param name="skipChildren">Specifies whether to include the child layers or not.</param>
		/// <returns>An instance of <see cref="IScreenshotResult"/> with information about the captured screenshot.</returns>
		public static Task<IScreenshotResult?> CaptureAsync(this IScreenshot screenshot, CoreAnimation.CALayer layer, bool skipChildren) =>
			screenshot.AsPlatform().CaptureAsync(layer, skipChildren);
 
#elif WINDOWS
		/// <summary>
		/// Captures a screenshot of the specified window.
		/// </summary>
		/// <param name="screenshot">The object this method is invoked on.</param>
		/// <param name="window">The window to capture.</param>
		/// <returns>An instance of <see cref="IScreenshotResult"/> with information about the captured screenshot.</returns>
		public static Task<IScreenshotResult> CaptureAsync(this IScreenshot screenshot, UI.Xaml.Window window) =>
			screenshot.AsPlatform().CaptureAsync(window);
 
		/// <summary>
		/// Captures a screenshot of the specified user-interface element.
		/// </summary>
		/// <param name="screenshot">The object this method is invoked on.</param>
		/// <param name="element">The user-interface element to capture.</param>
		/// <returns>An instance of <see cref="IScreenshotResult"/> with information about the captured screenshot.</returns>
		public static Task<IScreenshotResult?> CaptureAsync(this IScreenshot screenshot, UI.Xaml.UIElement element) =>
			screenshot.AsPlatform().CaptureAsync(element);
 
#elif TIZEN
		/// <summary>
		/// Captures a screenshot of the specified window.
		/// </summary>
		/// <param name="screenshot">The object this method is invoked on.</param>
		/// <param name="window">The window to capture.</param>
		/// <returns>An instance of <see cref="IScreenshotResult"/> with information about the captured screenshot.</returns>
		public static Task<IScreenshotResult> CaptureAsync(this IScreenshot screenshot, Tizen.NUI.Window window) =>
			screenshot.AsPlatform().CaptureAsync(window);
 
		/// <summary>
		/// Captures a screenshot of the specified view.
		/// </summary>
		/// <param name="screenshot">The object this method is invoked on.</param>
		/// <param name="view">The view to capture.</param>
		/// <returns>An instance of <see cref="IScreenshotResult"/> with information about the captured screenshot.</returns>
		public static Task<IScreenshotResult?> CaptureAsync(this IScreenshot screenshot, Tizen.NUI.BaseComponents.View view) =>
			screenshot.AsPlatform().CaptureAsync(view);
#endif
	}
 
	/// <summary>
	/// The possible formats for reading screenshot images.
	/// </summary>
	public enum ScreenshotFormat
	{
		/// <summary>Read the screenshot image as a PNG image.</summary>
		Png,
 
		/// <summary>Read the screenshot image as a JPEG image.</summary>
		Jpeg
	}
 
	/// <summary>
	/// A representation of a screenshot, as a result of a screenshot captured by the user.
	/// </summary>
	partial class ScreenshotResult : IScreenshotResult
	{
		public int Width { get; }
 
		public int Height { get; }
 
		public Task<Stream> OpenReadAsync(ScreenshotFormat format = ScreenshotFormat.Png, int quality = 100)
			=> PlatformOpenReadAsync(format, quality);
 
		public Task CopyToAsync(Stream destination, ScreenshotFormat format = ScreenshotFormat.Png, int quality = 100)
			=> PlatformCopyToAsync(destination, format, quality);
	}
}