You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Windows.Media.Devices.FocusControl控制HoloLens 2焦点时ArgumentException报错

HoloLens 2 手动控制焦点触发 ArgumentException 的解决方法

问题现象

在HoloLens 2上使用Windows.Media.Devices.FocusControl手动控制焦点时,调用FocusControl.Configure(FocusSettings)或FocusControl.SetValueAsync(UInt32)会抛出ArgumentException: Value does not fall within the expected range错误。已确认输入值在设备返回的支持范围(最小值170、最大值10000)内,且未使用FocusControl时拍照功能正常。

核心原因

  1. 共享模式限制:初始化MediaCapture时使用SharedReadOnly模式,该模式仅允许读取相机参数,无法修改焦点等控制项。
  2. 配置顺序错误:未正确启用FocusControl的手动模式,或步骤顺序颠倒导致配置未生效。
  3. 焦点值未对齐Step:即使值在Min/Max范围内,未按设备支持的Step值对齐也会触发错误。

解决方案

1. 切换MediaCapture至独占控制模式

将MediaCaptureInitializationSettings的SharingMode改为ExclusiveControl,获取相机的独占控制权以修改参数:

var settings = new MediaCaptureInitializationSettings
{
    SharingMode = MediaCaptureSharingMode.ExclusiveControl
};

2. 按正确顺序配置并启用FocusControl

必须遵循「配置手动模式 → 启用 → 锁定 → 设置值」的顺序:

  • 创建FocusSettings并设置Mode = FocusMode.Manual,同时开启Enabled = true
  • 调用focusControl.Configure应用配置
  • 调用LockAsync锁定焦点控制,避免其他操作干扰
  • 设置焦点值后记得解锁

3. 对齐焦点值至设备支持的Step

使用设备返回的Step值对输入焦点值进行对齐,确保值为Min + N * Step(N为整数):

private uint AlignFocusValue(FocusControl focusControl, uint inputValue)
{
    uint min = focusControl.Min;
    uint max = focusControl.Max;
    uint step = focusControl.Step;

    inputValue = Math.Clamp(inputValue, min, max);
    uint offset = inputValue - min;
    uint alignedOffset = (offset / step) * step;
    return min + alignedOffset;
}

修正后的完整代码

async private void CaptureImageByMediaCapture()
{
    MediaCapture mediaCapture = new MediaCapture();
    var settings = new MediaCaptureInitializationSettings
    {
        SharingMode = MediaCaptureSharingMode.ExclusiveControl
    };

    await mediaCapture.InitializeAsync(settings);

    var focusControl = mediaCapture.VideoDeviceController.FocusControl;

    if (focusControl.Supported)
    {
        Debug.Log($"焦点范围:Min={focusControl.Min}, Max={focusControl.Max}, Step={focusControl.Step}");

        // 配置并启用手动调焦
        var focusSettings = new FocusSettings
        {
            Mode = FocusMode.Manual,
            Enabled = true
        };
        focusControl.Configure(focusSettings);

        // 锁定焦点控制
        await focusControl.LockAsync();

        // 对齐焦点值并设置
        uint targetFocus = AlignFocusValue(focusControl, focusvalue);
        await focusControl.SetValueAsync(targetFocus);

        Debug.Log($"已成功设置焦点值:{targetFocus}");

        // 执行拍照逻辑...

        // 操作完成后解锁
        await focusControl.UnlockAsync();
    }
    else
    {
        Debug.Log("当前相机不支持手动焦点控制");
    }
}

// 对齐焦点值到设备支持的步进值
private uint AlignFocusValue(FocusControl focusControl, uint inputValue)
{
    uint min = focusControl.Min;
    uint max = focusControl.Max;
    uint step = focusControl.Step;

    inputValue = Math.Clamp(inputValue, min, max);
    uint offset = inputValue - min;
    uint alignedOffset = (offset / step) * step;
    return min + alignedOffset;
}

额外注意事项

  • 独占模式会阻止其他应用使用相机,操作完成后建议调用mediaCapture.Dispose()释放资源
  • 若存在多个相机,可添加辅助方法筛选出支持手动调焦的设备ID

内容的提问来源于stack exchange,提问作者Titin Zu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 02:58:17