Skip to main content

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:

  1. Bump version in pyproject.toml (and __version__ in src/pngd/__init__.py) and commit.
  2. Create a GitHub Release whose tag is vX.Y.Z (matching the pyproject.toml version exactly). The release workflow refuses to publish if the two disagree.
  3. 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
  • 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pngd-0.1.0.tar.gz (9.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pngd-0.1.0-py3-none-any.whl (7.8 kB view details)

Uploaded Python 3

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

Hashes for pngd-0.1.0.tar.gz
Algorithm Hash digest
SHA256 494bab10062e4ca25f6e6ef055c2fe1d316b64b799e7435806b82dc2719c6ae6
MD5 78ab792675181e4c335f2da88753a147
BLAKE2b-256 cb019e0609749a675dfff208115cd29d5b6992051dcfc507c05dcb2aac3ff5dd

See more details on using hashes here.

Provenance

The following attestation bundles were made for pngd-0.1.0.tar.gz:

Publisher: release.yml on safijari/pngd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for pngd-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 31ea44037e6420e2767a9e826958078c4e846928c51fee60c8452c8afe1af854
MD5 a60b8ab599627cb454ecece7943dffb7
BLAKE2b-256 3348215ba25ef37b86bae14ca04960eb6a63a359068d119ba82f669a75873990

See more details on using hashes here.

Provenance

The following attestation bundles were made for pngd-0.1.0-py3-none-any.whl:

Publisher: release.yml on safijari/pngd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page