mirror of
https://github.com/storytold/lightcraft.git
synced 2026-11-01 05:57:09 -06:00
Lightroom catalog import: size radial masks with the stored image's aspect (part of #1806)
This commit is contained in:
@@ -703,7 +703,11 @@ fn mapped_settings(
|
||||
if !props.contains_key("crs:HasCrop") && CROP.iter().any(|k| props.contains_key(*k)) {
|
||||
props.insert("crs:HasCrop".into(), vec!["True".into()]);
|
||||
}
|
||||
let (mut partial, mut unknown) = crate::crs::to_partial_report(&props, Some(&values), target, aspect);
|
||||
// Mask edges are fractions of the stored image, like the crop's, so radii go to long-edge units
|
||||
// with its aspect: `aspect` is the photo's in LightCraft, which is the shown one for a photo
|
||||
// already in the library and only stands in when the catalog has no file size.
|
||||
let mask_aspect = if stored_aspect.is_finite() && stored_aspect > 0.0 { stored_aspect } else { aspect };
|
||||
let (mut partial, mut unknown) = crate::crs::to_partial_report(&props, Some(&values), target, mask_aspect);
|
||||
catalog_crop(&mut partial, orientation, stored_aspect);
|
||||
catalog_masks(&mut partial, orientation);
|
||||
if deferred > 0 {
|
||||
@@ -767,9 +771,9 @@ fn catalog_crop(partial: &mut Value, orientation: Orientation, stored_aspect: f6
|
||||
|
||||
/// Lightroom's masks in LightCraft's frame. Like the crop's corners, their positions are on the
|
||||
/// stored image (before orientation), normalized to its size; LightCraft's are on the oriented
|
||||
/// image. So the points go through the orientation, a radial's radii (in long-edge units) swap when
|
||||
/// the axes do, and a mirror turns its angle the other way. A quarter turn keeps the angle: the
|
||||
/// ellipse turned 90° is the same ellipse with its radii swapped.
|
||||
/// image. So the points go through the orientation, a radial's radii (in long-edge units, from the
|
||||
/// stored image's aspect) swap when the axes do, and a mirror turns its angle the other way. A
|
||||
/// quarter turn keeps the angle: the ellipse turned 90° is the same ellipse with its radii swapped.
|
||||
fn catalog_masks(partial: &mut Value, orientation: Orientation) {
|
||||
if orientation == Orientation::Normal {
|
||||
return;
|
||||
|
||||
@@ -332,6 +332,13 @@ fn catalog_masks_follow_the_photo_orientation() {
|
||||
assert_eq!(masks(Orientation::Rotate180), [0.9, 0.8, 0.7, 0.4, 0.9, 0.8, r.0, r.1, 10.0, 0.9, 0.8, 0.7, 0.4]);
|
||||
assert_eq!(masks(Orientation::FlipH), [0.9, 0.2, 0.7, 0.6, 0.9, 0.2, r.0, r.1, -10.0, 0.9, 0.2, 0.7, 0.6]);
|
||||
assert_eq!(masks(Orientation::Transpose), [0.2, 0.1, 0.6, 0.3, 0.2, 0.1, r.1, r.0, -10.0, 0.2, 0.1, 0.6, 0.3]);
|
||||
// a photo already in the library has its shown size (portrait here), but Lightroom's edges are
|
||||
// fractions of the stored image: a circle on a 3:2 stored image stays a circle
|
||||
let s = r#"s = { MaskGroupBasedCorrections = { { What = "Correction", CorrectionAmount = 1, LocalExposure2012 = 0.1, CorrectionMasks = {
|
||||
{ What = "Mask/CircularGradient", Left = 0.3, Right = 0.5, Top = 0.3, Bottom = 0.6, Version = 2, Flipped = true } } } } }"#;
|
||||
let (partial, _) = mapped_settings(s, crate::crs::Target::RawAbsolute, 1.0 / 1.5, Orientation::Rotate90, 1.5).unwrap();
|
||||
let radial = &partial["masks"][0]["components"][0]["shape"];
|
||||
assert!(close(&radial["rx"], 0.1) && close(&radial["ry"], 0.1), "{radial}");
|
||||
}
|
||||
|
||||
/// The `crs` corners and angle Lightroom would store for LightCraft crop `g` on a stored image
|
||||
|
||||
Reference in New Issue
Block a user