CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-picamera2

The libcamera-based Python interface to Raspberry Pi cameras, based on the original Picamera library

Pending
Overview
Eval results
Files

preview.mddocs/

Preview and Display

Preview system supporting multiple display methods including Qt widgets, DRM/KMS direct rendering, and headless operation. The preview system provides real-time camera feed display with overlay support and platform-specific optimizations.

Capabilities

Preview Control

Start, stop, and manage camera preview display.

def start_preview(
    self,
    preview: Preview = None,
    **kwargs
):
    """
    Start camera preview display.
    
    Parameters:
    - preview: Preview type ("null", "drm", "qt", "qtgl") or Preview object
    - **kwargs: Preview-specific parameters
    
    Common kwargs:
    - width: int, preview window width
    - height: int, preview window height
    - x: int, window x position
    - y: int, window y position
    - fullscreen: bool, fullscreen display
    - title: str, window title
    
    Raises:
    - RuntimeError: If preview system fails to initialize
    """

def stop_preview(self):
    """
    Stop camera preview display.
    
    Closes preview window and releases display resources.
    """

def attach_preview(self, preview):
    """
    Attach custom preview object.
    
    Parameters:
    - preview: Preview instance (NullPreview, DrmPreview, etc.)
    """

def detach_preview(self):
    """
    Detach current preview object.
    
    Preview remains running but is no longer managed by camera.
    """

def set_overlay(self, overlay):
    """
    Set preview overlay content.
    
    Parameters:
    - overlay: PIL Image or numpy array for overlay graphics
    """

Preview Types

Enumeration of available preview display methods.

class Preview(Enum):
    """Preview display types."""
    
    NULL = "null"    # No display (headless)
    DRM = "drm"      # Direct DRM/KMS rendering
    QT = "qt"        # Qt widget display
    QTGL = "qtgl"    # Qt OpenGL display

Preview Classes

Base preview interface and concrete implementations.

class PreviewBase:
    """Base class for preview implementations."""
    
    def __init__(self, **kwargs):
        """
        Initialize preview with parameters.
        
        Common parameters:
        - width: int, display width
        - height: int, display height
        - x: int, window x position  
        - y: int, window y position
        """
    
    def start(self, picam2: Picamera2):
        """
        Start preview with camera instance.
        
        Parameters:
        - picam2: Picamera2 instance providing frames
        """
    
    def stop(self):
        """Stop preview and clean up resources."""
    
    def set_overlay(self, overlay):
        """
        Set overlay graphics.
        
        Parameters:
        - overlay: PIL Image or numpy array
        """
    
    def render_request(self, completed_request: CompletedRequest):
        """
        Render frame from completed request.
        
        Parameters:
        - completed_request: CompletedRequest with frame data
        """

class NullPreview(PreviewBase):
    """
    Null preview for headless operation.
    
    Provides preview interface without actual display.
    Useful for server applications and automated capture.
    """

class DrmPreview(PreviewBase):
    """
    Direct rendering via DRM/KMS.
    
    High-performance preview using direct hardware access.
    Requires DRM/KMS support and appropriate permissions.
    
    Parameters:
    - x: int, display x offset
    - y: int, display y offset
    - width: int, display width (0 = full screen width)
    - height: int, display height (0 = full screen height) 
    - plane_alpha: float, alpha blending (0.0-1.0)
    """

class QtPreview(PreviewBase):
    """
    Qt widget-based preview display.
    
    Cross-platform preview using Qt framework.
    Provides window management and user interaction.
    
    Parameters:
    - parent: QWidget, parent widget
    - width: int, window width
    - height: int, window height
    - keep_ar: bool, maintain aspect ratio
    - title: str, window title
    """

class QtGlPreview(PreviewBase):
    """
    Qt OpenGL-based preview display.
    
    Hardware-accelerated preview using OpenGL rendering.
    Provides better performance than QtPreview for high-resolution streams.
    
    Parameters: Same as QtPreview plus:
    - shader: str, custom fragment shader
    - vertex_shader: str, custom vertex shader
    """

Usage Examples

Basic Preview

from picamera2 import Picamera2, Preview

picam2 = Picamera2()
preview_config = picam2.create_preview_configuration()
picam2.configure(preview_config)

# Start with automatic preview detection
picam2.start(show_preview=True)

# Or explicitly start preview
picam2.start()
picam2.start_preview()

# Keep preview running
input("Press Enter to stop preview...")

picam2.stop_preview()
picam2.close()

Specific Preview Types

from picamera2 import Picamera2, Preview

picam2 = Picamera2()
picam2.configure(picam2.create_preview_configuration())
picam2.start()

# Qt widget preview with custom window
picam2.start_preview(Preview.QT, width=800, height=600, title="Camera Feed")

time.sleep(5)

# Switch to OpenGL preview for better performance
picam2.stop_preview()
picam2.start_preview(Preview.QTGL, width=1024, height=768)

time.sleep(5)
picam2.stop_preview()
picam2.close()

DRM Preview (Raspberry Pi)

from picamera2 import Picamera2, Preview

