/// <summary> /// Self-contained method for capturing a continual images from the camera still port for a specified period of time. /// An MMALImageEncoder component will be created and attached to the still port. /// </summary> /// <param name="handler">The image capture handler to apply to the encoder component.</param> /// <param name="encodingType">The image encoding type e.g. JPEG, BMP.</param> /// <param name="pixelFormat">The pixel format to use with the encoder e.g. I420 (YUV420).</param> /// <param name="cancellationToken">A cancellationToken to trigger stop capturing.</param> /// <param name="burstMode">When enabled, burst mode will increase the rate at which images are taken, at the expense of quality.</param> /// <returns>The awaitable Task.</returns> public async Task TakePictureTimeout(IFileStreamCaptureHandler handler, MMALEncoding encodingType, MMALEncoding pixelFormat, CancellationToken cancellationToken, bool burstMode = false) { if (burstMode) { MMALCameraConfig.StillBurstMode = true; } using (var imgEncoder = new MMALImageEncoder()) using (var renderer = new MMALNullSinkComponent()) { this.ConfigureCameraSettings(); var portConfig = new MMALPortConfig(encodingType, pixelFormat, 90); imgEncoder.ConfigureOutputPort(portConfig, handler); // Create our component pipeline. this.Camera.StillPort.ConnectTo(imgEncoder); this.Camera.PreviewPort.ConnectTo(renderer); // Camera warm up time await Task.Delay(2000).ConfigureAwait(false); while (!cancellationToken.IsCancellationRequested) { await this.ProcessAsync(this.Camera.StillPort).ConfigureAwait(false); if (!cancellationToken.IsCancellationRequested) { handler.NewFile(); } } } }
/// <summary> /// Self-contained method for capturing timelapse images. /// An MMALImageEncoder component will be created and attached to the still port. /// </summary> /// <param name="handler">The image capture handler to apply to the encoder component.</param> /// <param name="encodingType">The image encoding type e.g. JPEG, BMP.</param> /// <param name="pixelFormat">The pixel format to use with the encoder e.g. I420 (YUV420).</param> /// <param name="timelapse">A Timelapse object which specifies the timeout and rate at which images should be taken.</param> /// <returns>The awaitable Task.</returns> /// <exception cref="ArgumentNullException"/> public async Task TakePictureTimelapse(IFileStreamCaptureHandler handler, MMALEncoding encodingType, MMALEncoding pixelFormat, Timelapse timelapse) { int interval = 0; if (timelapse == null) { throw new ArgumentNullException(nameof(timelapse), "Timelapse object null. This must be initialized for Timelapse mode"); } using (var imgEncoder = new MMALImageEncoder()) using (var renderer = new MMALNullSinkComponent()) { this.ConfigureCameraSettings(); var portConfig = new MMALPortConfig(encodingType, pixelFormat, 90); imgEncoder.ConfigureOutputPort(portConfig, handler); // Create our component pipeline. this.Camera.StillPort.ConnectTo(imgEncoder); this.Camera.PreviewPort.ConnectTo(renderer); // Camera warm up time await Task.Delay(2000).ConfigureAwait(false); while (!timelapse.CancellationToken.IsCancellationRequested) { switch (timelapse.Mode) { case TimelapseMode.Millisecond: interval = timelapse.Value; break; case TimelapseMode.Second: interval = timelapse.Value * 1000; break; case TimelapseMode.Minute: interval = (timelapse.Value * 60) * 1000; break; } await Task.Delay(interval).ConfigureAwait(false); MMALLog.Logger.LogInformation($"Preparing to take picture. Resolution: {MMALCameraConfig.StillResolution.Width} x {MMALCameraConfig.StillResolution.Height}. " + $"Encoder: {encodingType.EncodingName}. Pixel Format: {pixelFormat.EncodingName}."); await this.ProcessAsync(this.Camera.StillPort).ConfigureAwait(false); if (!timelapse.CancellationToken.IsCancellationRequested) { handler.NewFile(); } } } }