【MAUI Blazor踩坑日记】2.关于Windows上的相机问题
前言
本系列文章,默认你已经踏上了MAUI Blazor的贼船,并且对MAUI Blazor有了一些了解,知道MAUI是什么,知道Blazor是什么。
不会教你怎么写MAUI Blazor的项目,只是提出一些注意点,避免踩坑。
MAUI中Windows上,调用MediaPicker.Default.CapturePhotoAsync()
并不能启动相机拍照。关于这个问题可以查看 https://github.com/dotnet/maui/issues/7660 ,https://github.com/dotnet/maui/pull/13220,
好消息是已经修复了,坏消息是.net8修复了,而且还没发布.
所以目前怎么办, https://github.com/dotnet/maui/issues/7660 中已经给出了临时的解决方案。
正文
- 把下面代码复制到 Platforms/Windows 文件夹下
using Windows.Foundation.Collections;
using Windows.Media.Capture;
using Windows.Storage;
using Windows.System;
using WinRT.Interop;
public static class WindowsMediaPicker
{
public static Task<FileResult?> CapturePhotoAsync()
=> CaptureAsync(false);
public static Task<FileResult?> CaptureVideoAsync()
=> CaptureAsync(true);
private static async Task<FileResult?> CaptureAsync(bool isVideo)
{
var captureUi = new CustomCameraCaptureUI();
StorageFile? file = await captureUi.CaptureFileAsync(isVideo ? CameraCaptureUIMode.Video : CameraCaptureUIMode.Photo);
if (file != null)
{
return new FileResult(file.Path, file.ContentType);
}
return null;
}
private class CustomCameraCaptureUI
{
private readonly LauncherOptions _launcherOptions;
public CustomCameraCaptureUI()
{
var window = WindowStateManager.Default.GetActiveWindow();
var handle = WindowNative.GetWindowHandle(window);
_launcherOptions = new LauncherOptions();
InitializeWithWindow.Initialize(_launcherOptions, handle);
_launcherOptions.TreatAsUntrusted = false;
_launcherOptions.DisplayApplicationPicker = false;
_launcherOptions.TargetApplicationPackageFamilyName = "Microsoft.WindowsCamera_8wekyb3d8bbwe";
}
public async Task<StorageFile?> CaptureFileAsync(CameraCaptureUIMode mode)
{
var extension = mode == CameraCaptureUIMode.Photo ? ".jpg" : ".mp4";
var currentAppData = ApplicationData.Current;
var tempLocation = currentAppData.LocalCacheFolder;
var tempFileName = $"capture{extension}";
var tempFile = await tempLocation.CreateFileAsync(tempFileName, CreationCollisionOption.GenerateUniqueName);
var token = Windows.ApplicationModel.DataTransfer.SharedStorageAccessManager.AddFile(tempFile);
var set = new ValueSet();
if (mode == CameraCaptureUIMode.Photo)
{
set.Add("MediaType", "photo");
set.Add("PhotoFileToken", token);
}
else
{
set.Add("MediaType", "video");
set.Add("VideoFileToken", token);
}
var uri = new Uri("microsoft.windows.camera.picker:");
var result = await Windows.System.Launcher.LaunchUriForResultsAsync(uri, _launcherOptions, set);
if (result.Status == LaunchUriStatus.Success && result.Result != null)
{
return tempFile;
}
return null;
}
}
}
- 如何使用
#if WINDOWS
FileResult? photo = await WindowsMediaPicker.CapturePhotoAsync();
#else
FileResult photo = await MediaPicker.Default.CapturePhotoAsync();
#endif
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)