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
相关产品推荐
相关产品推荐

