Thank you for your interest in PhotoMark! We welcome community bug reports, feature suggestions, and code contributions.
To keep the codebase clean, stable, and efficient to collaborate on, please read this guide carefully before submitting code.
- Node.js: >= 18.0.0
- Yarn: >= 1.22.0
- Rust: >= 1.80.0 (recommended:
rustup toolchain install stable) - Tauri CLI: 2.0+
Arch Linux example:
sudo pacman -S --needed webkit2gtk-4.1 gtk3 libsoup3 cairo gdk-pixbuf2 glib2# Clone the repository
git clone https://github.com/vectorfruit/photomark.git
cd photomark
# Install frontend dependencies
yarn install
# Start the dev server and Tauri debug window (with hot reload)
yarn tauri dev- Rust backend (
src-tauri/src/)exif_reader.rs: extracts camera make, model, lens, aperture, shutter, ISO and other EXIF metadata from original images at high speed.image_engine.rs: image decoding, color space handling, lossless original binary reading and saving.commands.rs: Tauri IPC command registration and async event emitters (parsing progress, batch progress).
- Frontend renderer (
src/renderer/)canvasRenderer.ts: 2D Canvas vector layout/redraw for each frame template.blurEngine.ts: in-house 3-Pass convolution multi-level downsampled Gaussian blur, delivering frosted-glass quality efficiently on any WebKitGTK platform.logoManager.ts: camera manufacturer fuzzy matching and vector SVG caching.
- State & main controller (
src/main.ts)- Handles queue management, drag-and-drop import, debounced live preview, light/dark theme switching, UI scaling, and export flows.
- Prepare two high-resolution vector SVG files: dark variant (
brand-b.svg) and light variant (brand-w.svg). - Place them in
public/logos/. - Register the brand in
BRAND_LOGOSinsidesrc/renderer/logoManager.tsand add detection rules todetectBrandId(make, model)for the EXIF make/model strings. - Add an option in the brand dropdown
<select id="cfg-brand-logo">inindex.html.
- Add the new template identifier to the
FrameTemplateIdtype insrc/types.ts. - Implement the corresponding rendering function, e.g.
renderMyNewTemplate(...), insrc/renderer/canvasRenderer.ts. - Add the corresponding card to the template grid in
index.htmland configure styles insrc/styles.css.
We follow the standard Conventional Commits. The commit message format is:
<type>(<scope>): <description>
feat: new featurefix: bug fixperf: performance improvementrefactor: code refactoring (no external behavior change)style: formatting or UI style changesdocs: documentation changeschore: build configuration, dependency updates, misc tasks
git commit -m "feat(renderer): add vintage polaroid frame template"
git commit -m "fix(exif): fix focal length parsing on legacy manual lenses"
git commit -m "perf(blur): optimize box blur array iteration using TypedArrays"- Fork this project and create your feature branch from
master:git checkout -b feat/my-new-feature
- Write code, run local formatting and type checks:
yarn build cargo check --manifest-path src-tauri/Cargo.toml
- Ensure all changes compile without warnings.
- Commit and push to your fork:
git push origin feat/my-new-feature
- Open a Pull Request on GitHub with a detailed description of the motivation, verification steps, and screenshots.
By contributing to PhotoMark, you agree that your contributions are released under the GNU General Public License v3.0 (GPLv3).