Capturing Photos with Capacitor 5’s Camera Plugin: Practical Guide, Limits and Common Pitfalls
Learn how to capture photos in a Capacitor 5 app using the Camera plugin. Install the plugin, configure native permissions, and call <code>Camera.getPhoto()</code> with <code>resultType: "Uri"</code> for production. The guide covers limits, common pitfalls, and a verification checklist.
11 Oct 2025, 15:43 UTC

Quick Takeaway
To reliably take a photo in a Capacitor 5 app, install @capacitor/camera, add the plugin to the native projects, and call Camera.getPhoto() with resultType: "Uri" for production images. On mobile, request CAMERA and STORAGE permissions; on the web, serve over HTTPS or localhost and handle the browser’s getUserMedia prompt.
Step‑by‑Step: From npm to a Working Photo
- Install the plugin
npm i @capacitor/camera # or using yarn # yarn add @capacitor/camera - Sync native projects
npx cap syncCapSync writes the plugin configuration into
AndroidManifest.xmlandInfo.plistautomatically. - Add usage descriptions (iOS only)
// ios/Runner/Info.plist NSCameraUsageDescription We need your camera to take photos. NSPhotoLibraryAddUsageDescription We will save photos to your library. - Request runtime permissions (Android only)
import { Camera } from "@capacitor/camera"; async function requestCameraPermission() { const status = await Camera.requestPermissions(); if (!status.camera || !status.ios) { throw new Error("Camera permission denied"); } } - Capture a photo
import { Camera, CameraResultType, CameraSource, CameraMediaType } from "@capacitor/camera"; async function takePhoto() { const photo = await Camera.getPhoto({ quality: 85, // 0–100, defaults to 100 allowEditing: false, // true to enable built‑in editor (iOS only) resultType: CameraResultType.Uri, // "DataUrl" or "Uri" source: CameraSource.Camera, // CameraSource.Prompt, .PhotoLibrary, .Camera mediaType: CameraMediaType.Pictures }); // photo.webPath is a local file URL on mobile, null on web console.log("Photo URI:", photo.webPath); // On mobile, the image is already in the gallery } - Verify on device
- Deploy:
npx cap open androidornpx cap open ios, then run the app. - Tap the button that calls
takePhoto(). - Check the device gallery; the new image should appear.
- In the app console, confirm
photo.webPathcontains a valid file URI.
- Deploy:
Understanding the Options
| Option | Type | Default | Notes |
|---|---|---|---|
| quality | number | 100 | 0–100; lower values reduce file size. |
| allowEditing | boolean | false | iOS only; opens the built‑in edit UI. |
| resultType | CameraResultType | Uri | "DataUrl" returns a Base64 string; "Uri" returns a file path. |
| source | CameraSource | Camera | Choose between Camera, PhotoLibrary, or Prompt. |
| mediaType | CameraMediaType | Pictures | Can be MediaType.Images, MediaType.Videos, or MediaType.All. |
Limits and Common Pitfalls
- Memory blow‑out with DataUrl – a 12‑MP image encoded as Base64 can exceed 30 MB. On mobile this can crash the app or cause the OS to kill it. Prefer
Urifor production. - Missing native integration – if you forget
npx cap syncafter installing the plugin, the native projects won’t contain the camera entry. Calls will silently fail on both Android and iOS. - Permission denial – on Android, the app must request
CAMERAandWRITE_EXTERNAL_STORAGEat runtime. If the user denies,Camera.getPhoto()resolves with an error but the stack trace is often swallowed by Capacitor’s wrapper. - Web context restrictions – the web implementation uses
navigator.mediaDevices.getUserMedia. It only works in a secure context (HTTPS or localhost). Running the dev server onhttp://localhostwill block the call and the plugin will returnundefined. - ResultType mismatch on web –
CameraResultType.Uriis not supported on the web; it returnsundefined. UseDataUrlon the web and handle the string appropriately. - Gallery storage on Android – by default the photo is written to the app’s cache directory. To persist it in the public gallery you must set
saveToGallery: true(available in newer Capacitor releases). Without this, the image disappears on app restart.
Common Mistakes & How to Avoid Them
- Skipping
cap syncafter adding the plugin – always run it before building. - Using
DataUrlfor high‑resolution images – switch toUrior reducequality. - Deploying to a device without granting permissions – test the permission dialog early in the app lifecycle.
- Serving the web app over plain HTTP – use
npx http-server -Sor a local HTTPS proxy. - Ignoring the
allowEditinglimitation on Android – it’s an iOS‑only feature.
Verification Checklist
- Confirm
Camera.getPhoto()returns a non‑nullwebPathon the device. - Open the device gallery and verify the image appears.
- On the web, ensure the browser prompts for camera access and the returned string starts with
data:image/. - Check console for permission errors or
Camera.getPhotorejection messages. - Run the app in release mode to confirm no memory warnings appear when capturing photos.
Conclusion
With the steps above, you can reliably capture photos across iOS, Android, and the web using Capacitor 5’s Camera plugin. Remember to prefer Uri for production, handle permissions explicitly, and serve the web app over HTTPS to avoid silent failures.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.