ImageCapture takePhoto() Demonstrator

Take maximum-resolution photos with the ImageCapture API and inspect all metadata

ImageCapture.takePhoto() Demonstrator

Open your camera, take a full-resolution still photo using the ImageCapture.takePhoto() API, inspect every piece of metadata the browser exposes, and download the result.

API Support

navigator.mediaDevices --
ImageCapture --
enumerateDevices --
Secure context (HTTPS) --
Capturing photo -- this may take a moment on high-res sensors...

Capture Timeline

Captured photo

Photo Blob Metadata

Decoded Image Metadata

MediaTrackSettings at Capture Time

PhotoSettings at Capture Time

Privacy: Everything runs locally in your browser. No images or data leave your device.

Tip: On phones, the rear camera typically exposes much higher resolution via takePhoto() than the video preview resolution.

takePhoto() vs grabFrame() -- What is the Difference?

The ImageCapture API provides two methods for obtaining an image from a camera stream. They serve very different purposes and produce different outputs.

takePhoto() grabFrame()
What it does Triggers the camera's full still-image capture pipeline, just like pressing a hardware shutter button Grabs the current frame from the live video track
Output type Blob (typically JPEG) ImageBitmap
Resolution Full sensor resolution (e.g. 12MP, 48MP, 108MP) -- independent of the video stream constraints Matches the video track resolution (e.g. 1280x720, 1920x1080)
Speed Slower -- may involve autofocus lock, auto-exposure, sensor readout at full res Very fast -- just copies the current decoded frame
Camera flash Can trigger the flash via PhotoSettings.fillLightMode No flash support
Red-eye reduction Supported (if hardware allows) Not available
Image processing Full ISP pipeline: noise reduction, HDR, sharpening, tone mapping Uses the video encode path, which is optimized for speed over quality
Use case When you need a high-quality still photograph When you need to process video frames in real-time (barcode scanning, CV, effects)
Interrupts video? May briefly pause the video stream during capture No interruption at all
Metadata available EXIF data may be embedded in the JPEG Blob (browser/OS dependent) No embedded metadata -- just raw pixel data

When to use takePhoto()

  • Document scanning where detail matters
  • Product photography
  • Any time you want the highest resolution the sensor can deliver
  • When you need flash support
  • When the user explicitly presses a "capture" button

When to use grabFrame()

  • Real-time computer vision (face detection, barcode scanning)
  • Video effects / filters applied per-frame
  • Motion detection
  • Timelapse where speed matters more than maximum resolution
  • Any continuous frame-by-frame processing loop

Understanding the Metadata

MediaTrackSettings

These are the actual negotiated settings of the video track. They tell you what resolution the camera is streaming at, the frame rate, the facing mode, aspect ratio, and device ID. The video stream resolution is typically lower than the sensor maximum because it needs to encode frames in real time.

MediaTrackCapabilities

This object describes the full ranges the hardware supports: minimum and maximum width/height, frame rate ranges, supported facing modes, zoom levels, torch mode, and more. This is what the camera could do, not what it is currently doing.

PhotoCapabilities

Specific to still capture. Reports the range of resolutions available for takePhoto(), supported fill light modes (flash), and red-eye reduction capability. The maximum width/height here is typically much larger than the video stream dimensions because the still pipeline accesses the full sensor.

PhotoSettings

The current configuration that will be used when takePhoto() is called. Includes image width/height, fill light mode, and red-eye reduction setting. You can override these by passing a PhotoSettings object to takePhoto().

Photo Blob Metadata

After capture, the Blob itself carries the MIME type, byte size, and when decoded into an Image element, we can read the actual pixel dimensions. Comparing the Blob dimensions to the video stream dimensions shows you exactly how much more resolution takePhoto() provides.

Browser Support

The ImageCapture API is a living standard maintained by the W3C. Support varies:

BrowsertakePhoto()grabFrame()PhotoCapabilities
Chrome (Android)Yes (since v59)YesYes
Chrome (Desktop)Yes (since v59)YesYes
EdgeYes (Chromium-based)YesYes
Samsung InternetYesYesYes
OperaYesYesYes
Safari (iOS/macOS)Partial (recent versions)PartialLimited
FirefoxBehind flagBehind flagNo

If ImageCapture is not available, this tool will show you a clear error. Using Chrome on Android gives the best experience with full PhotoCapabilities reporting.

Frequently Asked Questions

What is the ImageCapture API?

The ImageCapture API is a browser standard that gives JavaScript direct control over camera hardware. It lets you take full-resolution still photos (via takePhoto()) independent of the video stream resolution, and read or set camera parameters like ISO, white balance, exposure, zoom, and focus.

What is the difference between takePhoto() and grabFrame()?

takePhoto() triggers the camera's full still-image pipeline, producing a high-resolution Blob (often JPEG) at the sensor's maximum capability. grabFrame() simply grabs the current video frame as an ImageBitmap at the video track's resolution. takePhoto() is slower but produces much higher quality images.

Which browsers support the ImageCapture API?

As of 2026, ImageCapture is supported in Chromium-based browsers (Chrome, Edge, Opera, Samsung Internet) on desktop and Android. Safari on iOS and macOS has partial support. Firefox has limited support behind flags.

Why is the photo resolution higher than the video preview?

The video stream typically runs at a lower resolution for performance (e.g. 1280x720 or 1920x1080). takePhoto() bypasses the video pipeline and captures directly from the image sensor at its full native resolution, which can be 12MP, 48MP, or even higher on modern phones.

Is my photo uploaded anywhere?

No. Everything runs locally in your browser. The camera stream, the captured photo, and all metadata inspection happen entirely on your device. Nothing is sent to any server.

Can I control flash or zoom from this tool?

This demonstrator requests takePhoto() at maximum resolution with default settings. The PhotoCapabilities dump will show you whether your camera supports flash, zoom, torch, and other features. A production app could pass custom PhotoSettings to control all of these.

Why does the captured photo look different from the preview?

The still capture pipeline applies different processing than the video path. The camera may perform additional noise reduction, HDR merging, sharpening, and tone mapping when taking a still photo. This is normal and is the same difference you see between a phone's viewfinder and the final saved photo.

Related Tools

Related Tools

View all tools

ImageCapture takePhoto() Demonstrator FAQ

What is the ImageCapture API?

The ImageCapture API is a browser standard that gives JavaScript direct control over camera hardware. It lets you take full-resolution still photos (via takePhoto()) independent of the video stream resolution, and read or set camera parameters like ISO, white balance, exposure, zoom, and focus.

What is the difference between takePhoto() and grabFrame()?

takePhoto() triggers the camera's full still-image pipeline, producing a high-resolution Blob (often JPEG) at the sensor's maximum capability. grabFrame() simply grabs the current video frame as an ImageBitmap at the video track's resolution. takePhoto() is slower but produces much higher quality images.

Which browsers support the ImageCapture API?

As of 2026, ImageCapture is supported in Chromium-based browsers (Chrome, Edge, Opera, Samsung Internet) on desktop and Android. Safari on iOS and macOS has partial support. Firefox has limited support behind flags.

Why is the photo resolution higher than the video preview?

The video stream typically runs at a lower resolution for performance (e.g. 1280x720 or 1920x1080). takePhoto() bypasses the video pipeline and captures directly from the image sensor at its full native resolution, which can be 12MP, 48MP, or even higher on modern phones.

Is my photo uploaded anywhere?

No. Everything runs locally in your browser. The camera stream, the captured photo, and all metadata inspection happen entirely on your device. Nothing is sent to any server.

Request a New Tool
Improve This Tool