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

.NET MAUI中如何实现前置摄像头预览及按钮触发拍照功能?

在.NET MAUI中实现前置摄像头预览+按钮拍照的方案

目前.NET MAUI Community Toolkit确实还没有提供CameraView控件,你可以通过以下两种方式实现需求:

方案一:使用第三方库Camera.MAUI

这是最快捷的实现方式,该库专为MAUI打造,支持摄像头预览、拍照、切换前后置等核心功能。

  1. 安装NuGet包:Camera.MAUI
  2. 在MauiProgram.cs中初始化库:
builder.UseMauiApp<App>().UseCamera();
  1. 在XAML页面中添加相机预览控件和拍照按钮:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:camera="clr-namespace:Camera.MAUI;assembly=Camera.MAUI"
             x:Class="YourNamespace.CameraPage">
    <Grid>
        <!-- 前置摄像头预览控件 -->
        <camera:CameraView x:Name="cameraView" 
                           CameraOptions="Front"
                           HorizontalOptions="Fill"
                           VerticalOptions="Fill"/>
        <!-- 拍照触发按钮 -->
        <Button Text="拍照" 
                VerticalOptions="End"
                HorizontalOptions="Center"
                Margin="0,0,0,20"
                Clicked="OnTakePhotoClicked"/>
    </Grid>
</ContentPage>
  1. 在后台代码实现拍照逻辑:
private async void OnTakePhotoClicked(object sender, EventArgs e)
{
    if (cameraView.IsCameraAvailable)
    {
        var photo = await cameraView.CapturePhotoAsync();
        if (photo != null)
        {
            // 处理拍摄的照片,比如保存到本地或显示在Image控件中
            var imageSource = ImageSource.FromStream(() => photo.AsStream());
            // photoImage.Source = imageSource; // 假设页面有一个名为photoImage的Image控件
        }
    }
}

方案二:自定义平台视图(Handler)实现原生预览

如果不想依赖第三方库,可以通过MAUI的Handler机制,针对各平台编写原生相机逻辑,封装成可复用的自定义控件。

核心步骤:

  1. 在共享项目中定义CameraPreview自定义控件
  2. 为Android、iOS、Windows分别编写Handler,实现原生前置摄像头预览和拍照逻辑
  3. 在页面中使用自定义控件+按钮完成交互

简化版示例代码:

  1. 共享项目自定义控件:
public class CameraPreview : View
{
    // 绑定拍照命令
    public static readonly BindableProperty TakePhotoCommandProperty =
        BindableProperty.Create(nameof(TakePhotoCommand), typeof(ICommand), typeof(CameraPreview));

    public ICommand TakePhotoCommand
    {
        get => (ICommand)GetValue(TakePhotoCommandProperty);
        set => SetValue(TakePhotoCommandProperty, value);
    }

    // 照片拍摄完成事件
    public event EventHandler<Stream> PhotoCaptured;
}
  1. Android平台Handler关键实现:
[assembly: ExportHandler(typeof(CameraPreview), typeof(CameraPreviewHandler))]
namespace YourNamespace.Platforms.Android
{
    public class CameraPreviewHandler : ViewHandler<CameraPreview, Android.Views.View>
    {
        private CameraXPreviewView _previewView;
        private ImageCapture _imageCapture;

        protected override Android.Views.View CreatePlatformView()
        {
            _previewView = new CameraXPreviewView(Context);
            // 配置CameraX前置摄像头
            var cameraProviderFuture = ProcessCameraProvider.GetInstance(Context);
            cameraProviderFuture.AddListener(() =>
            {
                var cameraProvider = cameraProviderFuture.Get();
                var preview = new Preview.Builder().Build();
                var cameraSelector = new CameraSelector.Builder()
                    .RequireLensFacing(LensFacing.Front)
                    .Build();

                _imageCapture = new ImageCapture.Builder().Build();
                preview.SetSurfaceProvider(_previewView.SurfaceProvider);
                cameraProvider.BindToLifecycle((Activity)Context, cameraSelector, preview, _imageCapture);
            }, Context.MainExecutor);

            return _previewView;
        }

        protected override void ConnectHandler(Android.Views.View platformView)
        {
            base.ConnectHandler(platformView);
            VirtualView.TakePhotoCommand = new Command(async () =>
            {
                var outputFile = new File(Context.CacheDir, $"photo_{Guid.NewGuid()}.jpg");
                var outputOptions = new ImageCapture.OutputFileOptions.Builder(outputFile).Build();
                await _imageCapture.TakePictureAsync(outputOptions, Context.MainExecutor, new ImageCaptureCallback(VirtualView));
            });
        }

        private class ImageCaptureCallback : ImageCapture.OnImageSavedCallback
        {
            private readonly CameraPreview _virtualView;
            public ImageCaptureCallback(CameraPreview virtualView) => _virtualView = virtualView;

            public void OnImageSaved(ImageCapture.OutputFileResults outputFileResults)
            {
                using var stream = new FileStream(outputFileResults.SavedUri.Path, FileMode.Open);
                _virtualView.PhotoCaptured?.Invoke(null, stream);
            }

            public void OnError(int imageCaptureError, string message, Exception exception)
            {
                // 处理拍照错误
            }
        }
    }
}
  1. XAML页面使用自定义控件:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:YourNamespace"
             x:Class="YourNamespace.CameraPage">
    <Grid>
        <local:CameraPreview x:Name="cameraPreview"/>
        <Button Text="拍照" 
                VerticalOptions="End"
                HorizontalOptions="Center"
                Margin="0,0,0,20"
                Command="{Binding Source={x:Reference cameraPreview}, Path=TakePhotoCommand}"/>
    </Grid>
</ContentPage>

注:iOS和Windows平台需编写对应Handler,分别使用AVFoundation(iOS)、MediaCapture(Windows)API实现前置摄像头预览和拍照逻辑,核心思路与Android一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 22:18:10