mvdocs

# ImageDisplay

Avanti.Toolkit.MachineVision.Controls.ImageDisplay 是基于 Skia 的机器视觉图片显示表面。 包名为 Avanti.Toolkit.MachineVision.ImageDisplay。首版支持 Gray8 原始帧和静态栅格图片; 静态图片按亮度转换为 Gray8,暂不提供彩色或 16 位灰度显示。

# 注册与显示

在现有 UseAvantiToolkit 配置中调用:

using Avanti.Toolkit.Controls;
using Avanti.Toolkit.Desktop.Controls;
using Avanti.Toolkit.MachineVision;

builder.UseDesktopControls();
builder.UseMachineVisionImageDisplay();
builder.UseImageLoading(options =>
{
    // 示例 16384×4000 超过框架默认的 6400 万像素限制,应用显式配置。
    options.MaxImagePixelCount = 100_000_000;
    options.MaxDecodedImageBytes = 512L * 1024 * 1024;
});

UseMachineVisionImageDisplay() 只注册控件主题;应用图片服务由第一阶段的 UseDesktopControls() 或 UseImageLoading() 配置。控件注册可以放入 Deferred, 但图片服务及其预算配置必须保留在第一阶段。

<vision:ImageDisplay xmlns:vision="urn:avanti-toolkit/machine-vision"
                    Source="D:\Images\sample.png" />

Source 使用现有 ImageSource 契约,静态来源经过应用的 IImageLoader;帧流使用 FrameImageSource。 普通静态图片控件不消费帧流,收到该来源时返回明确的 UnsupportedFormat 错误。 本控件不接收 SVG 或 BorrowedImageSource;静态栅格必须通过编码来源进入受校验的解码管线。

# 连续帧

先在 UI 线程把 FrameImageSource 赋给已挂载显示控件,再由单个生产者提交:

var source = new FrameImageSource("Camera 1");
viewer.Source = source;

// 生产者线程:owner 是相机适配器交出的 IMemoryOwner<byte>。
using var frame = new ImageFrame(frameId, width, height, stride, owner);
FramePresentation drawn = await source.SubmitAsync(frame, cancellationToken);

SubmitAsync 返回时该帧已完成至少一次可见视口绘制,随后才提交下一帧。它不确认显示器物理扫描输出。 帧号须严格递增;宽高为正、步长至少等于宽度,缓冲区至少为 stride * height 字节。

提交前调用方拥有缓冲区;接收成功后所有权转交显示控件,调用方不得写入。返回后也不能自行复用, 必须等待租约的 Dispose 归还。失败发生在接收前时仍由调用方释放;接收后取消不提前释放正在渲染的缓冲区。 无法转移相机缓冲区时使用 SubmitCopyAsync,复制期间源内存必须稳定。

同一来源只允许一个显示控件与一个串行生产者。冻结、隐藏和最小化会向生产者施加背压;换源、卸载及关闭取消等待。 采集适配器必须真正等待提交;不能暂停的相机由宿主提供可靠录制,不能通过额外无限队列模拟无遗漏。

# 查看与扩展接口

接口 行为
Zoom、MinZoom、MaxZoom 默认范围 1/256~256;Zoom=1 是一原图像素对应一物理屏幕像素
FitToView()、ActualSize()、ZoomAt()、Pan() 适应、1:1、指定锚点缩放和平移
IsFrozen 保留当前帧,暂停消费
PixelGridMode、PixelGridThreshold 自动/隐藏/显示;自动阈值默认 8 物理像素
Viewport、ImageToView()、ViewToImage() 原图像素与控件 DIP 坐标转换
TryGetPixel()、PixelChanged 返回原始帧号、整数坐标和灰度值;图外无值
State、Error、StateChanged 加载、就绪、错误状态;状态事件通知宿主更新
FrameRendered、RenderBackend 首次绘制确认及实际 Skia GPU/软件后端
CpuMemoryBytes、GpuMemoryBytes 当前显示控件持有的数据与瓦片占用;GPU 采用保守估算
CpuMemoryLimit、GpuMemoryLimit 首次挂载前配置;默认 512 MiB / 128 MiB
ImageOverlays、ScreenOverlays、InvalidateOverlays() 不暴露 Skia 对象的覆盖层快照扩展
ActiveTool UI 线程输入工具,拥有激活、取消和指针捕获生命周期

滚轮以鼠标为中心缩放,中键或空格+左键拖动。Escape 或失去捕获取消交互。 首次输入适应窗口,后续帧保留视口;图片较小时居中,较大时限制平移使视口不越过图片边缘。

覆盖层几何使用原图坐标,控制柄与命中范围可使用屏幕单位,工具可在冻结帧上交互。 当前不提供这些形状的编辑、撤销、旋转、翻转或多视口联动。

更多见实现与生命周期、变更记录及模块边界。