CamDir

About CamDir

The Problem

When a smartphone takes a photo, it can record the compass direction the camera was pointing — a value called GPSImgDirection in the photo's EXIF metadata.

The problem is that different phone manufacturers report this value differently. Apple iPhones report the same bearing whether you hold the phone in portrait or landscape. Many Android phones shift the value by 90 degrees when you rotate to landscape, because they report the device sensor's reference frame rather than the lens direction.

There is no standard governing this, and no public database documenting which devices behave which way. Developers building location-aware photo apps have to guess — or ignore direction data entirely.

How CamDir Works

CamDir uses a simple method to detect each device's behavior: take two photos of the same subject — one in portrait, one in landscape — and compare the compass readings. The difference (the delta) reveals the device-specific offset.

You don't need to know which direction you were actually facing. The delta between portrait and landscape is what matters, and it depends only on the device.

As more people contribute, the median delta for each device converges to the true value. CamDir uses the median (not the mean) because it's robust to small aiming differences between shots.

How the Tool Works

CamDir uses exifr, an open-source JavaScript library, to read metadata from your photos. Here's what you should know:

  • exifr runs entirely in your browser. There is nothing to download or install.
  • Your photos are never uploaded or transmitted. The library reads them locally on your device.
  • Only numeric metadata (compass direction, device model, image dimensions) is sent to our server.
  • GPS coordinates are extracted to show you a preview, but are never transmitted or stored.
  • The library's source code is publicly auditable on GitHub.

API

CamDir provides a free, public API. No API key required for read access.

Get offset for a device

GET /camdir/api/v1/offset?make={make}&model={model}

Returns the aggregated offset for a specific device.

{
  "make_normal": "google",
  "model_normal": "pixel 8 pro",
  "median_delta": -90.0,
  "sample_count": 47,
  "confidence": "high",
  "rotation_type": "ccw"
}

List all devices

GET /camdir/api/v1/devices

Optional filters: ?confidence=high, ?make=samsung, ?min_samples=5

Database statistics

GET /camdir/api/v1/stats

Rate limits

API reads: 1,000 requests per hour per IP. Submissions: 10 per hour per IP.

Privacy

  • Photos never leave your device.
  • No account is required to contribute or browse.
  • GPS coordinates are extracted locally for preview only — never transmitted.
  • The only data sent to the server: device make, model, compass direction values, image dimensions, camera app name, and capture timestamps.
  • The camera app name (e.g., "Google Camera 9.2") is stored because different camera apps on the same device may produce different offset behavior. This data may be used in the future to provide per-app offset records.
  • IP addresses are hashed and stored only for rate-limiting purposes.
  • The aggregated device database is the only public-facing data. Raw submissions are internal.

Open Data

CamDir is a public service operated in the spirit of projects like OpenStreetMap. The aggregated dataset is freely available through the API. The data belongs to the community.