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;
|
||||
/// every press photo across the probe fixtures measures 1.33 or wider.
|
||||
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;
|
||||
/// 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
|
||||
@@ -8902,10 +8911,22 @@ fn score_bing_hero_image(
|
||||
// collage detector only runs at `text_penalty <= 0.70`). Camping in
|
||||
// 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
|
||||
// the floor sits below every one of them; portrait crops fail it too,
|
||||
// which is correct for a full-bleed banner. Trusted ticketing profiles
|
||||
// the floor sits below every one of them. Trusted ticketing profiles
|
||||
// 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 {
|
||||
eprintln!(
|
||||
"HERO_REJECT\taspect\t{}x{}\tratio={:.2}\t{}",
|
||||
|
||||
Reference in new issue
Block a user