与Xamarin.Forms相机接入 [英] Camera access with Xamarin.Forms

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

问题描述

有没有人能给出关于如何访问与Xamarin.Forms 1.3.x的相机很短的,自包含的例子吗?简单地调用本机摄像头应用程序和检索结果图像将是巨大的。显示Xamarin.Forms页面上的实时取景将是真棒!



我已经尝试过使用Xamarin.Mobile和Xamarin.Forms.Labs,但我无法得到任何解决这两个平台(侧重于Android和iOS目前)上工作。在网络上(包括计算器)发现,大多数的代码片段是不完整的,例如不显示一个IMediaPicker对象或者锚定的拍照方法的实现。


解决方案

我终于创建了一个最低的解决方案iOS和Android。



共享项目



首先,让我们看看到共享代码。对于共享应用类和特定于平台的代码之间的一个简单的互动,我们存储一个静态实例公共静态应用程序



<预类=郎-CS prettyprint-覆盖> 公共静态应用程序实例;



此外,我们将显示一个图片,稍后将填充有内容。因此,我们创建成员:

 只读图片形象=新的图像(); 



应用构造我们存储的实例和创建页面内容,这是一个简单的按钮和上述图片

 公共应用程序()
{
实例=这一点;

VAR按钮=新的Button {
文本=!捕捉,
命令=新司令部(O => ShouldTakePicture()),
};

=的MainPage新ContentPage {
含量=新StackLayout {
VerticalOptions = LayoutOptions.Center,
=儿童{
键,
图像,
},
},
};
}



按钮的Click处理程序调用该事件 ShouldTakePicture
这是一个公共成员和特定于平台的代码部分将分配给它以后。

 公共事件的行动ShouldTakePicture =()=> {}; 



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

 公共无效ShowImage(字符串文件路径)
{
image.Source = ImageSource.FromFile(文件路径);
}



的Andr​​oid项目



在Android上,我们修改 MainActivity
首先,我们定义为所拍摄的图像文件的路径:

 静态只读文件的文件=新的文件(环境。 GetExternalStoragePublicDirectory(Environment.DirectoryPictures),tmp.jpg); 



的OnCreate 结束时,我们可以使用静态实例创建应用程序的并分配一个匿名事件处理程序,这将启动一个新的意图用于捕捉图像:

  App.Instance.ShouldTakePicture + =()=> {
变种意图=新意图(MediaStore.ActionImageCapture);
intent.PutExtra(MediaStore.ExtraOutput,Uri.FromFile(文件));
StartActivityForResult(意向,0);
};



最后但并非最不重要的,我们的活动具有对由此产生的图像上的反应。它只是推动其文件路径共享 ShowImage 方法。

 保护覆盖无效的onActivityResult(INT requestCode,结果resultCode为,意图数据)
{
base.OnActivityResult(requestCode,resultCode为,数据);
App.Instance.ShowImage(file.Path);
}



这就是它!
只是不要忘记设置照相机和AndroidManifest.xml中!



iOS的项目

中的WriteExternalStorage权限

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

  [大会:ExportRenderer(typeof运算(ContentPage)的typeof(CustomContentPageRenderer))] 



CustomContentPageRenderer PageRenderer :

 公共类CustomContentPageRenderer:PageRenderer 
{

}

我们覆盖 ViewDidAppear 方法,并添加下面的部分。



创建一个新的图像选择器控制器指摄像头:

  VAR imagePicker =新的UIImagePickerController {SourceType中= UIImagePickerControllerSourceType.Camera}; 



目前图像选择器控制,一旦 ShouldTakePicture 事件引发的:

  App.Instance.ShouldTakePicture + =()=> PresentViewController(imagePicker,真实,NULL); 



拍摄照片后,将其保存到我的文档文件夹,并调用共享 ShowImage 方法:

  imagePicker.FinishedPickingMedia + =(发件人,E)=> {
变种文件路径= Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),tmp.png);
VAR图像=(的UIImage)e.Info.ObjectForKey(新的NSString(UIImagePickerControllerOriginalImage));
InvokeOnMainThread(()=> {
image.AsPNG()保存(文件路径,FALSE);
App.Instance.ShowImage(文件路径);
});
DismissViewController(TRUE,NULL);
};



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

  imagePicker.Canceled + =(发件人,E)=> DismissViewController(TRUE,NULL); 


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!

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.

解决方案

I finally created a minimum solution for iOS and Android.

The shared project

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;

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

readonly Image image = new 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,
           },
       },
   };
}

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

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

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

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

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

The iOS project

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))]

The CustomContentPageRenderer inherits from PageRenderer:

public class CustomContentPageRenderer: PageRenderer
{
    ...
}

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

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

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

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天全站免登陆