RaspberryIO/Unosquare.RaspberryIO/Camera/CameraStillSettings.cs
2019-12-03 18:43:54 +01:00

121 lines
3.9 KiB
C#

using Unosquare.Swan;
using System;
using System.Collections.Generic;
using System.Text;
namespace Unosquare.RaspberryIO.Camera {
/// <summary>
/// Defines a wrapper for the raspistill program and its settings (command-line arguments)
/// </summary>
/// <seealso cref="CameraSettingsBase" />
public class CameraStillSettings : CameraSettingsBase {
private Int32 _rotate;
/// <inheritdoc />
public override String CommandName => "raspistill";
/// <summary>
/// Gets or sets a value indicating whether the preview window (if enabled) uses native capture resolution
/// This may slow down preview FPS
/// </summary>
public Boolean CaptureDisplayPreviewAtResolution { get; set; } = false;
/// <summary>
/// Gets or sets the encoding format the hardware will use for the output.
/// </summary>
public CameraImageEncodingFormat CaptureEncoding { get; set; } = CameraImageEncodingFormat.Jpg;
/// <summary>
/// Gets or sets the quality for JPEG only encoding mode.
/// Value ranges from 0 to 100
/// </summary>
public Int32 CaptureJpegQuality { get; set; } = 90;
/// <summary>
/// Gets or sets a value indicating whether the JPEG encoder should add raw bayer metadata.
/// </summary>
public Boolean CaptureJpegIncludeRawBayerMetadata { get; set; } = false;
/// <summary>
/// JPEG EXIF data
/// Keys and values must be already properly escaped. Otherwise the command will fail.
/// </summary>
public Dictionary<String, String> CaptureJpegExtendedInfo { get; } = new Dictionary<String, String>();
/// <summary>
/// Gets or sets a value indicating whether [horizontal flip].
/// </summary>
/// <value>
/// <c>true</c> if [horizontal flip]; otherwise, <c>false</c>.
/// </value>
public Boolean HorizontalFlip { get; set; } = false;
/// <summary>
/// Gets or sets a value indicating whether [vertical flip].
/// </summary>
/// <value>
/// <c>true</c> if [vertical flip]; otherwise, <c>false</c>.
/// </value>
public Boolean VerticalFlip { get; set; } = false;
/// <summary>
/// Gets or sets the rotation.
/// </summary>
/// <exception cref="ArgumentOutOfRangeException">Valid range 0-359</exception>
public Int32 Rotation {
get => this._rotate;
set {
if(value < 0 || value > 359) {
throw new ArgumentOutOfRangeException(nameof(value), "Valid range 0-359");
}
this._rotate = value;
}
}
/// <inheritdoc />
public override String CreateProcessArguments() {
StringBuilder sb = new StringBuilder(base.CreateProcessArguments());
_ = sb.Append($" -e {this.CaptureEncoding.ToString().ToLowerInvariant()}");
// JPEG Encoder specific arguments
if(this.CaptureEncoding == CameraImageEncodingFormat.Jpg) {
_ = sb.Append($" -q {this.CaptureJpegQuality.Clamp(0, 100).ToString(Ci)}");
if(this.CaptureJpegIncludeRawBayerMetadata) {
_ = sb.Append(" -r");
}
// JPEG EXIF data
if(this.CaptureJpegExtendedInfo.Count > 0) {
foreach(KeyValuePair<String, String> kvp in this.CaptureJpegExtendedInfo) {
if(String.IsNullOrWhiteSpace(kvp.Key) || String.IsNullOrWhiteSpace(kvp.Value)) {
continue;
}
_ = sb.Append($" -x \"{kvp.Key.Replace("\"", "'")}={kvp.Value.Replace("\"", "'")}\"");
}
}
}
// Display preview settings
if(this.CaptureDisplayPreview && this.CaptureDisplayPreviewAtResolution) {
_ = sb.Append(" -fp");
}
if(this.Rotation != 0) {
_ = sb.Append($" -rot {this.Rotation}");
}
if(this.HorizontalFlip) {
_ = sb.Append(" -hf");
}
if(this.VerticalFlip) {
_ = sb.Append(" -vf");
}
return sb.ToString();
}
}
}