Skip to content

About

Camera application for the COSMIC™ desktop environment

Resources

Stars

59 stars

Watchers

1 watching

Forks

Repository files navigation

Camera

Sponsor Flathub Alpine Linux Edge package CI Release Translation status

A modern camera application for Linux, built for desktops and phones alike.

Camera app icon Get it on Flathub

Camera Preview

View more screenshots

Features

  • Photo, video and timelapse modes, with a self timer, composition guides and aspect ratios
  • Manual controls for exposure, ISO, shutter, focus, white balance and colour, plus pan and tilt on motorised cameras
  • GPU accelerated preview, filters and debayering via wgpu, with hardware video encoding (VA-API, NVENC, QSV, AMF, V4L2) and software fallback
  • 14 creative filters applied live to the preview, photos, recordings and the virtual camera
  • QR code scanner that opens links and connects to WiFi through NetworkManager
  • Virtual camera over PipeWire, so other apps see your filtered feed in video calls
  • JPEG, PNG and DNG output, including true sensor raw where libcamera exposes a raw stream
  • Motion Photo captures in JPEG or AVIF, with an embedded short video
  • Multi-camera and multi-microphone switching with hotplug support
  • Rebindable keyboard shortcuts, plus an insights panel and bug report generator for diagnostics

Built with libcosmic. It runs on any Wayland or X11 desktop, following the system light/dark preference through the XDG portal, and integrates natively with COSMIC where available.

Status

This is a personal project by Frederic Laing. It is not affiliated with or endorsed by System76. The application may be contributed to System76 or the COSMIC project in the future if there is interest.

Installation

Flatpak (Recommended)

# Install from Flathub
flatpak install flathub io.github.cosmic_utils.camera

# Or install from a downloaded .flatpak bundle
flatpak install camera-x86_64.flatpak

From Source

Dependencies

  • Rust (stable)
  • cosmic-icons
  • GStreamer 1.20 or newer with plugins (base, good, bad, ugly)
  • libcamera 0.8.0, including development headers and pkg-config metadata
  • dav1d (>= 1.3.0), including development headers and pkg-config metadata, for AVIF decoding
  • cmake (for building embedded libjpeg-turbo)
  • libwayland
  • libxkbcommon
  • libinput
  • libudev
  • libseat

Build

# Install just command runner
cargo install just

# Build release binary
just build-release

# Install to system
sudo just install

CLI Usage

Camera supports several command-line modes for headless operation:

camera              # Launch GUI (default)
camera --help       # Show help
camera list         # List available cameras
camera photo        # Take a photo
camera video        # Record a video
camera process      # Run a computational photography pipeline
camera terminal     # Terminal mode viewer

List Cameras

camera list

Shows available cameras with their supported formats:

Available cameras:

  [0] Laptop Webcam Module (V4L2)
      Formats: 1920x1080@30fps, 1280x720@30fps, 640x480@30fps

Take a Photo

camera photo [OPTIONS]

Options:

  • -c, --camera <INDEX> - Camera index from camera list (default: 0)
  • -o, --output <PATH> - Output file path (default: ~/Pictures/Camera/IMG_YYYYMMDD_HHMMSS_mmm.jpg)

Examples:

camera photo                         # Quick photo with defaults
camera photo -o ~/snapshot.jpg       # Custom output path
camera photo -c 1                    # Use second camera

Record a Video

camera video [OPTIONS]

Options:

  • -c, --camera <INDEX> - Camera index from camera list (default: 0)
  • -d, --duration <SECONDS> - Recording duration (default: 10)
  • -o, --output <PATH> - Output file path (default: ~/Videos/Camera/video_TIMESTAMP.mp4)
  • -a, --audio - Enable audio recording

Examples:

camera video                         # 10 second video
camera video -d 30                   # 30 second video
camera video -d 60 -a                # 1 minute with audio
camera video -c 1 -d 30 -o out.mp4   # Camera 1, custom output

Press Ctrl+C to stop recording early.

Process Images

Process images through computational photography pipelines.

camera process <MODE> [OPTIONS] <INPUT>...

Night Mode

Multi-frame denoising and HDR+ pipeline for low-light photography.

camera process burst-mode [OPTIONS] <INPUT>...

Arguments:

  • <INPUT>... - One or more image files (PNG, DNG) or a directory containing images

Options:

  • -o, --output <DIR> - Output directory for processed images (default: <input>/output or ~/Pictures/Camera)

Examples:

camera process burst-mode /path/to/burst/               # Process all images in directory
camera process burst-mode img1.png img2.png img3.png    # Process specific files
camera process burst-mode /path/to/burst/ -o /output/   # Custom output directory

The pipeline automatically:

  • Selects the sharpest frame as reference
  • Aligns all frames to the reference using GPU-accelerated pyramid alignment
  • Merges frames using FFT-based frequency domain denoising
  • Applies tone mapping with shadow recovery
  • Outputs as JPEG

