c# - 使用 Xamarin.Forms 访问相机

标签 c# camera xamarin.forms xamarin.mobile xamarin.forms.labs

有没有人能够提供一个简短的、独立的示例来说明如何使用 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/

相关文章:

c# - 合并键值对列表

c# - 触发事件时的事件和委托(delegate)顺序

swift - 如何从 iOS 11 和 Swift 4 中的相机捕获深度数据?

c# - 加载 WebView Xamarin 表单时的事件指示器

c# - 如何从 Windows 操作系统获取当前用户名和密码。

c# - 如何更改 PictureBox 的图像?

android - 我是 xamarin 新手,想在我的 xamarin.forms 项目中实现对话框

xamarin.forms - 是否可以使用 Xamarin Forms 来定位 iOS 7?

c++ - 使用 GLM 正确旋转 Open GL 相机

opengl - 有人可以解释一下我如何使用四元数来使用鼠标像 FPS 一样环顾四周吗?