JPEG Screenshots
Enable periodic JPEG session capture, request on-demand screenshots through VisualTree, and choose the right .NET SDK setup API for local host player and CLI workflows.
Ansight exposes screenshots through two .NET SDK surfaces:
- session JPEG capture, a Core runtime feature that streams periodic JPEG frames while a paired host session is open
- on-demand screenshot tools, a VisualTree tool-suite feature that lets the local player or a CLI client call
ui.get_screenshot
Use session capture when you want timeline evidence for replay, QA handoff, or later AI analysis. Use the on-demand tool when an agent needs the current screen at a specific point in an investigation.
Important: Screen capture will result in an FPS drop while frames are captured, encoded, and transported. Use conservative interval, quality, and max-width settings, and disable session JPEG capture for trend-focused runs unless visual evidence is required.
Feature Suite Defaults
The all-in-one setup APIs enable the usual local-development feature suite for you.
| Setup | Session JPEG capture | On-demand screenshots | Notes |
|---|---|---|---|
WithAnsightSdk(...) from Ansight | Enabled every 2000ms, quality 60, max width 480. | Registers Ansight.Tools.VisualTree, including ui.get_screenshot. | Standard non-MAUI setup. |
UseAnsight<App>(...) from Ansight.Maui | Enabled every 2000ms, quality 60, max width 480. | Registers the non-MAUI tools plus the MAUI suite. | Recommended MAUI setup. |
Ansight.Core manual setup | Disabled until you call WithSessionJpegCapture(...). | Unavailable until you add Ansight.Tools.VisualTree and call WithVisualTreeTools(). | Best when you want explicit control. |
Remote tools are still gated by ToolGuard. The all-in-one setup grants full tool access for local development; call WithReadOnlyToolAccess(), WithReadWriteToolAccess(), or WithToolsDisabled() inside the setup callback if the workflow should be narrower.
Session JPEG Capture
Session JPEG capture is a runtime feature. It captures the current app surface on an interval, encodes it as JPEG, and sends it over the paired host connection as live session evidence.
using Ansight;
var options = Options.CreateBuilder()
.WithSessionJpegCapture(intervalMilliseconds: 2000, quality: 60, maxWidth: 720)
.Build();
Runtime.InitializeAndActivate(options);
You can also pass a complete SessionJpegCaptureOptions instance:
using Ansight;
var options = Options.CreateBuilder()
.WithSessionJpegCapture(new SessionJpegCaptureOptions
{
IntervalMilliseconds = 3000,
Quality = 60,
MaxWidth = 720,
Mode = SessionJpegCaptureMode.ScreenshotAndVisualTree,
CaptureKeyboardPresence = true
})
.Build();
Disable periodic capture when a run does not need screenshot history:
using Ansight;
var options = Options.CreateBuilder()
.WithoutSessionJpegCapture()
.Build();
For all-in-one setup, make the same call inside the setup callback:
using Ansight.Maui;
builder.UseAnsight<App>(ansight =>
{
ansight.WithoutSessionJpegCapture();
});
SessionJpegCaptureOptions properties:
| Property | Meaning | Default from WithSessionJpegCapture() | Validation |
|---|---|---|---|
IntervalMilliseconds | Capture interval while a pairing session is open. | 2000 | Values below 250ms are clamped. |
Quality | JPEG quality. | 70 | Values are clamped to 1-100. |
MaxWidth | Optional output width cap. null keeps full width. | 720 | Values above 8192 are clamped. |
CaptureGpuBackedSurfaces | Use the higher-fidelity capture path for Metal, SceneKit, and similar Apple surfaces. | true | Meaningful on supported Apple targets. |
Mode | Select screenshot-only, screenshot-aligned visual trees, or touch-triggered visual trees. | ScreenshotOnly | Enum value must be defined. |
CaptureKeyboardPresence | Record whether the on-screen keyboard was present. Contents and dimensions are never collected. | false | Boolean. |
The all-in-one feature suite uses the more conservative 2000ms, quality 60, and max width 480 defaults.
Visual-Tree Capture Modes
| Mode | Behavior |
|---|---|
ScreenshotOnly | Sends periodic JPEG frames without an SDK visual-tree snapshot. |
ScreenshotAndVisualTree | Captures registered visual-tree sources with each app-owned screenshot and correlates them through the screenshot capture timestamp. |
ScreenshotWithVisualTreeOnTouch | Keeps periodic screenshots, but captures visual trees on touch down and touch up instead of for every frame. Move and cancel events do not trigger a tree. |
Tree capture requires a provider registered with SessionVisualTreeCaptureRegistry. Touch-triggered mode also requires touch capture. The Ansight and Ansight.Maui packages register their standard providers; a core-only app must register its provider explicitly. Payloads follow the compact visual-tree v2 contract.
Keyboard-presence capture is opt-in and reports presence only. It does not collect typed text or keyboard geometry, and the metadata remains useful when the host owns simulator/emulator screenshots.
Simulator and Emulator Capture Ownership
The runtime advertises sessionJpegCaptureControlVersion: 1 in device.profile. The resident host can acknowledge the profile with sessionJpegCapture.mode: "host" and an optional source such as simctl or adb.
In host mode, the SDK suspends its periodic in-app JPEG loop for that live session so the host can capture the simulator or emulator externally. A missing response or mode: "app" keeps the configured SDK capture behavior. This negotiation is automatic and does not affect on-demand ui.get_screenshot calls.
On-Demand Screenshot Tool
On-demand screenshots are exposed by the VisualTree tool suite. This is the path used when the local player or ansight app call <session-id> ui.get_screenshot asks the running app for a screenshot at a specific moment.
When you use Ansight or Ansight.Maui, the suite is registered for you. With Ansight.Core, add the package and register it explicitly:
dotnet add package Ansight.Tools.VisualTree --prerelease
using Ansight;
using Ansight.Tools.VisualTree;
var options = Options.CreateBuilder()
.WithVisualTreeTools()
.WithReadOnlyToolAccess()
.Build();
The tool id is ui.get_screenshot.
Arguments:
format:pngorjpegquality: JPEG quality1-100maxWidth: optional width capannotateNodeIds: overlay node ids on the screenshotafterScreenUpdates: Apple platforms wait for pending screen updates before rendering; defaulttrue
Example request:
{
"toolId": "ui.get_screenshot",
"arguments": {
"format": "jpeg",
"quality": 80,
"maxWidth": 1080,
"annotateNodeIds": false,
"afterScreenUpdates": true
}
}
The response contains screenshot metadata such as format, width, height, transferId, downloadId, fileName, mimeType, and sizeBytes. Image bytes are delivered out-of-band over Ansight’s binary transfer protocol rather than inline base64.
Choosing a Capture Path
| Workflow | Recommended API |
|---|---|
| Session replay, QA handoff, or post-run AI analysis | Enable WithSessionJpegCapture(...). |
| Agent needs to inspect the current rendered UI | Register VisualTree and call ui.get_screenshot. |
| Lowest runtime overhead with occasional visual checks | Keep session capture disabled and request on-demand screenshots only. |
| Core-only app with no remote tools | Use WithSessionJpegCapture(...) without adding Ansight.Tools.VisualTree. |
| Release or distribution build | Do not ship remote tool packages; keep screenshot capture out of protected builds unless explicitly required. |
Trends and Privacy
Screenshots can contain user data, credentials, notifications, and other sensitive rendered content. Keep screenshotting scoped to local development and QA workflows.
JPEG capture adds rendering, encoding, and transport work every time a frame is captured. Prefer conservative intervals, moderate quality, and a max width cap. For a trend-focused session, disable periodic capture or rely on single on-demand screenshots.