or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced.mdcapture.mdconfiguration.mdcontrols.mdcore-operations.mdindex.mdpreview.mdrecording.md

preview.mddocs/

0

# Preview and Display

1

2

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.

3

4

## Capabilities

5

6

### Preview Control

7

8

Start, stop, and manage camera preview display.

9

10

```python { .api }

11

def start_preview(

12

self,

13

preview: Preview = None,

14

**kwargs

15

):

16

"""

17

Start camera preview display.

18

19

Parameters:

20

- preview: Preview type ("null", "drm", "qt", "qtgl") or Preview object

21

- **kwargs: Preview-specific parameters

22

23

Common kwargs:

24

- width: int, preview window width

25

- height: int, preview window height

26

- x: int, window x position

27

- y: int, window y position

28

- fullscreen: bool, fullscreen display

29

- title: str, window title

30

31

Raises:

32

- RuntimeError: If preview system fails to initialize

33

"""

34

35

def stop_preview(self):

36

"""

37

Stop camera preview display.

38

39

Closes preview window and releases display resources.

40

"""

41

42

def attach_preview(self, preview):

43

"""

44

Attach custom preview object.

45

46

Parameters:

47

- preview: Preview instance (NullPreview, DrmPreview, etc.)

48

"""

49

50

def detach_preview(self):

51

"""

52

Detach current preview object.

53

54

Preview remains running but is no longer managed by camera.

55

"""

56

57

def set_overlay(self, overlay):

58

"""

59

Set preview overlay content.

60

61

Parameters:

62

- overlay: PIL Image or numpy array for overlay graphics

63

"""

64

```

65

66

### Preview Types

67

68

Enumeration of available preview display methods.

69

70

```python { .api }

71

class Preview(Enum):

72

"""Preview display types."""

73

74

NULL = "null" # No display (headless)

75

DRM = "drm" # Direct DRM/KMS rendering

76

QT = "qt" # Qt widget display

77

QTGL = "qtgl" # Qt OpenGL display

78

```

79

80

### Preview Classes

81

82

Base preview interface and concrete implementations.

83

84

```python { .api }

85

class PreviewBase:

86

"""Base class for preview implementations."""

87

88

def __init__(self, **kwargs):

89

"""

90

Initialize preview with parameters.

91

92

Common parameters:

93

- width: int, display width

94

- height: int, display height

95

- x: int, window x position

96

- y: int, window y position

97

"""

98

99

def start(self, picam2: Picamera2):

100

"""

101

Start preview with camera instance.

102

103

Parameters:

104

- picam2: Picamera2 instance providing frames

105

"""

106

107

def stop(self):

108

"""Stop preview and clean up resources."""

109

110

def set_overlay(self, overlay):

111

"""

112

Set overlay graphics.

113

114

Parameters:

115

- overlay: PIL Image or numpy array

116

"""

117

118

def render_request(self, completed_request: CompletedRequest):

119

"""

120

Render frame from completed request.

121

122

Parameters:

123

- completed_request: CompletedRequest with frame data

124

"""

125

126

class NullPreview(PreviewBase):

127

"""

128

Null preview for headless operation.

129

130

Provides preview interface without actual display.

131

Useful for server applications and automated capture.

132

"""

133

134

class DrmPreview(PreviewBase):

135

"""

136

Direct rendering via DRM/KMS.

137

138

High-performance preview using direct hardware access.

139

Requires DRM/KMS support and appropriate permissions.

140

141

Parameters:

142

- x: int, display x offset

143

- y: int, display y offset

144

- width: int, display width (0 = full screen width)

145

- height: int, display height (0 = full screen height)

146

- plane_alpha: float, alpha blending (0.0-1.0)

147

"""

148

149

class QtPreview(PreviewBase):

150

"""

151

Qt widget-based preview display.

152

153

Cross-platform preview using Qt framework.

154

Provides window management and user interaction.

155

156

Parameters:

157

- parent: QWidget, parent widget

158

- width: int, window width

159

- height: int, window height

160

- keep_ar: bool, maintain aspect ratio

161

- title: str, window title

162

"""

163

164

class QtGlPreview(PreviewBase):

165

"""

166

Qt OpenGL-based preview display.

167

168

Hardware-accelerated preview using OpenGL rendering.

169

Provides better performance than QtPreview for high-resolution streams.

170

171

Parameters: Same as QtPreview plus:

172

- shader: str, custom fragment shader

173

- vertex_shader: str, custom vertex shader

174

"""

175

```