picam2 = Picamera2()
picam2.configure(picam2.create_preview_configuration())
picam2.start()

# Full-screen DRM preview (requires root or appropriate permissions)
picam2.start_preview(Preview.DRM, 
                    x=0, y=0, 
                    width=0, height=0,  # 0 = full screen
                    plane_alpha=1.0)

input("Press Enter to stop full-screen preview...")
picam2.stop_preview()
picam2.close()

Custom Preview Object

from picamera2 import Picamera2
from picamera2.previews import QtPreview

picam2 = Picamera2()
picam2.configure(picam2.create_preview_configuration())

# Create custom preview with specific settings
preview = QtPreview(width=640, height=480, keep_ar=True, title="My Camera")

# Attach and start
picam2.attach_preview(preview)
picam2.start()

# Preview is now active
time.sleep(10)

# Can detach for independent control
picam2.detach_preview()
# Preview continues running independently

# Stop preview manually
preview.stop()
picam2.close()

Preview with Overlay

from picamera2 import Picamera2, Preview
from PIL import Image, ImageDraw, ImageFont
import numpy as np

picam2 = Picamera2()
picam2.configure(picam2.create_preview_configuration())
picam2.start()
picam2.start_preview(Preview.QT)

# Create overlay graphics
overlay = Image.new("RGBA", (640, 480), (0, 0, 0, 0))  # Transparent
draw = ImageDraw.Draw(overlay)

# Draw overlay elements
draw.rectangle([10, 10, 200, 50], fill=(255, 0, 0, 128))  # Semi-transparent red
draw.text((20, 20), "RECORDING", fill=(255, 255, 255, 255))

# Apply overlay to preview
picam2.set_overlay(overlay)

time.sleep(10)

# Update overlay
draw.rectangle([10, 60, 200, 100], fill=(0, 255, 0, 128))  # Green bar
draw.text((20, 70), "LIVE", fill=(255, 255, 255, 255))
picam2.set_overlay(overlay)

time.sleep(5)

# Remove overlay
picam2.set_overlay(None)

picam2.stop_preview()
picam2.close()

Dynamic Overlay Updates

from picamera2 import Picamera2, Preview
from PIL import Image, ImageDraw
import threading
import time
import datetime

picam2 = Picamera2()
picam2.configure(picam2.create_preview_configuration())
picam2.start()
picam2.start_preview(Preview.QT)

def update_overlay():
    """Update overlay with current timestamp."""
    while running:
        # Create overlay with timestamp
        overlay = Image.new("RGBA", (640, 480), (0, 0, 0, 0))
        draw = ImageDraw.Draw(overlay)
        
        timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        draw.rectangle([10, 10, 300, 40], fill=(0, 0, 0, 128))
        draw.text((15, 18), timestamp, fill=(255, 255, 255, 255))
        
        picam2.set_overlay(overlay)
        time.sleep(1)

# Start overlay update thread
running = True
overlay_thread = threading.Thread(target=update_overlay)
overlay_thread.start()

input("Press Enter to stop...")

# Stop overlay updates
running = False
overlay_thread.join()

picam2.stop_preview()
picam2.close()

Headless Operation

from picamera2 import Picamera2, Preview

# For server/headless applications
picam2 = Picamera2()
picam2.configure(picam2.create_preview_configuration())
picam2.start()

# Use null preview (no display)
picam2.start_preview(Preview.NULL)

# Camera runs without display - good for capture-only applications
for i in range(10):
    picam2.capture_file(f"headless_{i:03d}.jpg")
    time.sleep(1)

picam2.stop_preview()
picam2.close()

Preview Stream Selection

from picamera2 import Picamera2, Preview

picam2 = Picamera2()

# Configure with multiple streams
config = picam2.create_video_configuration(
    main={"size": (1920, 1080), "format": "YUV420"},
    lores={"size": (640, 480), "format": "YUV420"}
)

# Specify which stream to display
config.display = "lores"  # Use low-res stream for preview

picam2.configure(config)
picam2.start()
picam2.start_preview(Preview.QT)

# Preview shows low-res stream while main stream can be used for recording
# This reduces preview overhead while maintaining recording quality

time.sleep(10)
picam2.stop_preview()
picam2.close()

Platform-Specific Preview

from picamera2 import Picamera2, Preview
from picamera2.platform import Platform, get_platform

picam2 = Picamera2()
picam2.configure(picam2.create_preview_configuration())
picam2.start()

# Choose preview based on platform capabilities
platform = get_platform()

if platform == Platform.VC4:
    # Raspberry Pi 4 and earlier - use DRM for best performance
    picam2.start_preview(Preview.DRM)
elif platform == Platform.PISP:
    # Raspberry Pi 5 - can use Qt or DRM
    picam2.start_preview(Preview.QTGL)  # Hardware accelerated
else:
    # Generic platform
    picam2.start_preview(Preview.QT)

time.sleep(10)
picam2.stop_preview()
picam2.close()

Install with Tessl CLI

npx tessl i tessl/pypi-picamera2

docs

advanced.md

capture.md

configuration.md

controls.md

core-operations.md

index.md

preview.md

recording.md

tile.json