使用 Xamarin.Forms 访问相机 [英] Camera access with Xamarin.Forms

查看:77
本文介绍了使用 Xamarin.Forms 访问相机的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有人能够提供一个简短的、独立的示例,说明如何使用 Xamarin.Forms 1.3.x 访问相机?简单地调用本机相机应用程序并检索结果图片会很棒.在 Xamarin.Forms 页面上显示实时视图会很棒!

Is anyone able to give a short, self-contained example on how to access the camera with Xamarin.Forms 1.3.x? Simply calling the native camera application and retrieving the resulting picture would be great. Displaying a live view on the Xamarin.Forms page would be awesome!

我已经尝试使用 Xamarin.Mobile 和 Xamarin.Forms.Labs,但我无法获得在这两个平台上都可以使用的任何解决方案(目前专注于 Android 和 iOS).在网络上找到的大多数代码片段(包括 stackoverflow)都不完整,例如未显示 IMediaPicker 对象的实现或定位拍照方法的位置.

I already tried to use Xamarin.Mobile and Xamarin.Forms.Labs, but I couldn't get any solution to work on both platforms (focussing on Android and iOS for now). Most code snippets found on the web (including stackoverflow) are incomplete, e.g. not showing the implementation of an IMediaPicker object or where to anchor the method for taking pictures.

推荐答案

我终于为 iOS 和 Android 创建了一个最小的解决方案.

I finally created a minimum solution for iOS and Android.

首先,让我们看看共享代码.为了在共享 App 类和特定于平台的代码之间轻松交互,我们在 public static App 中存储了一个静态 Instance:

First, let's look into the shared code. For an easy interaction between the shared App class and the platform-specific code we store a static Instance within the public static App:

public static App Instance;

此外,我们将显示一个Image,稍后将填充内容.所以我们创建了一个成员:

Furthermore, we will display an Image, which will be filled with content later. So we create a member:

readonly Image image = new Image();

App 构造函数中,我们存储 Instance 并创建页面内容,这是一个简单的 button 和前面提到的 image:

Within the App constructor we store the Instance and create the page content, which is a simple button and the aforementioned 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.它是一个公共成员,平台特定的代码部分将在稍后分配给它.

The button's click handler calls the event ShouldTakePicture. It is a public member and the platform-specific code parts will assign to it later on.

public event Action ShouldTakePicture = () => {};

最后,我们提供了一个公共方法来显示捕获的图像:

Finally, we offer a public method for displaying the captured image:

public void ShowImage(string filepath)
{
    image.Source = ImageSource.FromFile(filepath);
}

Android 项目

在 Android 上,我们修改了 MainActivity.首先,我们为捕获的图像文件定义一个路径:

The Android project

On Android we modify the MainActivity. First, we define a path for the captured image file:

static readonly File file = new File(Environment.GetExternalStoragePublicDirectory(Environment.DirectoryPictures), "tmp.jpg");

OnCreate 的末尾,我们可以使用创建的 App 的静态 Instance 并分配一个匿名事件处理程序,它将启动一个用于捕获图像的新 Intent:

At the end of OnCreate we can use the static Instance of the created App and assign an anonymous event handler, which will start a new Intent for capturing an image:

App.Instance.ShouldTakePicture += () => {
   var intent = new Intent(MediaStore.ActionImageCapture);
   intent.PutExtra(MediaStore.ExtraOutput, Uri.FromFile(file));
   StartActivityForResult(intent, 0);
};

最后但并非最不重要的是,我们的活动必须对生成的图像做出反应.它将简单地将其文件路径推送到共享的 ShowImage 方法.

Last but not least, our activity has to react on the resulting image. It will simply push its file path to the shared ShowImage method.

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
   base.OnActivityResult(requestCode, resultCode, data);
   App.Instance.ShowImage(file.Path);
}

就是这样!只是不要忘记在AndroidManifest.xml"中设置Camera"和WriteExternalStorage"权限!

That's about it! Just don't forget to set the "Camera" and the "WriteExternalStorage" permission within "AndroidManifest.xml"!

对于 iOS 实现,我们创建了一个自定义渲染器.因此,我们添加一个新文件CustomContentPageRenderer"并在 using 语句之后添加相应的程序集属性:

For the iOS implementation we create a custom renderer. Therefore, we add a new file "CustomContentPageRenderer" and add the corresponding assembly attribute right after the using statements:

[assembly:ExportRenderer(typeof(ContentPage), typeof(CustomContentPageRenderer))]

CustomContentPageRenderer 继承自 PageRenderer:

public class CustomContentPageRenderer: PageRenderer
{
    ...
}

我们重写 ViewDidAppear 方法并添加以下部分.

We override the ViewDidAppear method and add the following parts.

创建一个引用相机的新图像选择器控制器:

Create a new image picker controller referring to the camera:

var imagePicker = new UIImagePickerController { SourceType = UIImagePickerControllerSourceType.Camera };

一旦 ShouldTakePicture 事件被引发,就呈现图像选择器控制器:

Present the image picker controller, as soon as the ShouldTakePicture event is raised:

App.Instance.ShouldTakePicture += () => PresentViewController(imagePicker, true, null);

拍照后保存到MyDocuments文件夹,调用共享的ShowImage方法:

After taking the picture, save it to the MyDocuments folder and call the shared ShowImage method:

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);
        };

最后,我们需要处理取消图像拍摄过程:

And finally, we need to handle a cancellation of the image taking process:

imagePicker.Canceled += (sender, e) => DismissViewController(true, null);

这篇关于使用 Xamarin.Forms 访问相机的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