121 lines
3.9 KiB
C#
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();
|
|
}
|
|
}
|
|
} |