Skip to main content

DNG and raw image processing utilities

Project description

muimg logo

muimg

License

Python library for reading, writing, and rendering Adobe DNG (Digital Negative) raw image files. Provides both a comprehensive Python API and command-line tools for DNG manipulation, rendering, metadata handling, and multi-threaded batch processing. Performance-critical operations are implemented in C/C++ extensions, but this initial (May 1, 2026) release prioritizes rendering correctness over speed optimization.

Key Features

  • DNG Read/Write: Full support for reading, writing, and modifying Adobe DNG (Digital Negative) files.
  • RAW Rendering Pipeline: Complete implementation of DNG rendering pipeline (linearization, demosaicing, opcodes, color correction, tone curves). On macOS can opt between built-in renderer and Core Image renderer.
  • Multiple Demosaicing Algorithms: DNGSDK_BILINEAR, VNG, RCD (optional), OPENCV_EA
  • XMP Support: Renderer supports Temperature, Tint, Exposure, Curves, and radial distortion from XMP metadata.
  • Metadata Handling: User-friendly TIFF/EXIF/XMP tag handling with automatic type conversion
  • Compression: Uncompressed, JPEG, JPEG XL support with multi-core parallel compression for tiled formats
  • CLI Tools: Comprehensive command-line interface for DNG operations.
  • Batch Processing: Multi-threaded batch conversion and video encoding.

Installation

From PyPI

pip install muimg

Or in pyproject.toml:

[project]
dependencies = [
    "muimg",
]

Optional Dependencies

Video Encoding & Google Photos: For video encoding and Google Photos integration:

pip install "muimg[all]"

Core Image (macOS): For macOS users, installing the Core Image dependency enables a second rendering engine that will be available at runtime alongside the built-in renderer:

pip install "muimg[coreimage]"

Combined: To install all optional features:

pip install "muimg[all,coreimage]"

Or in pyproject.toml:

[project]
dependencies = [
    "muimg[all,coreimage]",
]

From GitHub

To install the latest development version directly from GitHub:

[project]
dependencies = [
    "muimg @ git+https://github.com/mu-files/mu-image.git#subdirectory=muimg",
]

For Local Development

Clone the repository and install the package in editable mode:

git clone https://github.com/mu-files/mu-image.git
cd mu-image/muimg
pip install -e .

Note: muimg includes C/C++ extensions that are compiled during install. macOS and Linux have built-in C compilers and require no additional setup. Windows users installing from source need Microsoft C++ Build Tools. Pre-built Windows wheels are available when installing from PyPI.

API Overview

Core Classes

DngFile: Subclass of TiffFile for reading DNG files. Provides access to IFDs (Image File Directories), metadata, and raw image data.

DngPage: Subclass of TiffPage representing a single IFD within a DNG file. Can be a raw CFA page, LinearRaw RGB page, or preview/thumbnail. Provides methods to extract raw data at various pipeline stages and render to display-referred RGB.

MetadataTags: Container for TIFF/EXIF/DNG tags with type-safe tag handling.

Reading DNGs

Opening and navigating: DngFile(path) opens a DNG file. Use ifd0 property to access IFD0, get_main_page() to get the primary raw image, or get_flattened_pages() to access all IFDs including SubIFDs.

Extracting raw data: DngPage.get_cfa() extracts CFA (Color Filter Array) data at various pipeline stages (raw, linearized, post-opcodes). DngPage.get_linear_raw() extracts LinearRaw RGB data.

Rendering to RGB: DngPage.render() applies the full DNG rendering pipeline (demosaicing, opcodes, color correction, tone curves, etc.) to produce display-referred RGB. The scale parameter allows for fast preview renders at reduced resolution. decode_dng() is a convenience function that handles file opening and rendering in one call.

Metadata access: DngPage.get_tag(name) retrieves TIFF/DNG tags with automatic type conversion (e.g., get_tag("ColorMatrix1") returns a 3×3 NumPy array).

Writing DNGs

PageEncoding: Dataclass that groups compression type and codec-specific arguments. Used to specify how image data should be compressed when -writing DNGs from an array or -transcoding a DNG page. For JXL compression, compression_args=None defaults to lossless (distance=0.0, effort=4). Example: PageEncoding(compression=COMPRESSION.JPEGXL_DNG, compression_args={'distance': 0.5, 'effort': 7}).

write_dng(): The most general function to create a DNG file. Takes an IFD0 spec and optional list of SubIFD specs (each can be IfdPageSpec or IfdDataSpec). Each spec describes the page data and how to encode it.

