有没有人能够提供一个简短的、独立的示例来说明如何使用 Xamarin.Forms 1.3.x 访问相机?只需调用 native 相机应用程序并检索生成的图片就可以了。在 Xamarin.Forms 页面上显示实时 View 会很棒!
我已经尝试过使用 Xamarin.Mobile 和 Xamarin.Forms.Labs,但我无法找到适用于这两个平台的任何解决方案(目前专注于 Android 和 iOS)。在网络上找到的大多数代码片段(包括 stackoverflow)都不完整,例如不显示 IMediaPicker 对象的实现或在何处锚定拍照方法。
最佳答案
我终于为 iOS 和 Android 创建了一个最小的解决方案。
共享项目
首先,让我们看看共享代码。为了在共享 App
类和特定于平台的代码之间轻松交互,我们在 public static App
中存储了一个静态 Instance
:
public static App Instance;
此外,我们将显示一个 Image
,稍后将在其中填充内容。所以我们创建一个成员:
readonly Image image = new Image();
在 App
构造函数中,我们存储 Instance
并创建页面内容,这是一个简单的 button
和前面提到的 image
:
public App()
{
Instance = this;
var button = new Button {
Text = "Snap!",
Command = new Command(o => ShouldTakePicture()),
};
MainPage = new ContentPage {
Content = new StackLayout {
VerticalOptions = LayoutOptions.Center,
Children = {
button,
image,
},
},
};
}
按钮的点击处理程序调用事件 ShouldTakePicture
。
它是一个公共(public)成员,特定于平台的代码部分稍后将分配给它。
public event Action ShouldTakePicture = () => {};
最后,我们提供了一个公共(public)方法来显示捕获的图像:
public void ShowImage(string filepath)
{
image.Source = ImageSource.FromFile(filepath);
}
安卓项目
在 Android 上,我们修改 MainActivity
。
首先,我们为捕获的图像文件定义一个路径:
static readonly File file = new File(Environment.GetExternalStoragePublicDirectory(Environment.DirectoryPictures), "tmp.jpg");
在 OnCreate
结束时,我们可以使用创建的 App
的静态 Instance
并分配一个匿名事件处理程序,这将启动一个用于捕获图像的新 Intent
:
App.Instance.ShouldTakePicture += () => {
var intent = new Intent(MediaStore.ActionImageCapture);
intent.PutExtra(MediaStore.ExtraOutput, Uri.FromFile(file));
StartActivityForResult(intent, 0);
};
最后但同样重要的是,我们的事件必须对生成的图像使用react。它只会将其文件路径推送到共享的 ShowImage
方法。
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
App.Instance.ShowImage(file.Path);
}
就是这样! 只是不要忘记在“AndroidManifest.xml”中设置“Camera”和“WriteExternalStorage”权限!
iOS 项目
对于 iOS 实现,我们创建了一个自定义渲染器。 因此,我们添加一个新文件“CustomContentPageRenderer”,并在using语句之后添加相应的程序集属性:
[assembly:ExportRenderer(typeof(ContentPage), typeof(CustomContentPageRenderer))]
CustomContentPageRenderer
继承自PageRenderer
:
public class CustomContentPageRenderer: PageRenderer
{
...
}
我们覆盖ViewDidAppear
方法并添加以下部分。
创建一个引用相机的新图像选择器 Controller :
var imagePicker = new UIImagePickerController { SourceType = UIImagePickerControllerSourceType.Camera };
一旦引发了 ShouldTakePicture
事件,就显示图像选择器 Controller :
App.Instance.ShouldTakePicture += () => PresentViewController(imagePicker, true, null);
拍照后保存到MyDocuments
文件夹,调用共享的ShowImage
方法:
imagePicker.FinishedPickingMedia += (sender, e) => {
var filepath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "tmp.png");
var image = (UIImage)e.Info.ObjectForKey(new NSString("UIImagePickerControllerOriginalImage"));
InvokeOnMainThread(() => {
image.AsPNG().Save(filepath, false);
App.Instance.ShowImage(filepath);
});
DismissViewController(true, null);
};
最后,我们需要处理图像拍摄过程的取消:
imagePicker.Canceled += (sender, e) => DismissViewController(true, null);
关于c# - 使用 Xamarin.Forms 访问相机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28207571/