The libcamera-based Python interface to Raspberry Pi cameras, based on the original Picamera library
—
Comprehensive capture functionality supporting various output formats, synchronous and asynchronous operations, and different data types. The capture system provides both high-level convenience methods and low-level control for advanced applications.
Direct capture to files with automatic format detection and encoding.
def capture_file(
self,
file_output: str,
name: str = "main",
format: str = None,
wait: bool = True,
signal_function: callable = None,
exif_data: dict = None
):
"""
Capture image directly to file.
Parameters:
- file_output: str, output file path
- name: str, stream name to capture ("main", "lores", "raw")
- format: str, output format (auto-detected from filename if None)
- wait: bool, wait for capture completion
- signal_function: callable, completion callback
- exif_data: dict, EXIF metadata for JPEG files
Returns:
Job object if wait=False, None if wait=True
"""Capture images as numpy arrays for image processing and analysis.
def capture_array(
self,
name: str = "main",
wait: bool = True,
signal_function: callable = None
) -> np.ndarray:
"""
Capture image as numpy array.
Parameters:
- name: str, stream name to capture
- wait: bool, wait for capture completion
- signal_function: callable, completion callback
Returns:
np.ndarray: Image data with shape appropriate for format
"""
def capture_arrays(
self,
names: list[str] = None,
wait: bool = True,
signal_function: callable = None
) -> dict[str, np.ndarray]:
"""
Capture multiple streams as numpy arrays.
Parameters:
- names: list, stream names to capture (default: all active streams)
- wait: bool, wait for capture completion
- signal_function: callable, completion callback
Returns:
dict: Stream names mapped to numpy arrays
"""Capture images as PIL Image objects for easy manipulation and saving.
def capture_image(
self,
name: str = "main",
wait: bool = True,
signal_function: callable = None
) -> PIL.Image.Image:
"""
Capture image as PIL Image object.
Parameters:
- name: str, stream name to capture
- wait: bool, wait for capture completion
- signal_function: callable, completion callback
Returns:
PIL.Image.Image: PIL Image object
"""Low-level buffer capture for direct memory access and custom processing.
def capture_buffer(
self,
name: str = "main",
wait: bool = True,
signal_function: callable = None
) -> bytes:
"""
Capture raw buffer data.
Parameters:
- name: str, stream name to capture
- wait: bool, wait for capture completion
- signal_function: callable, completion callback
Returns:
bytes: Raw buffer data
"""
def capture_buffers(
self,
names: list[str] = None,
wait: bool = True,
signal_function: callable = None
) -> dict[str, bytes]:
"""
Capture multiple streams as raw buffers.
Parameters:
- names: list, stream names to capture
- wait: bool, wait for capture completion
- signal_function: callable, completion callback
Returns:
dict: Stream names mapped to buffer data
"""Advanced capture interface providing access to complete request objects with metadata.
def capture_request(
self,
wait: bool = True,
signal_function: callable = None,
flush: bool = False
) -> CompletedRequest:
"""
Capture complete request with all streams and metadata.
Parameters:
- wait: bool, wait for capture completion
- signal_function: callable, completion callback
- flush: bool, flush pending requests before capture
Returns:
CompletedRequest: Complete request object with all stream data
"""
def capture_metadata(
self,
wait: bool = True,
signal_function: callable = None
) -> dict:
"""
Capture only metadata without image data.
Parameters:
- wait: bool, wait for capture completion
- signal_function: callable, completion callback
Returns:
dict: Camera metadata
"""High-level methods combining common capture operations.
def start_and_capture_file(
self,
name: str,
delay: float = 1,
preview_mode: bool = None,
show_preview: bool = None,
initial_delay: float = None,
exif_data: dict = None
):
"""
Start camera and capture single file with delay.
Parameters:
- name: str, output filename
- delay: float, delay before capture (seconds)
- preview_mode: bool, use preview configuration
- show_preview: bool, show preview window
- initial_delay: float, initial settling delay
- exif_data: dict, EXIF metadata
"""
def start_and_capture_files(
self,
name: str,
delay: float = 1,
preview_mode: bool = None,
initial_delay: float = None,
num_files: int = 1,
show_preview: bool = None
):
"""
Start camera and capture multiple files with delay.
Parameters:
- name: str, output filename pattern
- delay: float, delay between captures
- preview_mode: bool, use preview configuration
- initial_delay: float, initial settling delay
- num_files: int, number of files to capture
- show_preview: bool, show preview window
"""Object representing a completed camera request with access to all stream data and metadata.
class CompletedRequest:
"""Completed camera request with stream data and metadata."""
request: libcamera.Request # Underlying libcamera request
config: CameraConfiguration # Configuration snapshot
stream_map: dict # Stream mapping information
def acquire(self):
"""Acquire reference to prevent request recycling."""
def release(self):
"""Release reference, allowing request recycling."""
def make_buffer(self, name: str = "main") -> bytes:
"""
Create buffer from stream data.
Parameters:
- name: str, stream name
Returns:
bytes: Raw buffer data
"""
def make_array(self, name: str = "main") -> np.ndarray:
"""
Create numpy array from stream data.
Parameters:
- name: str, stream name
Returns:
np.ndarray: Image array with appropriate shape
"""
def make_image(
self,
name: str = "main",
width: int = None,
height: int = None
) -> PIL.Image.Image:
"""
Create PIL Image from stream data.
Parameters:
- name: str, stream name
- width: int, override width
- height: int, override height
Returns:
PIL.Image.Image: PIL Image object
"""
def save(
self,
name: str,
file_output: str,
format: str = None,
exif_data: dict = None
):
"""
Save stream data to file.
Parameters:
- name: str, stream name
- file_output: str, output file path
- format: str, output format
- exif_data: dict, EXIF metadata
"""
def save_dng(self, file_output: str, name: str = "raw"):
"""
Save raw stream as DNG file.
Parameters:
- file_output: str, output DNG file path
- name: str, raw stream name
"""
def get_metadata(self) -> dict:
"""
Get request metadata.
Returns:
dict: Camera metadata for this request
"""from picamera2 import Picamera2
picam2 = Picamera2()
picam2.configure(picam2.create_still_configuration())
picam2.start()
# Simple file capture
picam2.capture_file("image.jpg")
# Multiple format capture
picam2.capture_file("image.png", format="PNG")
picam2.capture_file("image.tiff", format="TIFF")
picam2.close()from picamera2 import Picamera2
import numpy as np
import cv2
picam2 = Picamera2()
config = picam2.create_preview_configuration(
main={"format": "RGB888", "size": (640, 480)}
)
picam2.configure(config)
picam2.start()
# Capture as numpy array
array = picam2.capture_array()
print(f"Array shape: {array.shape}, dtype: {array.dtype}")
# Process with OpenCV
gray = cv2.cvtColor(array, cv2.COLOR_RGB2GRAY)
edges = cv2.Canny(gray, 100, 200)
# Save processed result
cv2.imwrite("edges.jpg", edges)
picam2.close()from picamera2 import Picamera2
picam2 = Picamera2()
config = picam2.create_video_configuration(
main={"size": (1920, 1080), "format": "YUV420"},
lores={"size": (640, 480), "format": "YUV420"}
)
picam2.configure(config)
picam2.start()
# Capture both streams simultaneously
arrays = picam2.capture_arrays(["main", "lores"])
print(f"Main: {arrays['main'].shape}")
print(f"Lores: {arrays['lores'].shape}")
# Process each stream differently
high_res = arrays["main"]
low_res = arrays["lores"]
picam2.close()from picamera2 import Picamera2
picam2 = Picamera2()
config = picam2.create_still_configuration()
picam2.configure(config)
picam2.start()
# Capture complete request
request = picam2.capture_request()
# Access metadata
metadata = request.get_metadata()
print(f"Exposure time: {metadata.get('ExposureTime', 'Unknown')}")
print(f"Analog gain: {metadata.get('AnalogueGain', 'Unknown')}")
# Process multiple representations
array = request.make_array("main")
image = request.make_image("main")
# Save with metadata
request.save("main", "output.jpg", format="JPEG")
# Important: release request when done
request.release()
picam2.close()from picamera2 import Picamera2
import time
def capture_complete(job):
print(f"Capture completed: {job.result()}")
picam2 = Picamera2()
picam2.configure(picam2.create_preview_configuration())
picam2.start()
# Start non-blocking capture
job = picam2.capture_file("async_image.jpg", wait=False,
signal_function=capture_complete)
# Do other work while capture proceeds
print("Doing other work...")
time.sleep(0.1)
# Wait for completion if needed
if not job.finished:
job.wait()
picam2.close()from picamera2 import Picamera2
import time
picam2 = Picamera2()
picam2.configure(picam2.create_still_configuration())
picam2.start()
# Rapid burst capture
for i in range(10):
filename = f"burst_{i:03d}.jpg"
picam2.capture_file(filename)
time.sleep(0.1) # Small delay between captures
# Or use convenience method
picam2.start_and_capture_files("sequence_{:03d}.jpg",
delay=0.5, num_files=5)
picam2.close()Install with Tessl CLI
npx tessl i tessl/pypi-picamera2