CameraShotPicker is a macOS SwiftUI app for quickly triaging camera RAW files from an SD card or local folder. It helps you browse a shoot, estimate image sharpness, mark keepers, and copy the selected original files to an export folder.
The app is intentionally small and local-first: it uses Apple frameworks for RAW decoding and image analysis, keeps file access scoped to user-selected folders, and does not require external services or third-party packages.
- Detects likely camera SD cards mounted under
/Volumes. - Opens a manually selected folder when a card is not detected.
- Scans for supported RAW files in the selected folder.
- Generates thumbnails for review.
- Scores images with a sharpness heuristic.
- Selects sharp images based on an adjustable threshold.
- Lets you manually toggle individual selections.
- Sorts the grid by sharpness after analysis.
- Copies selected original files to a destination folder while avoiding duplicate filename collisions.
CameraShotPicker currently scans for these file extensions:
CR3, CR2, NEF, ARW, DNG, RAF, SRW, ORF, RW2, PEF, and X3F.
RAW decoding quality and format support depend on the Core Image RAW pipeline available in the installed macOS version.
- macOS
- Xcode, for the macOS SDK and build toolchain
- PowerShell 7+ (
pwsh), for the helper scripts - A mounted camera SD card or a folder containing supported RAW files
The app has no third-party runtime dependencies.
Open the repository in VS Code:
code .Build, test, launch, and install from VS Code's integrated terminal with the helper scripts below. Xcode still needs to be installed because it provides the macOS SDK and build tools.
If you need Xcode's debugger or project settings UI, open the project file directly:
open CameraShotPicker.xcodeproj- Mount a camera SD card, or click Browse Folder... and choose a folder.
- Review the image grid as thumbnails load.
- Click Analyze All to calculate sharpness scores.
- Adjust the sharpness threshold if needed.
- Use Select Sharp or select/deselect images manually.
- Click Export Selected and choose a destination folder.
When an SD card contains RAW files, the app opens the narrowest folder that contains all of them. Folder scans include supported RAW files in subfolders.
The repository includes VS Code task and debug configuration under .vscode/.
Use Run and Debug in VS Code, then choose Debug CameraShotPicker to build and launch the app under LLDB. Install the recommended extensions when VS Code prompts for them.
Run these from the repository root in VS Code's integrated terminal:
pwsh -NoProfile -File scripts/Build-App.ps1
pwsh -NoProfile -File scripts/Run-Tests.ps1
pwsh -NoProfile -File scripts/Run-App.ps1
pwsh -NoProfile -File scripts/Install-App.ps1Each script accepts an optional build configuration:
pwsh -NoProfile -File scripts/Build-App.ps1 -Configuration Release
pwsh -NoProfile -File scripts/Run-Tests.ps1 -Configuration Release
pwsh -NoProfile -File scripts/Run-App.ps1 -Configuration Release
pwsh -NoProfile -File scripts/Install-App.ps1 -Configuration ReleaseCommand capabilities:
scripts/Build-App.ps1: builds the app withxcodebuildintobuild/DerivedData.scripts/Run-Tests.ps1: runs the XCTest suite for theCameraShotPickerscheme.scripts/Run-App.ps1: launches the built.appfrombuild/DerivedData; run the build script first.scripts/Install-App.ps1: copies the built.appto~/Applications, replacing an existingCameraShotPicker.appthere.
VS Code task capabilities:
- Build App (Debug): default build task.
- Build App (Release): release build task.
- Run Tests: default test task.
- Run App: builds and opens the Debug app.
- Install App: builds and copies the Debug app to
~/Applications.
Run these commands from the repository root:
xcodebuild -list -project CameraShotPicker.xcodeproj
xcodebuild -project CameraShotPicker.xcodeproj -scheme CameraShotPicker -configuration Debug -derivedDataPath build/DerivedData build
xcodebuild -project CameraShotPicker.xcodeproj -scheme CameraShotPicker -configuration Debug -derivedDataPath build/DerivedData -destination 'platform=macOS' testThe build/DerivedData path keeps generated build output inside the ignored build/ directory.
CameraShotPicker/CameraShotPickerApp.swift: SwiftUI app entry point and window setup.CameraShotPicker/Views/: sidebar, image grid, analysis controls, and export UI.CameraShotPicker/ViewModels/: browsing, analysis, and selection coordination.CameraShotPicker/Models/: observable RAW image state.CameraShotPicker/Utilities/: SD-card detection, RAW decoding, sharpness analysis, and file copying.CameraShotPickerTests/: XCTest coverage for deterministic logic.docs/: architecture and development notes.
- Prefer VS Code for day-to-day editing and the terminal helper scripts for build/test/run tasks.
- Use
xcodebuildor Xcode project settings when you need lower-level Xcode project behavior; this is a macOS app, not a Swift Package-first project. - Keep tests independent of mounted SD cards, real camera RAW files, and GUI automation.
- Use temporary directories for file-copy tests.
- Preserve user-selected file access behavior when changing import or export flows.
- If Python tooling is added later, use
python3from the activepyenvversion on this machine.
- Very large folders may take longer to scan because supported RAW files are discovered recursively.
- Sharpness scores are heuristic and are best used for ranking candidates, not as a final quality judgment.
- Unit tests avoid real RAW decoding and SD-card hardware.
- RAW decode support varies by camera format and macOS version.
docs/architecture.md: runtime flow and source responsibilities.docs/development.md: setup, verification, and testing guidance.AGENTS.md: agent-specific project instructions.