Example #1
0
		/// <summary>
		/// Captures page screenshot.
		/// </summary>
		/// <param name="webview">The WebView control.</param>
		/// <param name="settings">The capture settings or null.</param>
		/// <param name="targetStream">A stream to save the captured image to.</param>
		/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
		/// <returns>The task object representing the asynchronous operation.</returns>
		/// <exception cref="ArgumentNullException">
		/// <paramref name="webview"/> or <paramref name="targetStream"/> is null.
		/// </exception>
		/// <exception cref="DevToolsProtocolException">
		/// An error occurred while trying to execute a DevTools Protocol method.
		/// </exception>
		/// <exception cref="InvalidOperationException">Other error occurred.</exception>
		public static async Task CaptureScreenshotAsync(this IChromiumWebView webview, PageCaptureSettings settings, Stream targetStream, CancellationToken cancellationToken)
		{
			if (webview is null)
				throw new ArgumentNullException(nameof(webview));

			if (targetStream is null)
				throw new ArgumentNullException(nameof(targetStream));

			CefDictionaryValue args;
			if (settings is null)
			{
				args = null;
			}
			else
			{
				args = new CefDictionaryValue();
				if (settings.Format == ImageCompressionFormat.Jpeg)
				{
					args.SetString("format", "jpeg");
					if (settings.Quality.HasValue)
						args.SetInt("quality", settings.Quality.Value);
				}
				if (!settings.FromSurface)
					args.SetBool("fromSurface", false);
				if (settings.Viewport != null)
				{
					PageViewport viewport = settings.Viewport;
					var viewportDict = new CefDictionaryValue();
					viewportDict.SetDouble("x", viewport.X);
					viewportDict.SetDouble("y", viewport.Y);
					viewportDict.SetDouble("width", viewport.Width);
					viewportDict.SetDouble("height", viewport.Height);
					viewportDict.SetDouble("scale", viewport.Scale);
					args.SetDictionary("clip", viewportDict);
				}
				if (settings.CaptureBeyondViewport)
					args.SetBool("captureBeyondViewport", true);
			}

			byte[] rv = (byte[])await ExecuteDevToolsMethodInternalAsync(webview, "Page.captureScreenshot", args, null, cancellationToken).ConfigureAwait(false);

			if (rv != null && rv.Length > 11 && rv[rv.Length - 1] == '}' && rv[rv.Length - 2] == '"'
				&& "{\"data\":\"".Equals(Encoding.ASCII.GetString(rv, 0, 9), StringComparison.Ordinal))
			{
				using (var input = new MemoryStream(rv, 9, rv.Length - 11))
				using (var base64Transform = new FromBase64Transform(FromBase64TransformMode.IgnoreWhiteSpaces))
				using (var cryptoStream = new CryptoStream(input, base64Transform, CryptoStreamMode.Read))
				{
					await cryptoStream.CopyToAsync(targetStream, 4096, cancellationToken).ConfigureAwait(false);
					await targetStream.FlushAsync(cancellationToken).ConfigureAwait(false);
				}
			}
			else
			{
				throw new InvalidOperationException();
			}
		}
Example #2
0
		/// <summary>
		/// Enables touch on platforms which do not support them.
		/// </summary>
		/// <param name="webview">The WebView control.</param>
		/// <param name="enabled">True whether the touch event emulation should be enabled.</param>
		/// <param name="maxTouchPoints">Maximum touch points supported. Defaults to one.</param>
		/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
		/// <returns>The task object representing the asynchronous operation.</returns>
		public static async Task SetTouchEmulationEnabledAsync(this IChromiumWebView webview, bool enabled, int? maxTouchPoints, CancellationToken cancellationToken)
		{
			if (webview is null)
				throw new ArgumentNullException(nameof(webview));

			var args = new CefDictionaryValue();
			args.SetBool("enabled", enabled);
			if (maxTouchPoints is not null)
			{
				if (maxTouchPoints.Value < 1 || maxTouchPoints.Value > 16)
					throw new ArgumentOutOfRangeException(nameof(maxTouchPoints), "Touch points must be between 1 and 16.");
				args.SetInt("maxTouchPoints", maxTouchPoints.Value);
			}
			ThrowIfNotEmptyResponse(await ExecuteDevToolsMethodInternalAsync(webview, "Emulation.setTouchEmulationEnabled", args, cancellationToken).ConfigureAwait(false));
		}