hero: admit portrait sources, the crop was built for them
The aspect floor is really an ALBUM-ART guard -- its own comment says so: a square sleeve passes every other gate, and Camping in Alaska's square "lost and found" artwork once reached a live hero slot that way. But it was written as a blanket "wide only" rule, so it also discarded portrait press photography one crate before the machinery built to handle it. The app already crops tall sources to 16:9 around detected faces: hero_crop.rs keeps full source width, slides the window vertically, and applies headroom rules above the topmost face (recipe vertical-yoloxnano-...-faces-first). maximal_hero_rect exists specifically for sources taller than 16:9. Meanwhile the selection gate in the metadata crate rejected everything below 1.15, so those images never arrived. Sleeves are square; press portraits are not. Admitting ratio <= 0.92 with at least 1000px of width keeps the guard exactly where release artwork lives while opening the one route to a hero for artists whose entire press corpus is portrait. Posters and flyers cannot enter this way either: the text, flat and collage gates all run before this one. Hana Vu goes from BANNER NONE to 2 -- the LA Times 2000x2500 portrait and an Our Culture press shot -- and renders correctly, face placed with headroom. Camping in Alaska is unchanged, same three banners. Square 1:1 press crops (Nikki Nair's Rinse FM and Corsica shots) stay rejected, which is the guard still doing its job.
This commit is contained in:
1 parent
9536ff23a9
commit
d79fe2f28a
1 file changed
+24
-3
@@ -565,6 +565,15 @@ const HERO_SCORE_CONCURRENCY: usize = 4;
|
|||||||
/// Minimum width:height for a hero candidate. Album sleeves are exactly 1.0;
|
/// Minimum width:height for a hero candidate. Album sleeves are exactly 1.0;
|
||||||
/// every press photo across the probe fixtures measures 1.33 or wider.
|
/// every press photo across the probe fixtures measures 1.33 or wider.
|
||||||
const HERO_MIN_ASPECT: f64 = 1.15;
|
const HERO_MIN_ASPECT: f64 = 1.15;
|
||||||
|
/// Portrait sources are admitted below this ratio, well clear of the square
|
||||||
|
/// band where release artwork lives. The app crops tall sources to 16:9 around
|
||||||
|
/// the detected faces (`hero_crop::maximal_hero_rect` keeps full width and
|
||||||
|
/// slides the window vertically), so a portrait press photo is usable hero
|
||||||
|
/// material while a 1:1 sleeve is not.
|
||||||
|
const HERO_PORTRAIT_MAX_ASPECT: f64 = 0.92;
|
||||||
|
/// A portrait source is cropped to full-width x (width*9/16), so its width IS
|
||||||
|
/// the resulting hero width. Keep enough pixels that the crop is still a hero.
|
||||||
|
const HERO_PORTRAIT_MIN_WIDTH: u32 = 1000;
|
||||||
const HERO_SEARCH_WAVE_CONCURRENCY: usize = 3;
|
const HERO_SEARCH_WAVE_CONCURRENCY: usize = 3;
|
||||||
/// A Bing image page with at most this many cards is a degraded answer, not a
|
/// A Bing image page with at most this many cards is a degraded answer, not a
|
||||||
/// small result set. Bing's genuine pages run 12-100 cards; the degraded shape
|
/// small result set. Bing's genuine pages run 12-100 cards; the degraded shape
|
||||||
@@ -8902,10 +8911,22 @@ fn score_bing_hero_image(
|
|||||||
// collage detector only runs at `text_penalty <= 0.70`). Camping in
|
// collage detector only runs at `text_penalty <= 0.70`). Camping in
|
||||||
// Alaska's square "lost and found" sleeve reached a live hero slot that
|
// Alaska's square "lost and found" sleeve reached a live hero slot that
|
||||||
// way. Real press photos measured across the fixtures run 1.33-1.9, so
|
// way. Real press photos measured across the fixtures run 1.33-1.9, so
|
||||||
// the floor sits below every one of them; portrait crops fail it too,
|
// the floor sits below every one of them. Trusted ticketing profiles
|
||||||
// which is correct for a full-bleed banner. Trusted ticketing profiles
|
|
||||||
// keep their existing exemption — that tier is identity-verified art.
|
// keep their existing exemption — that tier is identity-verified art.
|
||||||
if ratio < HERO_MIN_ASPECT && !trusted_ticketing_profile {
|
//
|
||||||
|
// PORTRAIT is admitted, though, because the guard is really an ALBUM-ART
|
||||||
|
// guard and sleeves are square: a 0.75-0.85 press portrait is not a sleeve.
|
||||||
|
// The app already crops tall sources to 16:9 around the detected faces
|
||||||
|
// (`hero_crop.rs`, recipe `vertical-yoloxnano-...-faces-first`), so these
|
||||||
|
// were being discarded one crate before the machinery built to use them.
|
||||||
|
// This is the only route to a hero for artists whose entire press corpus is
|
||||||
|
// portrait: Hana Vu (2000x2500, 1705x2129) and Nikki Nair (1080x1350,
|
||||||
|
// 1024x1365) both pass identity and died here. Text-heavy posters and
|
||||||
|
// flyers cannot sneak in this way — the text, flat-graphic and collage
|
||||||
|
// gates all run BEFORE this one.
|
||||||
|
let usable_portrait =
|
||||||
|
ratio <= HERO_PORTRAIT_MAX_ASPECT && w >= HERO_PORTRAIT_MIN_WIDTH;
|
||||||
|
if ratio < HERO_MIN_ASPECT && !usable_portrait && !trusted_ticketing_profile {
|
||||||
if diagnostics {
|
if diagnostics {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"HERO_REJECT\taspect\t{}x{}\tratio={:.2}\t{}",
|
"HERO_REJECT\taspect\t{}x{}\tratio={:.2}\t{}",
|
||||||
|
|||||||
Reference in new issue
Block a user