# AaloniaUI内置相机控件
**Repository Path**: xecc/camera_view.avalonia
## Basic Information
- **Project Name**: AaloniaUI内置相机控件
- **Description**: AaloniaUI内置相机控件 In-App
- **Primary Language**: C#
- **License**: MulanPSL-2.0
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-05-27
- **Last Updated**: 2026-09-17
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# CameraView.Avalonia
跨平台相机预览与拍照控件,基于 Avalonia UI 框架。
## 支持的平台
| 平台 | TFM |
|------|-----|
| Android | `net10.0-android` |
| iOS | `net10.0-ios` |
| Windows | `net10.0-windows10.0.19041.0` |
| macOS | `net10.0-macos` |
| Browser (WASM) | `net10.0-browser` |
| Linux | `net10.0` (需 Linux 主机编译) |
## 安装
```shell
dotnet add package CameraView.Avalonia
```
## 快速开始
### 1. XAML 引用
```xml
xmlns:cv="using:CameraView"
```
### 2. 启动相机
```csharp
// 方式一:绑定 CameraEnabled(推荐,自动初始化)
CameraEnabled = true;
// 方式二:手动初始化并启动(需要 provider 引用时用此方式)
var provider = CameraProviderFactory.Create();
await CameraControl.InitializeCameraAsync(provider);
CameraEnabled = true; // 自动触发 StartCameraAsync
```
> 💡 `CameraEnabled = true` 会自动判断是否需要初始化,无需手动调用 `InitializeCameraAsync`。
### 3. Windows 项目配置
桌面项目的 `.csproj` 中 `TargetFramework` 必须改为 Windows 专用 TFM:
```diff
- net10.0
+ net10.0-windows10.0.19041.0
```
> ⚠️ 多项目结构中,**引用 CameraView 的项目**(如 `MyApp.Desktop.csproj`)需要改,
> 不是共享库项目(`MyApp.csproj` 保持 `net10.0`)。
### 4. App.axaml — 加载控件模板
```xml
```
### 5. Android 配置
> ⚠️ Android EXE 项目(如 `MyApp.Android.csproj`)**必须**直接引用 `CameraView.Avalonia`,
> 仅靠共享库(`net10.0`)间接引用不会触发 `buildTransitive .targets` 注入 Android JNI 文件。
```xml
```
```csharp
// MainActivity.OnCreate — 必须在 base.OnCreate 之前注册
var context = this.BaseContext;
var provider = new CameraView.Platforms.Android.AndroidCameraProvider(context);
CameraView.CameraProviderFactory.RegisterProvider(provider);
base.OnCreate(savedInstanceState);
CameraView.CameraProviderFactory.SetAndroidActivity(this);
```
> 💡 **前后台生命周期:** App 切到后台时相机应停止(释放 Camera 资源)。可在 `MainActivity` 中添加:
>
> ```csharp
> protected override void OnPause()
> {
> base.OnPause();
> if (cameraProvider?.IsInitialized == true)
> _ = cameraProvider.StopPreviewAsync();
> }
>
> protected override void OnResume()
> {
> base.OnResume();
> if (wasCameraRunning)
> _ = cameraProvider.StartPreviewAsync();
> }
> ```
>
> iOS 端由 `iOSCameraProvider` 内部自动处理,无需额外配置。
### 6. 权限
>
> iOS 端由 `iOSCameraProvider` 内部自动处理,无需额外配置。
```xml
```
```csharp
// 启动前手动申请权限
var perms = CameraProviderFactory.CreatePermissions(provider);
if (!await perms.CheckPermissionAsync())
if (!await perms.RequestPermissionAsync())
return; // 无权限,ErrorOccurred 会触发说明
CameraEnabled = true;
```
无权限时相机启动会失败,通过 `ErrorCommand`(MVVM)或 `CameraError` 事件输出错误信息。
```xml
```
```csharp
// ViewModel
[RelayCommand]
private void OnCameraError(string error)
{
StatusText = $"相机错误: {error}";
}
```
或者订阅事件:
```csharp
CameraControl.CameraError += (_, error) => Debug.WriteLine(error);
```
> 💡 **调试模式性能提示:** Debug 模式下 Mono 解释器/未优化 JIT 会导致 YUV→BGRA 帧转换性能显著降低,预览帧率可能降至 2-8fps。
> 使用 `Release` 配置(AOT 编译)可获得 25-30fps 流畅预览。
## 功能
- [x] 相机预览(实时帧)
- [x] 拍照(JPEG 输出)
- [x] 前后摄像头切换
- [x] 点击对焦
- [x] 捏合缩放
- [x] 手电筒(闪光灯)
- [x] 闪光灯模式(自动/开/关)
- [x] 曝光补偿
- [x] 拍照分辨率选择(自动查询支持的分辨率)
- [x] 设备朝向传感器(重力方向)
- [x] 照片 EXIF 方向校正(iOS/Android 拍照时自动旋转像素)
- [x] 调试模式(显示 FPS)
---
## API 参考
### 依赖属性(可绑定)
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `CameraEnabled` | `bool` | `false` | 开关相机(TwoWay) |
| `CameraFacing` | `CameraFacing` | `Back` | 前后摄像头(TwoWay) |
| `IsFrontCamera` | `bool` | `false` | 是否为前置摄像头(TwoWay) |
| `TorchOn` | `bool` | `false` | 手电筒(TwoWay) |
| `RequestZoomFactor` | `float?` | `null` | 请求缩放倍率(TwoWay) |
| `CurrentZoomFactor` | `float?` | `null` | 当前缩放倍率(只读,由 provider 同步) |
| `MinZoomFactor` | `float?` | `null` | 最小缩放倍率(只读,由 provider 同步) |
| `MaxZoomFactor` | `float?` | `null` | 最大缩放倍率(只读,由 provider 同步) |
| `TapToFocusEnabled` | `bool` | `true` | 点击对焦开关(TwoWay) |
| `PinchToZoomEnabled` | `bool` | `true` | 捏合缩放开关(TwoWay) |
| `FlashMode` | `FlashMode` | `Auto` | 闪光灯模式(TwoWay) |
| `PhotoResolution` | `PhotoResolution?` | `null` | 照片分辨率(TwoWay) |
| `SupportedResolutions` | `IReadOnlyList` | — | 支持的照片分辨率列表(只读) |
| `ExposureCompensation` | `float` | `0` | 曝光补偿 EV(TwoWay) |
| `DebugMode` | `bool` | `false` | 调试模式:显示 FPS 叠加层(TwoWay) |
| `IsCapturingNextFrame` | `bool` | `false` | 触发拍照:设为 true 触发拍照,完成后重置(TwoWay) |
| `IsBusying` | `bool` | `false` | 忙碌状态:拍照/切换时为 true(OneWayToSource) |
| `DeviceOrientation` | `DeviceOrientation?` | `null` | 设备朝向原始数据(OneWayToSource) |
| `OrientationState` | `DeviceOrientationState` | `PortraitUpright` | 设备朝向状态(OneWayToSource) |
| `PreviewAspectRatio` | `double` | `4/3` | 预览帧宽高比(只读) |
| `FocusIndicatorStroke` | `IBrush` | `DeepPink` | 对焦圆环颜色(TwoWay) |
| `FocusIndicatorStrokeThickness` | `double` | `2.0` | 对焦圆环粗细(TwoWay) |
| `CameraProvider` | `ICameraProvider?` | `null` | 外部注入的相机提供者 |
| `PhotoCapturedCommand` | `ICommand?` | `null` | 拍照完成命令(参数 `PhotoCaptureResult`) |
| `ErrorCommand` | `ICommand?` | `null` | 相机错误命令(参数 `string`) |
### 方法
| 方法 | 返回 | 说明 |
|------|------|------|
| `InitializeCameraAsync(ICameraProvider)` | `Task` | 初始化相机:注册事件 + 平台初始化 |
| `StartCameraAsync()` | `Task` | 启动预览(如果未初始化则自动初始化) |
| `StopCameraAsync()` | `Task` | 停止预览 |
| `TakePhotoAsync()` | `Task` | 拍照 |
### 事件
| 事件 | 参数 | 说明 |
|------|------|------|
| `PhotoCaptured` | `EventHandler` | 拍照完成(JPEG 原始字节) |
| `CameraError` | `EventHandler` | 相机错误 |
| `DeviceOrientationChanged` | `EventHandler` | 设备朝向变化(Pitch/Roll/Yaw + 重力向量) |
---
## 平台支持
| 功能 | Android | iOS | Windows | macOS | Browser | Linux |
|------|---------|-----|---------|-------|---------|-------|
| 相机预览 | ✅ | ✅ | ✅ | ✅ | ✅ | ⚠️ |
| 拍照(JPEG) | ✅ | ✅ | ✅ | ✅ | ✅ | ⚠️ |
| 前后摄像头切换 | ✅ | ✅ | ✅ | — | ✅ | — |
| 点击对焦 | ✅ | ✅ | — | — | — | — |
| 捏合缩放 | ✅ | ✅ | ⚠️ | — | — | — |
| 手电筒 / 闪光灯 | ✅ | ✅ | ⚠️ | — | — | — |
| 闪光灯模式 | ✅ | ✅ | ✅ | — | — | — |
| 曝光补偿 | ✅ | ✅ | ⚠️ | — | — | — |
| 拍照分辨率选择 | ✅ | ✅ | ✅ | — | — | — |
| 设备朝向传感器 | ✅ | ✅ | — | — | — | — |
| 照片 EXIF 方向校正 | ✅ | ✅ | — | — | — | — |
| 调试模式(FPS) | ✅ | ✅ | ✅ | ✅ | ✅ | ⚠️ |
> ✅ 已实现 ⚠️ 部分支持或依赖设备/驱动 — 平台不提供
>
> Windows 端的缩放、手电筒、曝光补偿、闪光灯模式已实现,但是否生效取决于摄像头驱动是否暴露对应控制接口
> (`ZoomControl` / `TorchControl` / `ExposureCompensationControl` / `FlashControl`),不支持时静默忽略。
> Windows 点击对焦未实现:WinRT 的 `RegionOfInterest.Bounds` 使用整型 `BitmapBounds`,无法可靠表达 0~1 归一化坐标。