feat: monochromatic color tint/temp
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
@@ -13,9 +13,10 @@ use ptp::{
|
||||
CommandCode, DevicePropCode, FujiClarity, FujiColor, FujiColorChromeEffect,
|
||||
FujiColorChromeFXBlue, FujiCustomSetting, FujiCustomSettingName, FujiDynamicRange,
|
||||
FujiDynamicRangePriority, FujiFilmSimulation, FujiGrainEffect, FujiHighISONR,
|
||||
FujiHighlightTone, FujiImageQuality, FujiImageSize, FujiShadowTone, FujiSharpness,
|
||||
FujiSmoothSkinEffect, FujiWhiteBalance, FujiWhiteBalanceShift, FujiWhiteBalanceTemperature,
|
||||
ObjectFormat, UsbMode,
|
||||
FujiHighlightTone, FujiImageQuality, FujiImageSize, FujiMonochromaticColorTemperature,
|
||||
FujiMonochromaticColorTint, FujiShadowTone, FujiSharpness, FujiSmoothSkinEffect,
|
||||
FujiWhiteBalance, FujiWhiteBalanceShift, FujiWhiteBalanceTemperature, ObjectFormat,
|
||||
UsbMode,
|
||||
},
|
||||
structs::{DeviceInfo, ObjectInfo},
|
||||
};
|
||||
@@ -82,6 +83,8 @@ impl Camera {
|
||||
get_dynamic_range => FujiDynamicRange,
|
||||
get_dynamic_range_priority => FujiDynamicRangePriority,
|
||||
get_film_simulation => FujiFilmSimulation,
|
||||
get_monochromatic_color_temperature => FujiMonochromaticColorTemperature,
|
||||
get_monochromatic_color_tint => FujiMonochromaticColorTint,
|
||||
get_grain_effect => FujiGrainEffect,
|
||||
get_white_balance => FujiWhiteBalance,
|
||||
get_high_iso_nr => FujiHighISONR,
|
||||
@@ -107,6 +110,8 @@ impl Camera {
|
||||
set_dynamic_range(value: &FujiDynamicRange) => (),
|
||||
set_dynamic_range_priority(value: &FujiDynamicRangePriority) => (),
|
||||
set_film_simulation(value: &FujiFilmSimulation) => (),
|
||||
set_monochromatic_color_temperature(value: &FujiMonochromaticColorTemperature) => (),
|
||||
set_monochromatic_color_tint(value: &FujiMonochromaticColorTint) => (),
|
||||
set_grain_effect(value: &FujiGrainEffect) => (),
|
||||
set_white_balance(value: &FujiWhiteBalance) => (),
|
||||
set_high_iso_nr(value: &FujiHighISONR) => (),
|
||||
@@ -234,6 +239,7 @@ pub trait CameraImpl<P: rusb::UsbContext> {
|
||||
}
|
||||
|
||||
fn chunk_size(&self) -> usize {
|
||||
// Conservative estimate. Could go up to 15.75 * 1024^2 on the X-T5 but only gained 200ms.
|
||||
1024 * 1024
|
||||
}
|
||||
|
||||
@@ -324,6 +330,8 @@ pub trait CameraImpl<P: rusb::UsbContext> {
|
||||
dynamic_range: FujiDynamicRange => DevicePropCode::FujiStillCustomSettingDynamicRange,
|
||||
dynamic_range_priority: FujiDynamicRangePriority => DevicePropCode::FujiStillCustomSettingDynamicRangePriority,
|
||||
film_simulation: FujiFilmSimulation => DevicePropCode::FujiStillCustomSettingFilmSimulation,
|
||||
monochromatic_color_temperature: FujiMonochromaticColorTemperature => DevicePropCode::FujiStillCustomSettingMonochromaticColorTemperature,
|
||||
monochromatic_color_tint: FujiMonochromaticColorTint => DevicePropCode::FujiStillCustomSettingMonochromaticColorTint,
|
||||
grain_effect: FujiGrainEffect => DevicePropCode::FujiStillCustomSettingGrainEffect,
|
||||
white_balance: FujiWhiteBalance => DevicePropCode::FujiStillCustomSettingWhiteBalance,
|
||||
high_iso_nr: FujiHighISONR => DevicePropCode::FujiStillCustomSettingHighISONR,
|
||||
|
@@ -136,7 +136,7 @@ impl PtpDeserialize for ContainerCode {
|
||||
pub enum DevicePropCode {
|
||||
FujiUsbMode = 0xd16e,
|
||||
FujiRawConversionRun = 0xD183,
|
||||
FujiRawConversionSettings = 0xD185,
|
||||
FujiRawConversionProfile = 0xD185,
|
||||
FujiStillCustomSetting = 0xD18C,
|
||||
FujiStillCustomSettingName = 0xD18D,
|
||||
FujiStillCustomSettingImageSize = 0xD18E,
|
||||
@@ -144,8 +144,8 @@ pub enum DevicePropCode {
|
||||
FujiStillCustomSettingDynamicRange = 0xD190,
|
||||
FujiStillCustomSettingDynamicRangePriority = 0xD191,
|
||||
FujiStillCustomSettingFilmSimulation = 0xD192,
|
||||
// TODO: 0xD193 All 0s
|
||||
// TODO: 0xD194 All 0s
|
||||
FujiStillCustomSettingMonochromaticColorTemperature = 0xD193,
|
||||
FujiStillCustomSettingMonochromaticColorTint = 0xD194,
|
||||
FujiStillCustomSettingGrainEffect = 0xD195,
|
||||
FujiStillCustomSettingColorChromeEffect = 0xD196,
|
||||
FujiStillCustomSettingColorChromeFXBlue = 0xD197,
|
||||
@@ -1211,6 +1211,8 @@ macro_rules! fuji_i16 {
|
||||
};
|
||||
}
|
||||
|
||||
fuji_i16!(FujiMonochromaticColorTemperature, -18.0, 18.0, 1.0, 10i16);
|
||||
fuji_i16!(FujiMonochromaticColorTint, -18.0, 18.0, 1.0, 10i16);
|
||||
fuji_i16!(FujiWhiteBalanceShift, -9.0, 9.0, 1.0, 1i16);
|
||||
fuji_i16!(FujiWhiteBalanceTemperature, 2500.0, 10000.0, 10.0, 1i16);
|
||||
fuji_i16!(FujiHighlightTone, -2.0, 4.0, 0.5, 10i16);
|
||||
|
@@ -3,16 +3,25 @@ use clap::Args;
|
||||
use crate::camera::ptp::hex::{
|
||||
FujiClarity, FujiColor, FujiColorChromeEffect, FujiColorChromeFXBlue, FujiDynamicRange,
|
||||
FujiDynamicRangePriority, FujiFilmSimulation, FujiGrainEffect, FujiHighISONR,
|
||||
FujiHighlightTone, FujiImageQuality, FujiImageSize, FujiShadowTone, FujiSharpness,
|
||||
FujiSmoothSkinEffect, FujiWhiteBalance, FujiWhiteBalanceShift, FujiWhiteBalanceTemperature,
|
||||
FujiHighlightTone, FujiImageQuality, FujiImageSize, FujiMonochromaticColorTemperature,
|
||||
FujiMonochromaticColorTint, FujiShadowTone, FujiSharpness, FujiSmoothSkinEffect,
|
||||
FujiWhiteBalance, FujiWhiteBalanceShift, FujiWhiteBalanceTemperature,
|
||||
};
|
||||
|
||||
#[derive(Args, Debug)]
|
||||
pub struct FilmSimulationOptions {
|
||||
/// The Fujifilm film simulation to use
|
||||
/// Fujifilm Film Simulation
|
||||
#[clap(long)]
|
||||
pub simulation: Option<FujiFilmSimulation>,
|
||||
|
||||
/// Monochromatic Color Temperature (only applicable to B&W film simulations)
|
||||
#[clap(long)]
|
||||
pub monochromatic_color_temperature: Option<FujiMonochromaticColorTemperature>,
|
||||
|
||||
/// Monochromatic Color Tint (only applicable to B&W film simulations)
|
||||
#[clap(long)]
|
||||
pub monochromatic_color_tint: Option<FujiMonochromaticColorTint>,
|
||||
|
||||
/// The output image resolution
|
||||
#[clap(long)]
|
||||
pub size: Option<FujiImageSize>,
|
||||
|
@@ -5,8 +5,9 @@ use crate::{
|
||||
FujiClarity, FujiColor, FujiColorChromeEffect, FujiColorChromeFXBlue, FujiCustomSetting,
|
||||
FujiCustomSettingName, FujiDynamicRange, FujiDynamicRangePriority, FujiFilmSimulation,
|
||||
FujiGrainEffect, FujiHighISONR, FujiHighlightTone, FujiImageQuality, FujiImageSize,
|
||||
FujiShadowTone, FujiSharpness, FujiSmoothSkinEffect, FujiWhiteBalance,
|
||||
FujiWhiteBalanceShift, FujiWhiteBalanceTemperature,
|
||||
FujiMonochromaticColorTemperature, FujiMonochromaticColorTint, FujiShadowTone,
|
||||
FujiSharpness, FujiSmoothSkinEffect, FujiWhiteBalance, FujiWhiteBalanceShift,
|
||||
FujiWhiteBalanceTemperature,
|
||||
},
|
||||
usb,
|
||||
};
|
||||
@@ -102,56 +103,94 @@ fn handle_list(json: bool, device_id: Option<&str>) -> anyhow::Result<()> {
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct FilmSimulationRepr {
|
||||
pub name: FujiCustomSettingName,
|
||||
pub simulation: FujiFilmSimulation,
|
||||
pub size: FujiImageSize,
|
||||
pub quality: FujiImageQuality,
|
||||
pub simulation: FujiFilmSimulation,
|
||||
pub monochromatic_color_temperature: FujiMonochromaticColorTemperature,
|
||||
pub monochromatic_color_tint: FujiMonochromaticColorTint,
|
||||
pub highlight: FujiHighlightTone,
|
||||
pub shadow: FujiShadowTone,
|
||||
pub color: FujiColor,
|
||||
pub sharpness: FujiSharpness,
|
||||
pub clarity: FujiClarity,
|
||||
pub noise_reduction: FujiHighISONR,
|
||||
pub grain: FujiGrainEffect,
|
||||
pub color_chrome_effect: FujiColorChromeEffect,
|
||||
pub color_chrome_fx_blue: FujiColorChromeFXBlue,
|
||||
pub smooth_skin_effect: FujiSmoothSkinEffect,
|
||||
pub white_balance: FujiWhiteBalance,
|
||||
pub white_balance_shift_red: FujiWhiteBalanceShift,
|
||||
pub white_balance_shift_blue: FujiWhiteBalanceShift,
|
||||
pub white_balance_temperature: FujiWhiteBalanceTemperature,
|
||||
pub dynamic_range: FujiDynamicRange,
|
||||
pub dynamic_range_priority: FujiDynamicRangePriority,
|
||||
pub noise_reduction: FujiHighISONR,
|
||||
pub grain: FujiGrainEffect,
|
||||
pub color_chrome_effect: FujiColorChromeEffect,
|
||||
pub color_chrome_fx_blue: FujiColorChromeFXBlue,
|
||||
pub smooth_skin_effect: FujiSmoothSkinEffect,
|
||||
}
|
||||
|
||||
impl fmt::Display for FilmSimulationRepr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(f, "Name: {}", self.name)?;
|
||||
writeln!(f, "Simulation: {}", self.simulation)?;
|
||||
writeln!(f, "Size: {}", self.size)?;
|
||||
writeln!(f, "Quality: {}", self.quality)?;
|
||||
|
||||
writeln!(f, "Simulation: {}", self.simulation)?;
|
||||
|
||||
match self.simulation {
|
||||
FujiFilmSimulation::Monochrome
|
||||
| FujiFilmSimulation::MonochromeYe
|
||||
| FujiFilmSimulation::MonochromeR
|
||||
| FujiFilmSimulation::MonochromeG
|
||||
| FujiFilmSimulation::AcrosSTD
|
||||
| FujiFilmSimulation::AcrosYe
|
||||
| FujiFilmSimulation::AcrosR
|
||||
| FujiFilmSimulation::AcrosG => {
|
||||
writeln!(
|
||||
f,
|
||||
"Monochromatic Color Temperature: {}",
|
||||
self.monochromatic_color_temperature
|
||||
)?;
|
||||
writeln!(
|
||||
f,
|
||||
"Monochromatic Color Tint: {}",
|
||||
self.monochromatic_color_tint
|
||||
)?;
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
if self.dynamic_range_priority == FujiDynamicRangePriority::Off {
|
||||
writeln!(f, "Highlights: {}", self.highlight)?;
|
||||
writeln!(f, "Shadows: {}", self.shadow)?;
|
||||
}
|
||||
|
||||
writeln!(f, "Color: {}", self.color)?;
|
||||
writeln!(f, "Sharpness: {}", self.sharpness)?;
|
||||
writeln!(f, "Clarity: {}", self.clarity)?;
|
||||
writeln!(f, "Noise Reduction: {}", self.noise_reduction)?;
|
||||
writeln!(f, "Grain: {}", self.grain)?;
|
||||
writeln!(f, "Color Chrome Effect: {}", self.color_chrome_effect)?;
|
||||
writeln!(f, "Color Chrome FX Blue: {}", self.color_chrome_fx_blue)?;
|
||||
writeln!(f, "Smooth Skin Effect: {}", self.smooth_skin_effect)?;
|
||||
|
||||
writeln!(f, "White Balance: {}", self.white_balance)?;
|
||||
writeln!(
|
||||
f,
|
||||
"White Balance Shift (R/B): {} / {}",
|
||||
self.white_balance_shift_red, self.white_balance_shift_blue
|
||||
)?;
|
||||
|
||||
if self.white_balance == FujiWhiteBalance::Temperature {
|
||||
writeln!(
|
||||
f,
|
||||
"White Balance Temperature: {}K",
|
||||
self.white_balance_temperature
|
||||
)?;
|
||||
}
|
||||
|
||||
if self.dynamic_range_priority == FujiDynamicRangePriority::Off {
|
||||
writeln!(f, "Dynamic Range: {}", self.dynamic_range)?;
|
||||
writeln!(f, "Dynamic Range Priority: {}", self.dynamic_range_priority)?;
|
||||
writeln!(f, "Noise Reduction: {}", self.noise_reduction)?;
|
||||
writeln!(f, "Grain: {}", self.grain)?;
|
||||
writeln!(f, "Color Chrome Effect: {}", self.color_chrome_effect)?;
|
||||
writeln!(f, "Color Chrome FX Blue: {}", self.color_chrome_fx_blue)?;
|
||||
writeln!(f, "Smooth Skin Effect: {}", self.smooth_skin_effect)
|
||||
}
|
||||
|
||||
writeln!(f, "Dynamic Range Priority: {}", self.dynamic_range_priority)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,25 +200,27 @@ fn handle_get(json: bool, device_id: Option<&str>, slot: FujiCustomSetting) -> a
|
||||
|
||||
let repr = FilmSimulationRepr {
|
||||
name: camera.get_custom_setting_name()?,
|
||||
simulation: camera.get_film_simulation()?,
|
||||
size: camera.get_image_size()?,
|
||||
quality: camera.get_image_quality()?,
|
||||
simulation: camera.get_film_simulation()?,
|
||||
monochromatic_color_temperature: camera.get_monochromatic_color_temperature()?,
|
||||
monochromatic_color_tint: camera.get_monochromatic_color_tint()?,
|
||||
highlight: camera.get_highlight_tone()?,
|
||||
shadow: camera.get_shadow_tone()?,
|
||||
color: camera.get_color()?,
|
||||
sharpness: camera.get_sharpness()?,
|
||||
clarity: camera.get_clarity()?,
|
||||
noise_reduction: camera.get_high_iso_nr()?,
|
||||
grain: camera.get_grain_effect()?,
|
||||
color_chrome_effect: camera.get_color_chrome_effect()?,
|
||||
color_chrome_fx_blue: camera.get_color_chrome_fx_blue()?,
|
||||
smooth_skin_effect: camera.get_smooth_skin_effect()?,
|
||||
white_balance: camera.get_white_balance()?,
|
||||
white_balance_shift_red: camera.get_white_balance_shift_red()?,
|
||||
white_balance_shift_blue: camera.get_white_balance_shift_blue()?,
|
||||
white_balance_temperature: camera.get_white_balance_temperature()?,
|
||||
dynamic_range: camera.get_dynamic_range()?,
|
||||
dynamic_range_priority: camera.get_dynamic_range_priority()?,
|
||||
noise_reduction: camera.get_high_iso_nr()?,
|
||||
grain: camera.get_grain_effect()?,
|
||||
color_chrome_effect: camera.get_color_chrome_effect()?,
|
||||
color_chrome_fx_blue: camera.get_color_chrome_fx_blue()?,
|
||||
smooth_skin_effect: camera.get_smooth_skin_effect()?,
|
||||
};
|
||||
|
||||
if json {
|
||||
@@ -219,6 +260,48 @@ fn handle_set(
|
||||
camera.set_film_simulation(simulation)?;
|
||||
}
|
||||
|
||||
if options.monochromatic_color_temperature.is_some()
|
||||
|| options.monochromatic_color_tint.is_some()
|
||||
{
|
||||
let simulation = if let Some(simulation) = &options.simulation {
|
||||
simulation
|
||||
} else {
|
||||
&camera.get_film_simulation()?
|
||||
};
|
||||
|
||||
let is_bnw = match *simulation {
|
||||
FujiFilmSimulation::Monochrome
|
||||
| FujiFilmSimulation::MonochromeYe
|
||||
| FujiFilmSimulation::MonochromeR
|
||||
| FujiFilmSimulation::MonochromeG
|
||||
| FujiFilmSimulation::AcrosSTD
|
||||
| FujiFilmSimulation::AcrosYe
|
||||
| FujiFilmSimulation::AcrosR
|
||||
| FujiFilmSimulation::AcrosG => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
if let Some(monochromatic_color_temperature) = &options.monochromatic_color_temperature {
|
||||
if is_bnw {
|
||||
camera.set_monochromatic_color_temperature(monochromatic_color_temperature)?;
|
||||
} else {
|
||||
warn!(
|
||||
"A B&W film simulation is not selected, refusing to set monochromatic color temperature"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(monochromatic_color_tint) = &options.monochromatic_color_tint {
|
||||
if is_bnw {
|
||||
camera.set_monochromatic_color_tint(monochromatic_color_tint)?;
|
||||
} else {
|
||||
warn!(
|
||||
"A B&W film simulation is not selected, refusing to set monochromatic color tint"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(color) = &options.color {
|
||||
camera.set_color(color)?;
|
||||
}
|
||||
@@ -291,8 +374,10 @@ fn handle_set(
|
||||
&camera.get_dynamic_range_priority()?
|
||||
};
|
||||
|
||||
let is_drp_off = *dynamic_range_priority == FujiDynamicRangePriority::Off;
|
||||
|
||||
if let Some(dynamic_range) = &options.dynamic_range {
|
||||
if *dynamic_range_priority == FujiDynamicRangePriority::Off {
|
||||
if is_drp_off {
|
||||
camera.set_dynamic_range(dynamic_range)?;
|
||||
} else {
|
||||
warn!("Dynamic Range Priority is enabled, refusing to set dynamic range");
|
||||
@@ -300,7 +385,7 @@ fn handle_set(
|
||||
}
|
||||
|
||||
if let Some(highlights) = &options.highlight {
|
||||
if *dynamic_range_priority == FujiDynamicRangePriority::Off {
|
||||
if is_drp_off {
|
||||
camera.set_highlight_tone(highlights)?;
|
||||
} else {
|
||||
warn!("Dynamic Range Priority is enabled, refusing to set highlight tone");
|
||||
@@ -308,7 +393,7 @@ fn handle_set(
|
||||
}
|
||||
|
||||
if let Some(shadows) = &options.shadow {
|
||||
if *dynamic_range_priority == FujiDynamicRangePriority::Off {
|
||||
if is_drp_off {
|
||||
camera.set_shadow_tone(shadows)?;
|
||||
} else {
|
||||
warn!("Dynamic Range Priority is enabled, refusing to set shadow tone");
|
||||
|
Reference in New Issue
Block a user