Terminal Mode (For the Brave)

Ever wanted to see your face rendered in glorious Unicode? Wonder what you'd look like as a half-block character? Well, wonder no more!

camera terminal

Controls:

  • s - Switch camera (cycle through available cameras)
  • q or Ctrl+C - Return to the real world

Why does this exist?

  • SSH into your server and check if you left the oven on (assuming your oven has a camera)
  • Finally achieve your dream of becoming ASCII art
  • Prove to your coworkers that you can attend video calls from a TTY
  • Because we could

Note: Your terminal needs true color support (most modern terminals have this). If you see a sad mosaic of wrong colors, try a different terminal emulator. Also, this won't make you more photogenic - trust us, we tried.

Development

# Run with debug logging
just run

# Run with verbose debug logging
just run-debug

# Format code
just fmt

# Run all checks (format, clippy, cargo check, tests)
just check

# Run clippy lints
just clippy

# Run tests only
just test

Dependency update policy

Cargo and GitHub Actions updates are checked daily at 06:00 UTC. libcosmic and its Iced crates stay outside the grouped registry minor/patch updates; major upgrades remain separate PRs. Cargo uses the auto strategy: compatible releases update the lockfile; manifest requirements change when needed to allow a new release. The compiler pin in rust-toolchain.toml is shared by developers, CI and musl images; it is not a declaration of the minimum supported Rust version. Toolchain updates run Mondays at 06:15 UTC. Python build-tool updates run Mondays at 06:30 UTC through requirements-build.txt, consumed by CI and the local uv/venv paths. After lockfile changes, run just flatpak-cargo-sources; its pinned generator is checksum-verified, replacing stale cached helpers before execution.

The Flatpak runtime/SDK and llvm22 extension remain on 26.08. COSMIC BaseApp stable currently declares runtime 25.08, but only supplies icon data, a cleanup script and a static musl just binary, not runtime-linked libraries; retaining it does not mix native SDK libraries into the 26.08 build. Ubuntu CI and Flatpak retain source-pinned libcamera 0.7.2; Flatpak also retains its libyuv subproject and libpisp 1.3.0. Moving those source builds to libcamera 0.8/libpisp 1.7 needs separate native SDK and physical-device validation rather than silently changing camera pipeline/IPA behavior. Alpine edge musl images continue using distro SDK packages, which can advance independently; compilation is not physical camera validation. Flatpak's source-built Python tools are separate from the host generator environment; their offline archives and checksums remain intact. In particular, Jinja 3.1.6 requires flit_core<4, so its 3.12.0 backend is retained instead of the incompatible 4.x release. Preview image/package baselines are intentionally not updated, and Docker updates are not enabled in Dependabot. Cross is pinned to one revision in local instructions and CI. Architecture-specific GNU sysroots remain distinct; musl images both use Alpine edge and the canonical compiler.

Cross-Compilation

Cross-compilation for other architectures uses cross with custom Dockerfiles in docker/.

# Install cross
cargo install cross --git https://github.com/cross-rs/cross --rev a9301e91f72bba3850460512685f6b16062015ff

# Debug build
cross build --target aarch64-unknown-linux-gnu

# Release build
cross build --release --target aarch64-unknown-linux-gnu
Target Dockerfile Base
aarch64-unknown-linux-gnu docker/Dockerfile.aarch64 Ubuntu 24.04
armv7-unknown-linux-gnueabihf docker/Dockerfile.armhf Ubuntu 24.04
riscv64gc-unknown-linux-gnu docker/Dockerfile.riscv64 Ubuntu 24.04
x86_64-unknown-linux-gnu docker/Dockerfile.x86_64 Ubuntu 24.04
x86_64-unknown-linux-musl docker/Dockerfile.x86_64-musl Alpine
aarch64-unknown-linux-musl docker/Dockerfile.aarch64-musl Alpine + clang

The configuration is in Cross.toml. Docker or Podman is required. The GNU images build native libcamera 0.8.0 from its pinned upstream release for each target architecture. Alpine images require libcamera-dev>=0.8.0 in their configured repositories and fail rather than falling back to an older ABI. These packaged binaries need matching libcamera.so.0.8 and libcamera-base.so.0.8 libraries on the destination system.

Podman users: If your system uses btrfs, configure the storage driver:

mkdir -p ~/.config/containers
printf '[storage]\ndriver = "btrfs"\n' > ~/.config/containers/storage.conf
podman system reset --force

If your kernel lacks the tun module (check with modprobe tun), pass host networking:

CROSS_BUILD_OPTS="--network=host" CROSS_CONTAINER_OPTS="--network=host" cross build --target ...

Alpine APK Packages

