The merge job and its page: a selection to a panorama DNG, confirmed first

dr_ui::merge is the orchestration with no interface in it: decode each
frame to sensor data and build its graph as a session would (orientation,
lens profile); render each through the camera-space tap at proxy size and
detect keypoints there, so the alignment is measured in the undistorted
frame the tiles are rendered in; align; solve one gain per frame from the
proxies' overlaps; draw the aligned set in colour for the page; then wait.
Nothing is written until a Decision arrives (FR-MRG-1). The merge writes
a linear DNG through the outbox with a destination record, so the drain
puts it beside its sources on a folder library and a server alike, and
the library rescans (FR-MRG-3).

merge.slint is the page, on the import page's model: the alignment
table with a failed frame named on its row and the button held off
(FR-MRG-5), the preview, the projection choice, Stop and Back. A
"Merge to panorama" button joins the grid's selection bar at two frames.

Headless, the example produces the fixture's 22 993 x 5 980 DNG in 45 s
on the reference desktop, exposures balanced across the stop of drift.
This commit is contained in:
2026-09-19 15:24:20 +02:00
parent 44ea763c61
commit 2e9a1eb0f0
12 changed files with 1654 additions and 105 deletions
+1 -1
View File
@@ -4578,7 +4578,7 @@ impl DevelopSession {
/// lens's distortion and not its vignetting, or covers only part of a
/// zoom's range, and a partial profile is worth applying — discarding it
/// because one field is missing would turn a good correction into none.
fn profile_for(meta: &dr_decode::Metadata) -> Option<dr_pipeline::LensProfile> {
pub(crate) fn profile_for(meta: &dr_decode::Metadata) -> Option<dr_pipeline::LensProfile> {
// All three are needed to ask the question at all. A lens name alone
// does not identify a correction: distortion is interpolated across a
// zoom's focal range and vignetting depends strongly on aperture — a