Byte-split depth PNG: lossless single-file container for uint16 depth images
Project description
pngd
Lossless single-file container for 16-bit depth images, stored as two byte-split 8-bit PNGs.
For depth maps from RealSense-style cameras, .pngd is consistently
smaller than a single uint16 PNG of the same image — ~1.2–1.5× on
typical frames, more on scenes with large flat regions — while
remaining bit-exact and decoder-friendly.
See docs/format.md for the normative format spec.
Install
pip install pngd
Use
As a function
import numpy as np
import pngd
depth = np.load("frame.npy").astype(np.uint16) # (H, W) uint16
pngd.save_depth(depth, "frame.pngd")
roundtrip = pngd.load_depth("frame.pngd")
assert np.array_equal(depth, roundtrip)
Through Pillow
Importing pngd registers the format with Pillow, so the usual
Image.open / img.save flow works:
import pngd # registers the PNGD plugin
from PIL import Image
img = Image.open("frame.pngd") # mode "I;16"
img.save("copy.pngd") # round-trips losslessly
You can also save any 16-bit Pillow image to .pngd:
from PIL import Image
import pngd # noqa: F401
Image.open("frame_16bit.png").save("frame.pngd")
Streams
import io, pngd
buf = io.BytesIO()
pngd.save_depth_stream(depth, buf)
buf.seek(0)
restored = pngd.load_depth_stream(buf)
When to use this
- You have many uint16 depth frames and storage matters.
- You need a single file per frame (e.g. for indexing, archival, S3 keys).
- You don't want to invent your own naming scheme to keep the hi/lo PNG pair from getting separated.
If you only need the in-memory split, the existing
save_depth_bytesplit / load_depth_bytesplit helpers that write two
side-by-side files remain fine.
Compatibility
- Python 3.9+
- NumPy 1.20+
- Pillow 9.0+
Releasing
Releases are cut by publishing a GitHub Release; the
Release workflow builds an sdist
and wheel and publishes them to PyPI via trusted publishing (OIDC),
so no API tokens are stored in the repo.
To cut a release:
- Bump
versioninpyproject.toml(and__version__insrc/pngd/__init__.py) and commit. - Create a GitHub Release whose tag is
vX.Y.Z(matching thepyproject.tomlversion exactly). The release workflow refuses to publish if the two disagree. - The workflow builds, runs
twine check, and uploads to PyPI.
One-time PyPI setup
Before the first release, configure the PyPI project as a Trusted Publisher (no API token needed):
- Go to https://pypi.org/manage/account/publishing/ and add a
pending trusted publisher with:
- PyPI Project Name:
pngd - Owner:
safijari - Repository name:
pngd - Workflow name:
release.yml - Environment name:
pypi
- PyPI Project Name:
- In the GitHub repo, create an Environment named
pypi(Settings → Environments → New environment). Optionally add required reviewers so a human has to approve each publish.
After the first successful publish PyPI converts the pending publisher to a normal one automatically.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pngd-0.1.0.tar.gz.
File metadata
- Download URL: pngd-0.1.0.tar.gz
- Upload date:
- Size: 9.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
494bab10062e4ca25f6e6ef055c2fe1d316b64b799e7435806b82dc2719c6ae6
|
|
| MD5 |
78ab792675181e4c335f2da88753a147
|
|
| BLAKE2b-256 |
cb019e0609749a675dfff208115cd29d5b6992051dcfc507c05dcb2aac3ff5dd
|
Provenance
The following attestation bundles were made for pngd-0.1.0.tar.gz:
Publisher:
release.yml on safijari/pngd
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pngd-0.1.0.tar.gz -
Subject digest:
494bab10062e4ca25f6e6ef055c2fe1d316b64b799e7435806b82dc2719c6ae6 - Sigstore transparency entry: 1607870333
- Sigstore integration time:
-
Permalink:
safijari/pngd@ee22f9beeebdd6ab27dd4268d46824ff2571d7bf -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/safijari
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ee22f9beeebdd6ab27dd4268d46824ff2571d7bf -
Trigger Event:
release
-
Statement type:
File details
Details for the file pngd-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pngd-0.1.0-py3-none-any.whl
- Upload date:
- Size: 7.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
31ea44037e6420e2767a9e826958078c4e846928c51fee60c8452c8afe1af854
|
|
| MD5 |
a60b8ab599627cb454ecece7943dffb7
|
|
| BLAKE2b-256 |
3348215ba25ef37b86bae14ca04960eb6a63a359068d119ba82f669a75873990
|
Provenance
The following attestation bundles were made for pngd-0.1.0-py3-none-any.whl:
Publisher:
release.yml on safijari/pngd
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pngd-0.1.0-py3-none-any.whl -
Subject digest:
31ea44037e6420e2767a9e826958078c4e846928c51fee60c8452c8afe1af854 - Sigstore transparency entry: 1607870397
- Sigstore integration time:
-
Permalink:
safijari/pngd@ee22f9beeebdd6ab27dd4268d46824ff2571d7bf -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/safijari
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ee22f9beeebdd6ab27dd4268d46824ff2571d7bf -
Trigger Event:
release
-
Statement type: