To take a photo with the Mac camera from the command line, install imagesnap and run it with a filename:
brew install imagesnap
imagesnap photo.jpgThat captures one frame from the default camera and writes it to photo.jpg in the current directory. If you leave the filename off, imagesnap writes to snapshot.jpg. That is the whole job for the simple case. The rest of this page is the detail that actually matters when it does not work: choosing the right camera, the warm-up delay that keeps the frame from coming out black, and the one thing that trips up everyone scripting this in 2026, the macOS Camera-permission gap that makes a CLI capture fail silently.
imagesnap is a small open-source tool by Robert Harder. It is the cleanest way to grab a still from the built-in FaceTime camera or any attached USB webcam without opening Photo Booth.
List the cameras
A Mac often has more than one capture device: the built-in camera, an attached webcam, a phone acting as a Continuity Camera. List them before you pick:
imagesnap -lThat prints every video device by name. The first one in the list is the system default that a bare imagesnap photo.jpg uses.
Pick a specific camera
Pass the device name from -l with -d:
imagesnap -d "FaceTime HD Camera" photo.jpgThe name has to match what -l reported. Quote it, because the names contain spaces. If you only ever use one camera you can skip this and let imagesnap take the default.
Add a warm-up delay or you get a dark frame
This is the single most common complaint, and the fix is one flag. A camera sensor needs a moment to adjust exposure after it powers on. Capture instantly and you get a dark, sometimes fully black, frame. Give it time to settle with -w:
imagesnap -w 2 photo.jpg-w 2 warms the camera up for two seconds before the shot. imagesnap already applies a default warm-up of about three seconds, so a bare imagesnap photo.jpg is usually fine, but if you have lowered it or your camera is slow to expose, bump -w until the frame is properly lit. The value is in seconds and accepts decimals (-w 1.5).
The Camera-permission gap (the real gotcha)
Here is the thing that breaks scripted captures and is absent from most older guides. Since macOS Mojave (10.14), the camera is gated behind TCC, Apple's privacy permission system. A command-line tool does not get its own permission entry. It inherits the permission of the app that launched it: the Terminal, iTerm, VS Code's integrated terminal, or whatever is running your script.
The first interactive run usually triggers a permission prompt, and clicking Allow records the grant against your terminal app. But run imagesnap from a non-interactive context (a cron job, a launchd agent, an SSH session, a CI step) before that grant exists, and there is no prompt to click. The capture fails, often quietly, and you are left staring at a missing or empty file with no obvious error.
The fix is to grant the controlling app Camera access explicitly:
- Open System Settings, then Privacy and Security, then Camera.
- Find your terminal app (Terminal, iTerm, or whichever runs your script) in the list and turn it on. If it is not listed, run
imagesnaponce interactively to make macOS register it, then toggle it. - Quit and reopen that terminal app so the new permission takes effect.
If you script this, the rule is simple: the app that owns the process needs the grant, not imagesnap itself. Move the script to a different terminal and you need to authorize that one too.
To sanity-check whether something already holds the camera open, the green dot next to the menu bar clock lights up whenever any process is using the camera. If imagesnap returns a frame but the dot never appeared, the capture did not actually reach the sensor, which usually points back at the permission gap.
Shoot a timelapse
imagesnap can also fire on an interval instead of taking a single shot. Pass -t with the number of seconds between frames:
imagesnap -t 5 frame.jpgThat captures a frame every five seconds, writing numbered files (frame00001.jpg, frame00002.jpg, and so on) until you stop it with Ctrl+C. The interval accepts decimals, so -t 0.5 gives two frames a second. To cap the run at a fixed number of shots instead of stopping by hand, add -n:
imagesnap -t 5 -n 12 frame.jpg-n 12 takes twelve frames and exits, so the command above grabs one shot every five seconds for a minute and then stops. The same Camera-permission rule below applies to a timelapse run, and a slow interval gives the sensor plenty of time to settle, so a per-frame warm-up is rarely needed here.
The ffmpeg alternative
If you already have ffmpeg installed (for transcoding or thumbnails), you can skip imagesnap entirely and capture a single frame through ffmpeg's avfoundation input:
ffmpeg -f avfoundation -i "0" -frames:v 1 out.jpg-f avfoundation selects the macOS capture backend, -i "0" is the device index (run ffmpeg -f avfoundation -list_devices true -i "" to see the numbered list), and -frames:v 1 grabs exactly one video frame. The same TCC rule applies here: the terminal running ffmpeg needs Camera permission, and avfoundation can return a dark first frame for the same warm-up reason, so add -ss 1 to seek a second in if the shot comes out underexposed.
imagesnap is the friendlier tool for a quick still. Reach for the ffmpeg form when you are already in an ffmpeg pipeline or want the frame piped straight into a larger video workflow. For the related job of pulling a still out of an existing video file rather than a live camera, see extract a thumbnail from a video with ffmpeg.
FAQ
See also
- Turn Bluetooth on and off from the macOS command line: another small Homebrew tool (blueutil) for a thing the GUI usually owns.
- Using the open command on macOS: launch apps, files, and URLs from the Terminal, including the Camera app if you want the GUI.
- Extract a thumbnail from a video with ffmpeg: the same avfoundation tool, but pulling a still frame out of a recorded file instead of a live camera.
Sources
Authoritative references this article was fact-checked against.
- imagesnap (Robert Harder, official repo)github.com
- Control access to the camera on Mac (Apple Support)support.apple.com
- ffmpeg avfoundation input device (official documentation)ffmpeg.org
- imagesnap — Homebrew Formulaeformulae.brew.sh





