public void CaptureScreenshot_WhenBitmapIsNullAndZoomed_CapturesScaledScreenshotIntoNewBitmap() { var parameters = new CaptureParameters() { Zoom = 0.25 }; using (var grabber = new ScreenGrabber(parameters)) { if (ScreenGrabber.CanCaptureScreenshot()) { using (Bitmap bitmap = grabber.CaptureScreenshot(null)) { TestLog.EmbedImage("Screenshot with 0.25x zoom", bitmap); Assert.Multiple(() => { Assert.AreApproximatelyEqual(ScreenGrabber.GetScreenSize().Width / 2, grabber.ScreenshotWidth, 1); Assert.AreApproximatelyEqual(ScreenGrabber.GetScreenSize().Height / 2, grabber.ScreenshotHeight, 1); Assert.AreEqual(grabber.ScreenshotWidth, bitmap.Width); Assert.AreEqual(grabber.ScreenshotHeight, bitmap.Height); }); } } else { Assert.Throws <ScreenshotNotAvailableException>(() => grabber.CaptureScreenshot(null), "CanCaptureScreenshot returned false so expected an exception to be thrown."); } } }
/// <summary> /// Initializes a new photo capture controller, if needed. /// </summary> /// <param name="captureMode">Photo capture mode.</param> /// <param name="parameters">Camera capture parameters.</param> /// <returns>Awaitable task.</returns> /// <exception cref="ArgumentNullException"><paramref name="parameters"/> is <see langword="null"/>.</exception> /// <exception cref="NotImplementedException"><paramref name="captureMode"/> is not supported.</exception> public async Task InitializePhotoCaptureAsync(CaptureMode captureMode, CaptureParameters parameters) { if (parameters == null) { throw new ArgumentNullException("parameters"); } if (parameters.ImageEncoding == null) { throw new ArgumentNullException("parameters", "Image encoding is not set."); } Tracing.Trace("PhotoCamera::InitializePhotoCaptureAsync"); if (this.photoCapture != null && this.CaptureMode == captureMode && parameters.Equals(this.CaptureParameters)) { Tracing.Trace("PhotoCamera: Capture is already initialized with the same parameters."); return; } this.CaptureMode = captureMode; this.CaptureParameters = parameters; await this.DestroyPhotoCaptureAsync(); this.photoCapture = this.CreatePhotoCapture(captureMode); await this.TaskEngine.EnqueueTaskAsync(new InitializePhotoCaptureTask(this.CameraController, this.photoCapture, parameters)); }
public void CaptureScreenshot_WhenBitmapIsNotNull_CapturesScreenshotIntoProvidedBitmap() { var parameters = new CaptureParameters() { Zoom = 0.25 }; using (var grabber = new ScreenGrabber(parameters)) { using (Bitmap bitmap = new Bitmap(grabber.ScreenshotWidth, grabber.ScreenshotHeight)) { if (ScreenGrabber.CanCaptureScreenshot()) { Bitmap returnedBitmap = grabber.CaptureScreenshot(bitmap); TestLog.EmbedImage("Screenshot with 0.25x zoom", bitmap); Assert.AreSame(bitmap, returnedBitmap); } else { Assert.Throws <ScreenshotNotAvailableException>(() => grabber.CaptureScreenshot(bitmap), "CanCaptureScreenshot returned false so expected an exception to be thrown."); } } } }
public void Parameters_ReturnsParameters() { var parameters = new CaptureParameters(); using (var grabber = new ScreenGrabber(parameters)) { Assert.AreSame(parameters, grabber.Parameters); } }
public void CaptureScreenshot_WhenDisposed_Throws() { var parameters = new CaptureParameters(); var grabber = new ScreenGrabber(parameters); grabber.Dispose(); Assert.Throws <ObjectDisposedException>(() => grabber.CaptureScreenshot(null)); }
public void ScreenshotWidth_WhenDisposed_Throws() { var parameters = new CaptureParameters(); var grabber = new ScreenGrabber(parameters); grabber.Dispose(); int x; Assert.Throws <ObjectDisposedException>(() => x = grabber.ScreenshotWidth); }
public void ScreenshotHeight_ReturnsScaledHeight() { var parameters = new CaptureParameters() { Zoom = 0.25 }; using (var grabber = new ScreenGrabber(parameters)) { Assert.AreApproximatelyEqual(ScreenGrabber.GetScreenSize().Height / 2, grabber.ScreenshotHeight, 1); } }
/// <summary> /// Captures an image of the entire desktop. /// </summary> /// <param name="parameters">The capture parameters.</param> /// <returns>The screenshot.</returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="parameters"/> is null.</exception> /// <exception cref="ScreenshotNotAvailableException">Thrown if a screenshot cannot be captured at this time.</exception> public static Bitmap Screenshot(CaptureParameters parameters) { if (parameters == null) { throw new ArgumentNullException("parameters"); } using (var grabber = new ScreenGrabber(parameters)) { grabber.OverlayManager.AddOverlay(GetOverlayManager().ToOverlay()); return(grabber.CaptureScreenshot(null)); } }
public void CaptureScreenshot_WhenBitmapIsNotTheRightSize_Throws() { var parameters = new CaptureParameters() { Zoom = 0.25 }; using (var grabber = new ScreenGrabber(parameters)) { var ex = Assert.Throws <ArgumentException>(() => grabber.CaptureScreenshot(new Bitmap(1, grabber.ScreenshotHeight))); Assert.Contains(ex.Message, "The bitmap dimensions must exactly match the screenshot dimensions."); ex = Assert.Throws <ArgumentException>(() => grabber.CaptureScreenshot(new Bitmap(grabber.ScreenshotWidth, 1))); Assert.Contains(ex.Message, "The bitmap dimensions must exactly match the screenshot dimensions."); } }
/// <summary> /// Initializes a new instance of the <see cref="InitializePhotoCaptureTask"/> class. /// </summary> /// <param name="cameraController">Current camera controller.</param> /// <param name="photoCapture">Photo capture to initialize.</param> /// <param name="captureParameters">Photo capture parameters.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="cameraController"/> is <see langword="null"/>. /// <para>-or-</para> /// <paramref name="photoCapture"/> is <see langword="null"/>. /// <para>-or-</para> /// <paramref name="captureParameters"/> is <see langword="null"/>. /// </exception> public InitializePhotoCaptureTask(CameraController cameraController, IPhotoCapture photoCapture, CaptureParameters captureParameters) : base(cameraController) { if (photoCapture == null) { throw new ArgumentNullException("photoCapture"); } if (captureParameters == null) { throw new ArgumentNullException("captureParameters"); } this.photoCapture = photoCapture; this.captureParameters = captureParameters; }
public void Zoom_CanGetAndSetValue() { var parameters = new CaptureParameters(); Assert.AreEqual(1.0, parameters.Zoom); parameters.Zoom = 1.0 / 16; Assert.AreEqual(1.0 / 16, parameters.Zoom); parameters.Zoom = 16; Assert.AreEqual(16, parameters.Zoom); var ex = Assert.Throws <ArgumentOutOfRangeException>(() => parameters.Zoom = 1.0 / 17); Assert.Contains(ex.Message, "The zoom factor must be between 1/16 and 16."); ex = Assert.Throws <ArgumentOutOfRangeException>(() => parameters.Zoom = 17); Assert.Contains(ex.Message, "The zoom factor must be between 1/16 and 16."); }
/// <summary> /// Starts recording a screen capture video of the entire desktop. /// </summary> /// <remarks> /// <para> /// Recording a screen capture video can be very CPU and space intensive particularly /// when running tests on a single-core CPU. We recommend calling /// <see cref="StartRecording(CaptureParameters, double)" /> with /// a <see cref="CaptureParameters.Zoom" /> factor of 0.25 or less and a frame rate /// of no more than 5 to 10 frames per second. /// </para> /// </remarks> /// <param name="parameters">The capture parameters.</param> /// <param name="framesPerSecond">The number of frames per second to capture.</param> /// <returns>The recorder.</returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="parameters"/> is null.</exception> /// <exception cref="ScreenshotNotAvailableException">Thrown if a screenshot cannot be captured at this time.</exception> public static ScreenRecorder StartRecording(CaptureParameters parameters, double framesPerSecond) { if (parameters == null) { throw new ArgumentNullException("parameters"); } ScreenGrabber.ThrowIfScreenshotNotAvailable(); ScreenGrabber grabber = new ScreenGrabber(parameters); try { FlashScreenVideo video = new FlashScreenVideo(new FlashScreenVideoParameters( grabber.ScreenshotWidth, grabber.ScreenshotHeight, framesPerSecond)); ScreenRecorder recorder = new ScreenRecorder(grabber, video); try { recorder.OverlayManager.AddOverlay(GetOverlayManager().ToOverlay()); recorder.Start(); return(recorder); } catch { recorder.Dispose(); throw; } } catch { grabber.Dispose(); throw; } }
/// <summary> /// Automatically embeds a video of the test run from this point forward when a trigger event occurs. /// </summary> /// <remarks> /// <para> /// Recording a screen capture video can be very CPU and space intensive particularly /// when running tests on a single-core CPU. We recommend calling /// <see cref="AutoEmbedRecording(TriggerEvent, string, CaptureParameters, double)" /> with /// a <see cref="CaptureParameters.Zoom" /> factor of 0.25 or less and a frame rate /// of no more than 5 to 10 frames per second. /// </para> /// <para> /// If screenshots cannot be captured, the method will embed a warning message to that effect. /// </para> /// </remarks> /// <param name="triggerEvent">The trigger event.</param> /// <param name="attachmentName">The name to give the video attachment, or null to assign one automatically.</param> /// <param name="parameters">The capture parameters.</param> /// <param name="framesPerSecond">The number of frames per second to capture.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="parameters"/> is null.</exception> /// <seealso cref="TestContext.AutoExecute(TriggerEvent, Gallio.Common.GallioAction)"/> public static void AutoEmbedRecording(TriggerEvent triggerEvent, string attachmentName, CaptureParameters parameters, double framesPerSecond) { if (parameters == null) { throw new ArgumentNullException("parameters"); } TestContext context = TestContext.CurrentContext; if (context != null) { try { ScreenRecorder recorder = StartRecording(parameters, framesPerSecond); context.AutoExecute(triggerEvent, () => { recorder.Stop(); if (recorder.Video.FrameCount != 0) { context.LogWriter.Default.EmbedVideo(attachmentName, recorder.Video); } }, recorder.Dispose); } catch (ScreenshotNotAvailableException ex) { context.AutoExecute(triggerEvent, () => { context.LogWriter.Default.WriteException(ex, "Recording not available."); }); } } }
/// <summary> /// Automatically embeds a screenshot when a trigger event occurs. /// </summary> /// <remarks> /// <para> /// If screenshots cannot be captured, the method will embed a warning message to that effect. /// </para> /// </remarks> /// <param name="triggerEvent">The trigger event.</param> /// <param name="attachmentName">The name to give to the image attachment, or null to assign one automatically.</param> /// <param name="parameters">The capture parameters.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="parameters"/> is null.</exception> /// <seealso cref="TestContext.AutoExecute(TriggerEvent, Gallio.Common.GallioAction)"/> public static void AutoEmbedScreenshot(TriggerEvent triggerEvent, string attachmentName, CaptureParameters parameters) { if (parameters == null) { throw new ArgumentNullException("parameters"); } TestContext context = TestContext.CurrentContext; if (context != null) { context.AutoExecute(triggerEvent, () => { try { Bitmap bitmap = Screenshot(parameters); context.LogWriter.Default.EmbedImage(attachmentName, bitmap); } catch (ScreenshotNotAvailableException ex) { context.LogWriter.Default.WriteException(ex, "Screenshot not available."); } }); } }
CaptureSession StartCapture(SessionModel model) { SessionSettings settings = model.Settings; settings.RestartPending = false; bool sourceChanged = false; bool sinkChanged = false; CaptureParameters.SourceInfo source = settings.Source?.ToSourceInfo(devices, out sourceChanged); CaptureParameters.WASSinkInfo wasSink = settings.WASSink?.ToWASSinkInfo(devices, out sinkChanged); if (sourceChanged || sinkChanged) { this.settings.Dirty = true; } model.Valid = null != source && (null != wasSink || null == settings.WASSink); if (source is CaptureParameters.DefaultDeviceWASSourceInfo defSource) { Device device = Array.Find(devices, dev => dev.Flow == defSource.Flow && (dev.DefaultFor & defSource.Role) != 0); if (null == device) { throw new InvalidOperationException(); } model.SourceName = device.FriendlyName; model.CanSwap = defSource.Flow == DataFlow.Render && defSource.Role == Role.Console; } else if (source is CaptureParameters.DeviceWASSourceInfo devSource) { Device device = Array.Find(devices, dev => dev.Id == devSource.DeviceId); if (null == device) { throw new InvalidOperationException(); } model.SourceName = device.FriendlyName; model.CanSwap = device.Flow == DataFlow.Render && (device.DefaultFor & Role.Console) != 0; } else { model.SourceName = "???"; } model.WithNetworkSink = null != settings.NetworkSink; model.WithWASSink = null != settings.WASSink; if (!model.Valid) { return(null); } CaptureParameters parameters = new CaptureParameters { ControlStructure = model.ControlStructure, SampleRate = settings.SampleRate, Channels = settings.Channels, Source = source, WASSink = wasSink, NetworkSink = settings.NetworkSink?.ToNetworkSinkInfo(this.settings.NetworkSinkDefaults), }; return(Driver.StartCapture(parameters, model.Console, delegate { settings.Source?.ToSourceInfo(devices, out sourceChanged); settings.WASSink?.ToWASSinkInfo(devices, out sinkChanged); if (sourceChanged || sinkChanged) { settings.RestartPending = true; this.settings.Dirty = true; } if (settings.RestartPending) { RestartSession(model); } })); }