176

177

## Usage Examples

178

179

### Basic Preview

180

181

```python

182

from picamera2 import Picamera2, Preview

183

184

picam2 = Picamera2()

185

preview_config = picam2.create_preview_configuration()

186

picam2.configure(preview_config)

187

188

# Start with automatic preview detection

189

picam2.start(show_preview=True)

190

191

# Or explicitly start preview

192

picam2.start()

193

picam2.start_preview()

194

195

# Keep preview running

196

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

197

198

picam2.stop_preview()

199

picam2.close()

200

```

201

202

### Specific Preview Types

203

204

```python

205

from picamera2 import Picamera2, Preview

206

207

picam2 = Picamera2()

208

picam2.configure(picam2.create_preview_configuration())

209

picam2.start()

210

211

# Qt widget preview with custom window

212

picam2.start_preview(Preview.QT, width=800, height=600, title="Camera Feed")

213

214

time.sleep(5)

215

216

# Switch to OpenGL preview for better performance

217

picam2.stop_preview()

218

picam2.start_preview(Preview.QTGL, width=1024, height=768)

219

220

time.sleep(5)

221

picam2.stop_preview()

222

picam2.close()

223

```

224

225

### DRM Preview (Raspberry Pi)

226

227

```python

228

from picamera2 import Picamera2, Preview

229

230

picam2 = Picamera2()

231

picam2.configure(picam2.create_preview_configuration())

232

picam2.start()

233

234

# Full-screen DRM preview (requires root or appropriate permissions)

235

picam2.start_preview(Preview.DRM,

236

x=0, y=0,

237

width=0, height=0, # 0 = full screen

238

plane_alpha=1.0)

239

240

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

241

picam2.stop_preview()

242

picam2.close()

243

```

244

245

### Custom Preview Object

246

247

```python

248

from picamera2 import Picamera2

249

from picamera2.previews import QtPreview

250

251

picam2 = Picamera2()

252

picam2.configure(picam2.create_preview_configuration())

253

254

# Create custom preview with specific settings

255

preview = QtPreview(width=640, height=480, keep_ar=True, title="My Camera")

256

257

# Attach and start

258

picam2.attach_preview(preview)

259

picam2.start()

260

261

# Preview is now active

262

time.sleep(10)

263

264

# Can detach for independent control

265

picam2.detach_preview()

266

# Preview continues running independently

267

268

# Stop preview manually

269

preview.stop()

270

picam2.close()

271

```

272

273

### Preview with Overlay

274

275

```python

276

from picamera2 import Picamera2, Preview

277

from PIL import Image, ImageDraw, ImageFont

278

import numpy as np

279

280

picam2 = Picamera2()

281

picam2.configure(picam2.create_preview_configuration())

282

picam2.start()

283

picam2.start_preview(Preview.QT)

284

285

# Create overlay graphics

286

overlay = Image.new("RGBA", (640, 480), (0, 0, 0, 0)) # Transparent

287

draw = ImageDraw.Draw(overlay)

288

289

# Draw overlay elements

290

draw.rectangle([10, 10, 200, 50], fill=(255, 0, 0, 128)) # Semi-transparent red

291

draw.text((20, 20), "RECORDING", fill=(255, 255, 255, 255))

292

293

# Apply overlay to preview

294

picam2.set_overlay(overlay)

295

296

time.sleep(10)

297

298

# Update overlay

299

draw.rectangle([10, 60, 200, 100], fill=(0, 255, 0, 128)) # Green bar

300

draw.text((20, 70), "LIVE", fill=(255, 255, 255, 255))

301

picam2.set_overlay(overlay)

302

303

time.sleep(5)

304

305

# Remove overlay

306

picam2.set_overlay(None)

307

308

picam2.stop_preview()

309

picam2.close()

310

```

