using Unosquare.Swan;
using System;
using System.Collections.Generic;
using System.Text;
namespace Unosquare.RaspberryIO.Camera {
///
/// Defines a wrapper for the raspistill program and its settings (command-line arguments)
///
///
public class CameraStillSettings : CameraSettingsBase {
private Int32 _rotate;
///
public override String CommandName => "raspistill";
///
/// Gets or sets a value indicating whether the preview window (if enabled) uses native capture resolution
/// This may slow down preview FPS
///
public Boolean CaptureDisplayPreviewAtResolution { get; set; } = false;
///
/// Gets or sets the encoding format the hardware will use for the output.
///
public CameraImageEncodingFormat CaptureEncoding { get; set; } = CameraImageEncodingFormat.Jpg;
///
/// Gets or sets the quality for JPEG only encoding mode.
/// Value ranges from 0 to 100
///
public Int32 CaptureJpegQuality { get; set; } = 90;
///
/// Gets or sets a value indicating whether the JPEG encoder should add raw bayer metadata.
///
public Boolean CaptureJpegIncludeRawBayerMetadata { get; set; } = false;
///
/// JPEG EXIF data
/// Keys and values must be already properly escaped. Otherwise the command will fail.
///
public Dictionary CaptureJpegExtendedInfo { get; } = new Dictionary();
///
/// Gets or sets a value indicating whether [horizontal flip].
///
///
/// true if [horizontal flip]; otherwise, false.
///
public Boolean HorizontalFlip { get; set; } = false;
///
/// Gets or sets a value indicating whether [vertical flip].
///
///
/// true if [vertical flip]; otherwise, false.
///
public Boolean VerticalFlip { get; set; } = false;
///
/// Gets or sets the rotation.
///
/// Valid range 0-359
public Int32 Rotation {
get => this._rotate;
set {
if(value < 0 || value > 359) {
throw new ArgumentOutOfRangeException(nameof(value), "Valid range 0-359");
}
this._rotate = value;
}
}
///
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 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();
}
}
}