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

2023年C# Android:Xamarin.Forms MediaPicker捕获分辨率设置咨询

解决Xamarin.Forms MediaPicker无法调整拍摄分辨率/画质的方案

Xamarin.Forms的MediaPicker确实没有提供直接配置拍摄分辨率、画质的API,要实现这个需求,你需要针对Android平台做自定义相机实现,通过调用Android原生相机API来控制参数,具体方案如下:

一、图像拍摄的分辨率控制

1. 定义共享依赖服务接口

在Xamarin.Forms共享项目中创建接口,统一跨平台调用入口:

public interface ICustomCameraService
{
    // 指定宽高捕获图像,返回图像本地路径
    Task<string> CaptureImageWithResolution(int targetWidth, int targetHeight);
}

2. Android平台实现依赖服务

在Android项目中实现上述接口,负责启动自定义相机页面:

[assembly: Dependency(typeof(CustomCameraService))]
namespace YourAppNamespace.Droid
{
    public class CustomCameraService : ICustomCameraService
    {
        private TaskCompletionSource<string> _resultSource;

        public Task<string> CaptureImageWithResolution(int targetWidth, int targetHeight)
        {
            _resultSource = new TaskCompletionSource<string>();
            // 启动自定义相机Activity,传递分辨率参数
            var cameraIntent = new Intent(Android.App.Application.Context, typeof(CustomCameraActivity));
            cameraIntent.PutExtra("TargetWidth", targetWidth);
            cameraIntent.PutExtra("TargetHeight", targetHeight);
            cameraIntent.AddFlags(ActivityFlags.NewTask);
            Android.App.Application.Context.StartActivity(cameraIntent);
            return _resultSource.Task;
        }

        // 供相机Activity调用,返回拍摄结果
        public void SetCaptureResult(string imagePath)
        {
            _resultSource.SetResult(imagePath);
        }
    }
}

3. 编写Android自定义相机Activity

使用Google推荐的CameraX API来配置分辨率,创建CustomCameraActivity:

public class CustomCameraActivity : AppCompatActivity
{
    private ImageCapture _imageCapture;

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.CustomCameraLayout);

        int targetWidth = Intent.GetIntExtra("TargetWidth", 1920);
        int targetHeight = Intent.GetIntExtra("TargetHeight", 1080);

        // 初始化CameraX
        var cameraProviderFuture = ProcessCameraProvider.GetInstance(this);
        cameraProviderFuture.AddListener(() =>
        {
            var cameraProvider = cameraProviderFuture.Get();
            // 预览组件
            var preview = new Preview.Builder()
                .Build()
                .SetSurfaceProvider(FindViewById<PreviewView>(Resource.Id.camera_preview).SurfaceProvider);

            // 配置图像捕获参数,指定分辨率
            _imageCapture = new ImageCapture.Builder()
                .SetTargetResolution(new Size(targetWidth, targetHeight))
                .SetCaptureMode(ImageCapture.CaptureMode.MaximizeQuality)
                .Build();

            // 绑定相机生命周期
            try
            {
                cameraProvider.UnbindAll();
                cameraProvider.BindToLifecycle(this, CameraSelector.DefaultBackCamera, preview, _imageCapture);
            }
            catch (Exception ex)
            {
                // 捕获相机绑定异常
                DependencyService.Get<ICustomCameraService>().SetCaptureResult(null);
                Finish();
            }
        }, ContextCompat.GetMainExecutor(this));

        // 拍摄按钮点击事件
        FindViewById<Button>(Resource.Id.capture_btn).Click += async (s, e) =>
        {
            var outputFile = new File(ExternalMediaDirs[0], $"CapturedImage_{DateTime.Now:yyyyMMddHHmmss}.jpg");
            var outputOptions = new ImageCapture.OutputFileOptions.Builder(outputFile).Build();

            await _imageCapture.TakePictureAsync(outputOptions, ContextCompat.GetMainExecutor(this),
                new ImageCapture.OnImageSavedCallback
                {
                    OnImageSaved = (results) =>
                    {
                        DependencyService.Get<ICustomCameraService>().SetCaptureResult(outputFile.AbsolutePath);
                        Finish();
                    },
                    OnError = (error, message) =>
                    {
                        DependencyService.Get<ICustomCameraService>().SetCaptureResult(null);
                        Finish();
                    }
                });
        };
    }
}

二、视频拍摄的分辨率/画质控制

和图像方案逻辑一致,扩展依赖服务接口,使用CameraX的VideoCapture API配置分辨率和码率:

1. 扩展接口

public interface ICustomCameraService
{
    Task<string> CaptureImageWithResolution(int targetWidth, int targetHeight);
    // 添加视频拍摄方法,指定分辨率和码率(码率控制画质,值越高画质越好)
    Task<string> CaptureVideoWithResolution(int targetWidth, int targetHeight, int bitRate);
}

2. Android实现视频拍摄逻辑

在CustomCameraService中添加对应实现,并在相机Activity中配置VideoCapture:

// 配置VideoCapture示例代码
var videoCapture = new VideoCapture.Builder()
    .SetTargetResolution(new Size(targetWidth, targetHeight))
    .SetBitRate(bitRate) // 例如设置为10*1024*1024(10Mbps)
    .Build();

三、关键注意事项

  • 必须在AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" /> <!-- 视频拍摄需要 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.camera" />
  • 运行时动态申请相机、存储等权限,确保用户授权后再启动相机
  • CameraX兼容性优于旧版Camera API,建议优先使用,需在Android项目的NuGet中安装Xamarin.Google.Camerax.Core包

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 11:59:52