与Xamarin.Forms相机接入 [英] Camera access with 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(文件路径);
}
的Android项目
在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屋!