diff --git a/app/routes.py b/app/routes.py index 743d1d0..7f41b81 100644 --- a/app/routes.py +++ b/app/routes.py @@ -8,7 +8,7 @@ from flask import abort, redirect, render_template, request, send_file, url_for from . import assembler, jobs, validation -def _process_pair(job_dir, index, sdr_file, hdr_file): +def _process_pair(job_dir, index, sdr_file, hdr_file, ignore_ig_resolution=False): """Runs one SDR/HDR pair through validation + assembly. Returns an item dict for the job report; never raises — failures are recorded in it.""" name = hdr_file.filename or sdr_file.filename or f"pair {index}" @@ -28,7 +28,7 @@ def _process_pair(job_dir, index, sdr_file, hdr_file): sdr_file.save(sdr_path) hdr_file.save(hdr_path) - ig_error = validation.instagram_resolution_error(sdr_path, hdr_path) + ig_error = validation.instagram_resolution_error(sdr_path, hdr_path, ignore_ig_resolution) if ig_error: for p in (sdr_path, hdr_path): p.unlink(missing_ok=True) @@ -62,11 +62,13 @@ def register_routes(app): if len(sdr_files) != len(hdr_files): return render_template("index.html", error="Each pair needs both an SDR and an HDR file."), 400 + ignore_ig_resolution = request.form.get("ignore_ig_resolution") == "on" + job_id = uuid.uuid4().hex[:12] job_dir = jobs.new_job_dir(job_id) items = [ - _process_pair(job_dir, i, sdr_file, hdr_file) + _process_pair(job_dir, i, sdr_file, hdr_file, ignore_ig_resolution) for i, (sdr_file, hdr_file) in enumerate(zip(sdr_files, hdr_files), start=1) ] diff --git a/app/validation.py b/app/validation.py index b0b6613..946aaea 100644 --- a/app/validation.py +++ b/app/validation.py @@ -42,9 +42,17 @@ def probe_dimensions(path: Path) -> tuple[int, int]: raise ValueError(f"could not read image dimensions ({e})") from e -def instagram_resolution_error(sdr_path: Path, hdr_path: Path) -> str | None: +def instagram_resolution_error( + sdr_path: Path, hdr_path: Path, ignore_ig_resolution: bool = False, +) -> str | None: """Returns an error message if the pair doesn't meet Instagram's feed - requirements, otherwise None.""" + requirements, otherwise None. + + The dimension-match check always applies: mismatched SDR/HDR + dimensions misalign the gain map regardless of what platform the + result is for. ignore_ig_resolution skips only the exact-match check + against Instagram's own feed resolutions, for results meant for + somewhere other than Instagram.""" try: sdr_w, sdr_h = probe_dimensions(sdr_path) hdr_w, hdr_h = probe_dimensions(hdr_path) @@ -57,7 +65,7 @@ def instagram_resolution_error(sdr_path: Path, hdr_path: Path) -> str | None: "dimensions, otherwise the gain map will misalign." ) - if (sdr_w, sdr_h) not in IG_RESOLUTIONS: + if not ignore_ig_resolution and (sdr_w, sdr_h) not in IG_RESOLUTIONS: allowed = ", ".join(f"{w}x{h} ({label})" for (w, h), label in IG_RESOLUTIONS.items()) return f"Image is {sdr_w}x{sdr_h} — Instagram requires an exact match to one of: {allowed}." diff --git a/static/style.css b/static/style.css index b812a1b..7e14052 100644 --- a/static/style.css +++ b/static/style.css @@ -118,6 +118,18 @@ form { display: block; } .add-duo:hover { color: var(--text); border-color: var(--accent-dim); } +.checkbox-row { + display: flex; + align-items: center; + gap: 0.5rem; + margin: 1rem 0; + font-size: 0.85rem; + color: var(--text-muted); + cursor: pointer; +} + +.checkbox-row input { cursor: pointer; } + .dropzones { display: grid; grid-template-columns: 1fr 1fr; diff --git a/templates/index.html b/templates/index.html index 321a298..4c105da 100644 --- a/templates/index.html +++ b/templates/index.html @@ -40,16 +40,23 @@ + +
- Each pair's files must have identical dimensions, matching exactly one of Instagram's feed
- resolutions: 1080x1080 (1:1), 1080x1350 (4:5), or
- 1080x566 (1.91:1). Assembling more than one pair downloads as a .zip.
- HDR can be a regular gain-map JPEG or Lightroom's 32-bit float linear HDR TIFF export; a
- TIFF HDR file gives a more precise result than the JPEG gain-map route.
+ Each pair's files must have identical dimensions. By default that must also match one of
+ Instagram's feed resolutions exactly: 1080x1080 (1:1),
+ 1080x1350 (4:5), or 1080x566 (1.91:1); check the box above
+ to skip that check for results meant for somewhere other than Instagram. Assembling more
+ than one pair downloads as a .zip. HDR can be a regular gain-map JPEG or
+ Lightroom's 32-bit float linear HDR TIFF export; a TIFF HDR file gives a more precise result
+ than the JPEG gain-map route.
Instagram HDR Assembler v{{ app_version }}