311

312

### Dynamic Overlay Updates

313

314

```python

315

from picamera2 import Picamera2, Preview

316

from PIL import Image, ImageDraw

317

import threading

318

import time

319

import datetime

320

321

picam2 = Picamera2()

322

picam2.configure(picam2.create_preview_configuration())

323

picam2.start()

324

picam2.start_preview(Preview.QT)

325

326

def update_overlay():

327

"""Update overlay with current timestamp."""

328

while running:

329

# Create overlay with timestamp

330

overlay = Image.new("RGBA", (640, 480), (0, 0, 0, 0))

331

draw = ImageDraw.Draw(overlay)

332

333

timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

334

draw.rectangle([10, 10, 300, 40], fill=(0, 0, 0, 128))

335

draw.text((15, 18), timestamp, fill=(255, 255, 255, 255))

336

337

picam2.set_overlay(overlay)

338

time.sleep(1)

339

340

# Start overlay update thread

341

running = True

342

overlay_thread = threading.Thread(target=update_overlay)

343

overlay_thread.start()

344

345

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

346

347

# Stop overlay updates

348

running = False

349

overlay_thread.join()

350

351

picam2.stop_preview()

352

picam2.close()

353

```

354

355

### Headless Operation

356

357

```python

358

from picamera2 import Picamera2, Preview

359

360

# For server/headless applications

361

picam2 = Picamera2()

362

picam2.configure(picam2.create_preview_configuration())

363

picam2.start()

364

365

# Use null preview (no display)

366

picam2.start_preview(Preview.NULL)

367

368

# Camera runs without display - good for capture-only applications

369

for i in range(10):

370

picam2.capture_file(f"headless_{i:03d}.jpg")

371

time.sleep(1)

372

373

picam2.stop_preview()

374

picam2.close()

375

```

376

377

### Preview Stream Selection

378

379

```python

380

from picamera2 import Picamera2, Preview

381

382

picam2 = Picamera2()

383

384

# Configure with multiple streams

385

config = picam2.create_video_configuration(

386

main={"size": (1920, 1080), "format": "YUV420"},

387

lores={"size": (640, 480), "format": "YUV420"}

388

)

389

390

# Specify which stream to display

391

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

392

393

picam2.configure(config)

394

picam2.start()

395

picam2.start_preview(Preview.QT)

396

397

# Preview shows low-res stream while main stream can be used for recording

398

# This reduces preview overhead while maintaining recording quality

399

400

time.sleep(10)

401

picam2.stop_preview()

402

picam2.close()

403

```

404

405

### Platform-Specific Preview

406

407

```python

408

from picamera2 import Picamera2, Preview

409

from picamera2.platform import Platform, get_platform

410

411

picam2 = Picamera2()

412

picam2.configure(picam2.create_preview_configuration())

413

picam2.start()

414

415

# Choose preview based on platform capabilities

416

platform = get_platform()

417

418

if platform == Platform.VC4:

419

# Raspberry Pi 4 and earlier - use DRM for best performance

420

picam2.start_preview(Preview.DRM)

421

elif platform == Platform.PISP:

422

# Raspberry Pi 5 - can use Qt or DRM

423

picam2.start_preview(Preview.QTGL) # Hardware accelerated

424

else:

425

# Generic platform

426

picam2.start_preview(Preview.QT)

427

428

time.sleep(10)

429

picam2.stop_preview()

430

picam2.close()

431

```