HDR+ Swift is a Swift implementation of Google's HDR+ burst photography algorithm, designed for computational photography on macOS. This project aims to bring powerful HDR image processing to Swift developers and photography enthusiasts.
- Multi-frame burst photography processing
- Automatic alignment of burst frames
- Temporal merging for noise reduction
- HDR tone mapping
- Local and global contrast enhancement
Clone this repository and open the Xcode project:
git clone https://github.com/SZim92/hdr-plus-swift.git
cd hdr-plus-swift
open burstphoto.xcodeproj
- macOS 13.0+ (Ventura)
- Xcode 15.0+
- Swift 5.9+
This project uses GitHub Actions for continuous integration. For details on the CI system, see CI_DOCS.md.
- macOS-only Testing: Due to Metal API requirements, automated testing is only performed on macOS platforms (currently Sonoma and Ventura).
- Build Verification: CI primarily verifies that the code builds successfully and collects Metal environment diagnostics.
- Local Testing: For full testing including Metal shaders, use physical devices with proper GPU support.
This project follows consistent markdown formatting standards to ensure documentation readability and accessibility. For details on the standards and how to check your files, see MARKDOWN_STANDARDS.md.
We provide tools to help maintain consistent markdown formatting:
- Automated Fixing: Run
.\fix-markdown.ps1
(Windows) or./fix-markdown.sh
(macOS/Linux) to automatically fix common formatting issues - CI Linting: The
markdown-lint.yml
workflow checks documentation formatting on PRs and pushes - Editor Integration: Configure your editor with markdownlint for real-time feedback
Burst Photo is a macOS app written in Swift / SwiftUI / Metal that implements a simplified version of HDR+, the computational photography pipeline in Google Pixel phones. With Burst Photo, this processing can be applied to a burst of images from any camera, increasing dynamic range and reducing noise of the resulting image. You can read more about HDR+ in Google's paper Burst photography for high dynamic range and low-light imaging on mobile cameras.
If you are a researcher or you prefer Python/PyTorch, you can check out hdr-plus-pytorch.
In the example, a burst of 51 images was taken at ISO 51,200 on a Sony A7S III camera. Exposure was adjusted to taste with equal settings for both images. Here is a comparison of a single image from the burst versus a merge of all the images.
To test motion-robustness, a burst with strong scene motion is evaluated. Here is a full comparison of results. The figure is similar to Figure 6 in Google's original publication. The input image was taken from Google's HDR+ dataset licensed under CC BY-SA.
For more examples, please visit burst.photo/gallery/.
To process a burst of RAW images, simply drag-and-drop them into the app. Only DNG files are supported by default - but if you download and install Adobe DNG Converter, Burst Photo will be able to convert most RAW formats in the background. The resulting image will be in the RAW-DNG format and can be further processed with the RAW converter of choice. You can read more at burst.photo/help/.
You can download the app from the Mac App Store or as a GitHub release.
-
DNG support
-
RAW support (requires Adobe DNG Converter to be installed)
-
simple temporal averaging
-
motion-robust merge in spatial domain (simplified)
-
motion-robust merge in frequency domain (similar to original publication)
-
Bayer sensor support
-
non-Bayer sensor support (beta)
-
support for bursts with bracketed exposure
-
optional exposure correction to improve tonality in the shadows
-
optional output with full 16 bit precision
-
preserves lens profiles
-
hot pixel suppression
-
multi-threaded RAW conversion and image loading
-
caching of converted DNGs both on disk and in-memory
-
align+merge running in pure Metal
-
native Intel, Apple Silicon support
-
add super-resolution algorithm
-
add support for demosaic images (or foveon cameras)
-
fix progressbar getting stuck loading the first image
Please feel free to contribute to any of these features or suggest other features.
This product includes DNG technology under license by Adobe.
This repository includes a comprehensive testing framework designed specifically for HDR image processing. The framework provides tools and utilities to ensure proper functionality, performance, and visual consistency in the HDR+ processing pipeline.
-
Visual Testing: The
VisualTestUtility
provides specialized support for comparing and validating HDR images, including perceptual comparison and HDR-specific tolerance settings. -
Performance Testing: The
HDRPerformanceTestHelper
enables detailed performance analysis of HDR processing, including CPU and GPU timing, memory usage tracking, and pipeline stage analysis. -
Result Visualization: The
HDRResultVisualizer
generates visual reports of HDR processing, combining input brackets, output image, histograms, and metadata for easy visual inspection. -
Quarantine System: A
TestQuarantine
utility manages flaky tests, allowing them to be tracked, analyzed, and temporarily disabled with proper documentation.
To run the tests locally:
swift test --filter "HDRVisualTests"
For performance tests:
swift test --filter "HDRPerformanceTests"
The project includes specialized GitHub Actions workflows for testing:
- HDR Visual Tests: Runs visual comparison tests on macOS systems with Metal support
- Test Quarantine: Automatically analyzes test stability and manages flaky tests
- Performance Monitoring: Tracks and reports performance metrics across changes
When creating new HDR tests, use the provided utilities:
// Visual comparison test
func testHDRProcessing() throws {
// Process your HDR image
let result = processHDRImages()
// Compare with reference image with HDR-specific settings
try assertHDRImage(
result,
matchesReferenceNamed: "expected_hdr_result"
)
}
// Performance test
func testPerformance() throws {
let metrics = measureHDRPipeline(
name: "HDR Processing Pipeline",
stages: [
"Alignment": alignmentOperation,
"Merging": mergingOperation,
"ToneMapping": toneMappingOperation
]
)
// Analyze results
XCTAssertLessThan(metrics.totalTime, 0.5)
}
When contributing to the HDR+ Swift project, make sure to:
- Write tests for any new functionality
- Run the test suite locally before submitting a PR
- Document any test quarantines with appropriate ticket references
[Insert your license information here]