write_dng_from_page(): Create a DNG from an existing DngPage or IfdPageSpec. Supports transformations (scaling, demosaicing), compression transcoding (e.g., uncompressed to JXL via transcode_encoding=PageEncoding(...)), preview/pyramid generation, and tag manipulation.

write_dng_from_array(): Create a DNG from an IfdDataSpec containing a NumPy raw pixel data array and metadata. Supports preview and pyramid generation with optional compression via encoding=PageEncoding(...).

Batch Processing

Pipeline control: ProcessingPipeline class provides fine-grained control over batch processing with customizable producer/consumer/writer stages that decouple file I/O operations from pixel processing (e.g., decouple reading DngFile from disk and rendering it).

Image sequences: ImageSequencePipeline is a ProcessingPipeline for processing sequences of image files and saving the results (.tiff/.jpg) to an output folder.

Video encoding: VideoEncodePipeline is a ProcessingPipeline for encoding image sequences to video files with configurable codecs, resolution, and frame rates, and saving the result to a video file (.mp4). Requires pip install muimg[all].

Parallelism: Control parallelism with --num-workers flag in CLI or num_workers parameter in API. Default is 4 workers. Adjust based on CPU cores and memory availability.

Metadata

Tag management: MetadataTags.add_tag() adds TIFF/EXIF tags with automatic type handling. DngPage.get_page_tags() returns a MetadataTags object with metadata for that page.

Type registry: TIFF_TAG_TYPE_REGISTRY provides metadata about all supported TIFF/DNG tags, including data types, valid IFDs, and enum mappings.

CLI Commands

The muimg command provides comprehensive DNG operations:

Image Format Conversion

# Convert any image format to another
muimg convert-image input.tif output.jpg

DNG Metadata

Display and filter DNG metadata:

# Show all metadata for all IFDs
muimg dng metadata input.dng

# Show specific IFD
muimg dng metadata input.dng --ifd 0

# Filter tags by pattern
muimg dng metadata input.dng --tag "Color.*" --tag "Exposure"

# Exclude tags
muimg dng metadata input.dng --exclude-tag "XMP"

# Summary only
muimg dng metadata input.dng --summary

DNG Raw Stage Extraction

Extract raw data at specific pipeline stages:

# Extract unprocessed raw data
muimg dng raw-stage input.dng output.tif raw

# Extract after OpcodeList2
muimg dng raw-stage input.dng output.tif linearized-plus-ops

# Extract demosaiced camera RGB
muimg dng raw-stage input.dng output.tif camera-rgb --demosaic VNG

# Extract from specific IFD
muimg dng raw-stage input.dng output.tif linearized --ifd subifd2

DNG Copy and Transform

Create a new DNG from source DNG with optional transformations:

# Create a new DNG file with the main page transcoded to JXL
muimg dng copy input.dng output.dng --jxl-distance 0.5

# Scale and demosaic
muimg dng copy input.dng output.dng --scale 0.5 --demosaic

# Generate preview (1/4 scale)
muimg dng copy input.dng output.dng --preview --preview-reduce 4

# Generate preview (1/2 scale)
muimg dng copy input.dng output.dng --preview --preview-reduce 2

# Strip tags
muimg dng copy input.dng output.dng --strip-tag OpcodeList2,OpcodeList3

# Add/override tags
muimg dng copy input.dng output.dng --tag "Artist=John Doe" --tag "Copyright=2026"

# Generate raw "preview" pyramid levels
muimg dng copy input.dng output.dng --pyramid-levels 3

DNG Rendering

Convert DNG to display image with adjustments:

# Basic conversion
muimg dng convert input.dng output.jpg

# With white balance and exposure
muimg dng convert input.dng output.tif --temperature 5500 --tint 10 --exposure 0.5

# 16-bit output
muimg dng convert input.dng output.tif --bit-depth 16

# Use Core Image on macOS
muimg dng convert input.dng output.jpg --use-coreimage

# Convert specific IFD
muimg dng convert input.dng output.jpg --ifd subifd1

Batch DNG Conversion

Process multiple DNGs in parallel:

# Convert folder of DNGs to TIFF
muimg dng batch-convert /path/to/dngs/ /path/to/output/ --format tif

# Control parallelism (set to 8 here, default is 4 workers)
muimg dng batch-convert /path/to/dngs/ /path/to/output/ --format tif --num-workers 8

# Use fixed rendering parameters for each image
muimg dng batch-convert /path/to/dngs/ /path/to/output/ \
  --format jxl --temperature 5500 --exposure 0.5

