Merge page: outline every frame on the preview, and let it be tall
A sweep whose frames overlap by more than half reads as one photograph, and the page's job is to show frames. Each footprint is walked along its border and drawn in amber where it lands, so twelve frames look like twelve and a misplaced one is visible as such. The preview may take most of the page's height rather than 320 px.
This commit is contained in:
@@ -603,6 +603,41 @@ fn preview(
|
||||
out[o + 3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
// Each frame's outline, so the page shows *frames* and not one picture:
|
||||
// a sweep of frames overlapping by more than half reads as a single
|
||||
// photograph otherwise, which is what a photographer looking for a
|
||||
// misplaced frame needs to see through. Walked along each border and
|
||||
// drawn where it lands, two pixels wide, in a colour the scene does not
|
||||
// have.
|
||||
let steps = 600;
|
||||
for k in 0..proxies.len() {
|
||||
for s in 0..steps {
|
||||
let t = s as f64 / steps as f64;
|
||||
for p in [
|
||||
(-fw / 2.0 + fw * t, -fh / 2.0),
|
||||
(-fw / 2.0 + fw * t, fh / 2.0 - 1.0),
|
||||
(-fw / 2.0, -fh / 2.0 + fh * t),
|
||||
(fw / 2.0 - 1.0, -fh / 2.0 + fh * t),
|
||||
] {
|
||||
let d = cameras.bearing(k, p);
|
||||
let Some((u, v)) = projection.from_direction(scale, d) else { continue };
|
||||
let x = ((u - bounds.min_u) / px) as i64;
|
||||
let y = ((v - bounds.min_v) / px) as i64;
|
||||
for (dx, dy) in [(0, 0), (1, 0), (0, 1), (1, 1)] {
|
||||
let (xx, yy) = (x + dx, y + dy);
|
||||
if xx < 0 || yy < 0 || xx >= out_w as i64 || yy >= out_h as i64 {
|
||||
continue;
|
||||
}
|
||||
let o = (yy as usize * out_w + xx as usize) * 4;
|
||||
out[o] = 255;
|
||||
out[o + 1] = 176;
|
||||
out[o + 2] = 0;
|
||||
out[o + 3] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
(out_w as u32, out_h as u32, out)
|
||||
}
|
||||
|
||||
|
||||
+10
-1
@@ -139,8 +139,13 @@ export component MergePage inherits Rectangle {
|
||||
// was found at: ghosting here is the alignment's error,
|
||||
// and what it looks like is what the photographer is
|
||||
// confirming.
|
||||
// As tall as the picture needs up to most of the page,
|
||||
// and as wide as it is at that height: a four-frame
|
||||
// perspective merge is nearly square, a twelve-frame
|
||||
// cylinder is a strip, and either should fill what it
|
||||
// can rather than sit in a letterbox.
|
||||
if root.preview.width > 0: Rectangle {
|
||||
height: min(320px, parent.width * root.preview.height / max(1, root.preview.width));
|
||||
height: min(root.height * 0.55, parent.width * root.preview.height / max(1, root.preview.width));
|
||||
background: Theme.rule;
|
||||
Image {
|
||||
source: root.preview;
|
||||
@@ -151,6 +156,10 @@ export component MergePage inherits Rectangle {
|
||||
}
|
||||
|
||||
Caption { text: root.summary; wrap: word-wrap; }
|
||||
Caption {
|
||||
text: "Each frame is outlined in amber where it lands. Ghosting in an overlap is the alignment's error.";
|
||||
wrap: word-wrap;
|
||||
}
|
||||
|
||||
Segmented {
|
||||
label: "Projection";
|
||||
|
||||
Reference in New Issue
Block a user