1st commit
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
> [!NOTE]
|
||||
> ⚠️ _This is an heavily vibe-coded proof of concept — **do not expose it to the internet** — use it at your own risk._
|
||||
> _Github repo is a mirror of https://git.djeex.fr/Djeex/insta-hdr-converter. You'll find full package, history and release note there._
|
||||
|
||||
# Instagram HDR Assembler
|
||||
|
||||
A small web front end for assembling Instagram-compatible HDR JPEGs (gain
|
||||
map) from an SDR export and an HDR export out of Lightroom or Camera Raw.
|
||||
|
||||
The gain-map assembly logic ([app/assembler.py](app/assembler.py)) is
|
||||
adapted from [kostis-kounadis/instagram-hdr-assembler](https://github.com/kostis-kounadis/instagram-hdr-assembler),
|
||||
itself based on the reverse-engineering work of
|
||||
[karachungen/instagram-hdr-converter](https://github.com/karachungen/instagram-hdr-converter).
|
||||
Original MIT license kept in [LICENSE](LICENSE).
|
||||
|
||||
Only the upstream's Method 2 (starting from an HDR JPEG that already
|
||||
carries a gain map) is implemented here. Method 1's AVIF decoding and
|
||||
its quality/transfer/gamut settings were dropped, but the HDR side can
|
||||
still be a 32-bit float linear TIFF (Lightroom's HDR TIFF export)
|
||||
instead of a gain-map JPEG for a more precise result. Either way the
|
||||
gain map is recomputed rather than reused as-is (see below), since it
|
||||
needs to be correct against the SDR file you actually provide.
|
||||
|
||||

|
||||
|
||||
## How it works
|
||||
|
||||
1. Upload an SDR file (`.jpg`/`.jpeg`) and an HDR file: either a gain-map
|
||||
JPEG (`.jpg`/`.jpeg`) or Lightroom's 32-bit float linear HDR TIFF
|
||||
export (`.tif`/`.tiff`).
|
||||
2. Both files must have identical dimensions and match one of Instagram's
|
||||
feed resolutions exactly: `1080x1080` (1:1), `1080x1350` (4:5), or
|
||||
`1080x566` (1.91:1).
|
||||
3. The real HDR pixel data is obtained from the HDR file: decoded back
|
||||
out of a gain-map JPEG (`ultrahdr_app`, undoing its own embedded base
|
||||
image and gain map), or read directly from a linear TIFF and given
|
||||
HLG's system-gamma OOTF so it's on the same display-referred scale a
|
||||
gain-map JPEG's HDR intent would be. A gain map is only correct
|
||||
against the exact base it was computed from, and that's rarely the
|
||||
SDR file you upload, so reusing an existing one as-is would quietly
|
||||
reconstruct the wrong HDR look. Your SDR file is cleaned up and
|
||||
re-encoded at 4:2:0 chroma subsampling (Pillow), then a fresh gain map
|
||||
is computed against it and packaged into the final UltraHDR JPEG
|
||||
(`ultrahdr_app`). The output's visible image is exactly your SDR file;
|
||||
only the gain map is recomputed. The TIFF route skips the gain-map
|
||||
JPEG's 8-bit-in-8-bit precision ceiling, giving a more accurate result.
|
||||
4. The validation report is shown on the result page, including the
|
||||
"GainMapMin is negative" warning when present, with a download link
|
||||
for the finished JPEG.
|
||||
|
||||
Uploads and results don't stick around: SDR/HDR originals are deleted
|
||||
right after conversion, the result a few seconds after you leave the
|
||||
result page (heartbeat + background reaper), and `jobs/` is wiped on every
|
||||
app startup.
|
||||
|
||||
|
||||
## Running locally, without Docker
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
# also install exiftool and compile libultrahdr, see docker/Dockerfile
|
||||
# for the exact packages and commands (validated on Alpine)
|
||||
PORT=5050 python3 main.py # PORT is optional, defaults to 5000
|
||||
```
|
||||
|
||||
## Running with Docker
|
||||
|
||||
```bash
|
||||
docker compose -f docker/compose.yaml up -d --build
|
||||
```
|
||||
|
||||
Opens on `http://<host>:5050` (port 5000 collides with AirPlay Receiver on
|
||||
macOS, hence 5050 by default; change it in `docker/compose.yaml` if
|
||||
needed).
|
||||
|
||||
## Running this on the open internet
|
||||
|
||||
Don't do it.
|
||||
Reference in New Issue
Block a user