# From CSV with per-file settings
# CSV format: filename,Temperature,Tint,Exposure2012,orientation
muimg dng batch-convert settings.csv /path/to/output/ --format tif

# Scaled output (uses the efficient scaling rendering path)
muimg dng batch-convert /path/to/dngs/ /path/to/output/ --scale 0.5

Batch DNG to Video

Requires: pip install muimg[all] (for video encoding support)

Create video from DNG sequence:

# Basic video creation
muimg dng batch-to-video /path/to/dngs/ output.mp4

# With rendering and encoding options
muimg dng batch-to-video /path/to/dngs/ output.mp4 \
  --resolution 1920x1080 --codec hevc --crf 20 --bit-depth 10 \
  --temperature 5500 --exposure 0.5 --frame-rate 30

# Timelapse (1 frame every 2 seconds)
muimg dng batch-to-video /path/to/dngs/ timelapse.mp4 --frame-rate 0.5

# With filename overlay
muimg dng batch-to-video /path/to/dngs/ output.mp4 --overlay-txt

# From CSV with per-file settings
muimg dng batch-to-video settings.csv output.mp4 --resolution 1920x1080

Google Photos Integration

Requires: pip install muimg[all] (for Google Photos support)

Upload images to Google Photos:

# Authenticate
muimg google-photos auth --credentials credentials.json

# Upload image
muimg google-photos upload image.jpg --album "My Album"

# List albums
muimg google-photos list-albums

Examples

make_test_dng.py

Creates size-constrained test DNG files by iteratively scaling down the image resolution until it fits within a target size. All test files were generated using this code.

python examples/make_test_dng.py input.dng output.dng --target-size 1048576
python examples/make_test_dng.py input.dng output.dng --target-size 1048576 --generate-preview

Features:

  • Iterative scaling by powers of 2 until target size is met
  • Demosaics to LINEAR_RAW in order to scale image
  • Optional JXL compression

Tests

The test suite covers DNG reading, writing, rendering, metadata handling, and CLI operations.

Running Tests

Requires: pip install muimg[all] (pytest is included in the [all] extra)

cd /path/to/mu-image/muimg
venv/bin/pytest tests/

Run specific test file:

venv/bin/pytest tests/test_dng_render.py -v

Run with detailed logging:

venv/bin/pytest tests/test_cli.py -v -s --log-cli-level=INFO

Test Categories

Note: Many tests validate results against Adobe's dng_validate tool from the DNG SDK. To use this validation:

  1. Download DNG SDK from: https://helpx.adobe.com/camera-raw/digital-negative.html
  2. Build the dng_validate tool (see SDK documentation)
  3. Place the binary at the path specified in tests/conftest.py or update DNG_VALIDATE_PATH

Tests always use muimg's built-in validator.

Note: Test image files (~80 MB) are stored in a separate repository (mu-files/mu-image-testdata) and are automatically downloaded on the first test run.

DNG Rendering (test_dng_render.py): Tests the full rendering pipeline, including linearization, demosaicing, color correction, tone curves, and output color space conversion for a variety of real camera DNG files (scaled to download-friendly resolution) and compares results against dng_validate.

Metadata Handling (test_metadata_*.py): Tests TIFF tag reading/writing, endianness handling, XMP parsing, and Core Graphics metadata extraction on macOS.

Write Operations (test_write_dng*.py): Tests DNG creation from arrays, page copying, compression options, and tag manipulation.

Roundtrip Tests (test_*_roundtrip.py): Tests that read-modify-write operations preserve data correctly (color temperature, SubIFD structure).

CLI Commands (test_cli.py): Tests command-line interface functionality.

Preview and Pyramid (test_preview_rendering.py, test_pyramid_subifd.py): Tests thumbnail/preview generation and pyramid-level creation.

Demosaicing (test_demosaic.py): Tests various demosaicing algorithms.

Known Issues

Not Implemented

The following DNG features are not yet implemented:

  • Triple-illuminant: Support for 3 calibration illuminants (ColorMatrix3, CalibrationIlluminant3)
  • RGBTables: DNG version 1.6+ per-channel 1D LUTs
  • ReductionMatrix: Support for cameras with >3 color channels
  • SemanticMasks: DNG v1.6+ depth maps and segmentation masks
  • HDR/Overrange: ProfileDynamicRange and extended dynamic range support

See docs/dng_render_pipeline.md for detailed implementation status of each pipeline stage.

Performance Notes

Demosaicing Algorithms: muimg includes several demosaicing algorithms with different quality/speed tradeoffs:

  • DNGSDK_BILINEAR: Good quality, fast (default for most operations)
  • VNG: High quality, slower
  • OPENCV_EA: Fastest, lower quality
  • RCD (optional, GPL-licensed): High quality, slower

The RCD (Ratio Corrected Demosaicing) algorithm is disabled by default because it's licensed under GPL v3, which is separate from muimg's PolyForm Small Business license. To enable RCD:

  1. Rename c-src/demosaic/rcd.txt to c-src/demosaic/rcd.c
  2. Rebuild: pip install -e .

By enabling RCD, you accept the GPL v3 license terms for that component. The RCD source is based on Luis Sanz Rodríguez's implementation.

Core Image Rendering: On macOS, Core Image provides native DNG rendering. Use --use-coreimage flag in CLI or use_coreimage_if_available=True in API.

Technical Documentation

For detailed technical documentation on the DNG rendering pipeline, including tag reference, pipeline stages, and implementation status, see:

docs/dng_render_pipeline.md

This document provides:

  • Complete pipeline flowchart from raw sensor data to display RGB
  • Tag reference organized by pipeline stage
  • Implementation status for each stage
  • Detailed explanations of color matrix calculations, tone curves, and opcode processing

License

This software is released under a modified PolyForm Small Business License 1.0.0.

Free for:

  • Small businesses (<100 employees, <$10M revenue)
  • Individuals
  • Academic institutions
  • Non-profit organizations
  • Government entities (non-commercial use)

Large enterprises require a commercial license. Contact: license@mu-files.com

⚠️ AI Training Notice: The core implementation source code is NOT licensed for AI/ML training. However, documentation, tests, examples, and CLI code are available for learning the API. See llms.txt and robots.txt for details.

See LICENSE for full terms.

Third-Party Components

  • Adobe DNG SDK: Adobe DNG SDK License (permissive, royalty-free)
  • VNG Demosaicing: LGPL v2.1 / CDDL v1.0
  • RCD Demosaicing (optional): GPL v3

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

muimg-0.1.20260531.1501.tar.gz (268.6 kB view details)

Uploaded Source

Built Distributions

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

muimg-0.1.20260531.1501-cp313-cp313-win_amd64.whl (239.2 kB view details)

Uploaded CPython 3.13Windows x86-64

muimg-0.1.20260531.1501-cp312-cp312-win_amd64.whl (239.2 kB view details)

Uploaded CPython 3.12Windows x86-64

File details

Details for the file muimg-0.1.20260531.1501.tar.gz.

File metadata

  • Download URL: muimg-0.1.20260531.1501.tar.gz
  • Upload date:
  • Size: 268.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for muimg-0.1.20260531.1501.tar.gz
Algorithm Hash digest
SHA256 f3ac39c042a83b60dc7b80653091e3155bf23178d19bad46bd50fec7fec75d55
MD5 a57f7bc7adf40a6c1a6f780d2477399d
BLAKE2b-256 65bbdd25db0a045b971bf0a430351b4b242fe7c3d378236d7a325bf9c3dffba7

See more details on using hashes here.

Provenance

The following attestation bundles were made for muimg-0.1.20260531.1501.tar.gz:

Publisher: publish.yml on mu-files/mu-image

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

File details

Details for the file muimg-0.1.20260531.1501-cp313-cp313-win_amd64.whl.

File metadata

File hashes

Hashes for muimg-0.1.20260531.1501-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 8d0cf29bc160b7fc94752485981786dc002a062241b9e11a016ed4026afc7a3f
MD5 25330c2193aade588da36f2a3cd81303
BLAKE2b-256 0670d4ba9d9ea1d2dab9d081f720c1265641840029050a82bbac1cb1f6475028

See more details on using hashes here.

Provenance

The following attestation bundles were made for muimg-0.1.20260531.1501-cp313-cp313-win_amd64.whl:

Publisher: publish.yml on mu-files/mu-image

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

File details

Details for the file muimg-0.1.20260531.1501-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for muimg-0.1.20260531.1501-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 fde891a3407b58dd885098776dcce3a91e677ced09d767215d82b8fa62693df9
MD5 f30c8875a4f67f5b10458c38c50f715f
BLAKE2b-256 842efae0f7b8f3483ee63ffc677707b12cf950178683c0c476ee0c9837d4b4ad

See more details on using hashes here.

Provenance

The following attestation bundles were made for muimg-0.1.20260531.1501-cp312-cp312-win_amd64.whl:

Publisher: publish.yml on mu-files/mu-image

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