just apk-build [arch] cross-compiles the binary and then packages it as an .apk in an Alpine container, leaving the result in apk-out/:

just apk-build aarch64

The musl build images compile the pinned libcamera 0.8.0 source rather than installing Alpine's libcamera development package. The aarch64 image installs the resulting libraries and headers into its target sysroot. APK CI and the packaging image build and install local libcamera and libcamera-dev APKs so abuild can satisfy the same versioned dependencies without waiting for Alpine to publish the release. These build-time libraries include the UVC and simple pipelines with the software ISP; they are not a full replacement for Alpine's distribution package. Camera APKs still require a matching libcamera 0.8 runtime on the target system.

On an x86_64 host the packaging half runs in an emulated aarch64 container, and that needs binfmt_misc registered with the C (credentials) flag. Distros commonly register qemu-aarch64 with F alone, which makes the kernel ignore setuid bits on emulated binaries — abuild then fails with:

abuild-apk: setuid(0) failed: Operation not permitted

Check the current flags, and add C if it is missing:

# Check — look for "flags: OCF" rather than "flags: F"
cat /proc/sys/fs/binfmt_misc/qemu-aarch64

# Override the vendor registration with C added (C implies O; keep F)
sed 's/:F$/:OCF/' /usr/lib/binfmt.d/qemu-aarch64-static.conf \
    | sudo tee /etc/binfmt.d/qemu-aarch64-static.conf
sudo systemctl restart systemd-binfmt

Note that C makes setuid bits effective for all emulated binaries, not just this build.

Distrobox (Atomic Desktops)

For development on atomic/immutable desktops (Fedora Silverblue, Kinoite, Bazzite, etc.):

The Distrobox setup targets libcamera-devel >= 0.8.0 from the configured repositories. If unavailable, use the Flatpak build or provide a matching native libcamera 0.8.0 build.

# Create the development container
distrobox assemble create

# Enter the container
distrobox enter camera-dev

# Build inside the container
just build-release

# Run the binary on the host (not inside distrobox)
# Camera access via PipeWire requires running on the host
./target/release/camera

# Remove when no longer needed
distrobox rm camera-dev

To run GUI apps from inside the container, allow local display access on your host:

xhost +si:localuser:$USER

Add this to ~/.distroboxrc to make it permanent.

Note: Camera access requires PipeWire, which doesn't work reliably from inside containers. Build in distrobox, run on host for full functionality.

Flatpak Development

# Full install (uninstalls old, installs deps if needed, builds and installs)
just flatpak-install

# Run the installed Flatpak
just flatpak-run

# Uninstall all Flatpak components
just flatpak-uninstall

# Individual steps (if needed)
just flatpak-deps   # Install Flatpak SDK/runtime
just flatpak-build  # Build and install Flatpak
just flatpak-clean  # Remove build artifacts

Acknowledgments

The exposure controls implementation was inspired by cameractrls, a camera controls GUI for Linux.

Night Mode Feature

The night mode photo feature implements a simplified version of the HDR+ algorithm, with implementation guidance from:

  • hdr-plus-swift by Martin Marek (GitHub) - GPL-3.0

    • Hierarchical pyramid alignment with L1/L2 hybrid cost functions
    • FFT-based frequency domain merging
    • Spatial domain merge algorithm
    • Noise estimation techniques
  • Google HDR+ Paper - "Burst photography for high dynamic range and low-light imaging on mobile cameras" (Hasinoff et al., SIGGRAPH 2016)

  • Night Sight Paper - "Handheld Mobile Photography in Very Low Light" (Liba et al., SIGGRAPH Asia 2019)

Frosted Glass Overlays

The blur behind the app's overlay chrome reuses shader work from:

  • cosmic-comp by System76 (GitHub) - GPL-3.0-only
    • Dual-Kawase downsample/upsample blur kernels, transcribed to WGSL
    • The BLUR_PARAMS radius/iteration/offset table
    • The film-grain hash, which cosmic-comp in turn took from niri

License

Licensed under the GNU Public License 3.0.

Contribution

Any contribution intentionally submitted for inclusion in the work by you shall be licensed under the GNU Public License 3.0 (GPL-3.0). Each source file should have a SPDX copyright notice at the top of the file:

// SPDX-License-Identifier: GPL-3.0-only

Reporting Bugs

The easiest way to report a bug is to use the "Report a Bug" button in the app settings. This generates a detailed system report that helps with debugging.

  1. Open Camera → Settings → "Report a Bug"
  2. A bug report file will be saved to ~/Pictures/Camera/
  3. Your browser will open the bug report form
  4. Attach the generated report file and describe the issue

You can also report bugs manually if you prefer.

Feature Requests

Have an idea for a new feature? Submit a feature request!

About

Camera application for the COSMIC™ desktop environment

Resources

Stars

59 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages