Camera_CustomCamera¶
演示如何使用非系统API的自定义摄像头创建一个EasyAR应用。
你可以参考这个sample,自己定制一个CameraDevice。这个sample使用系统API作为示例,不直接支持Android USB摄像头,如果需要应集成libuvc,可以参考 这个帖子 。
注:Windows USB摄像头有自带支持,不需要使用此示例。
注:使用视频流作为Camera也是可以的,你可以参考接口文档修改这个样例来实现。
用法¶
详解¶
使用自定义FrameSource¶
在场景中使用自定义相机设备,只需要使用自定义的FrameSource替换VideoCamera。将它放到ARSession节点下面,session将会自动使用它。
继承CameraSource¶
这个sample继承CameraSource来实现camera功能。Override Open/Close/OnEnable/OnDisable 方法来让camera可以运行。
如果需要使用非camera的frame source,可以继承FrameSource而非CameraSource。
public override bool HasSpatialInformation
{
get { return false; }
}
protected override void OnEnable()
{
base.OnEnable();
#if !UNITY_EDITOR && UNITY_ANDROID
if (externalCamera != null)
externalCamera.Call<bool>("start", cameraCallback);
#elif !UNITY_EDITOR && UNITY_IOS
if (externalCamera != null)
externalCamera.start(cameraCallback);
#endif
}
protected override void OnDisable()
{
base.OnDisable();
#if !UNITY_EDITOR && UNITY_ANDROID
if (externalCamera != null)
externalCamera.Call<bool>("stop");
#elif !UNITY_EDITOR && UNITY_IOS
if (externalCamera != null)
externalCamera.stop();
#endif
}
public override void Open()
{
}
public override void Close()
{
}
原生camera实现¶
这个sample使用原生camera代码来提供camera功能。不同平台的代码位于不同的地方。
Android实现在CustomCameraAndroid的Gradle工程中,它的输出被预先编译成custom-camera.jar并存放在Plugins文件夹。
iOS实现在Plugins文件夹的MyCamera文件中。
使用原生代码实现camera设备可以使用系统camera提供最大的灵活性。你可以修改这些代码来让没有被集成到EasyAR VideoCameraDevice中的系统相机的功能工作。
暴露原生相机接口道C#¶
sample中有一部分代码用来将原生接口包装成C#接口以便在C#中访问。这些代码会直接调用Java或C接口。
private AndroidJavaObject externalCamera;
private CameraCallback cameraCallback;
private class CameraCallback : AndroidJavaProxy
{
}
private ExternalCamera externalCamera;
private Action<IntPtr, int> cameraCallback;
private class ExternalCamera : IDisposable
{
}
在相机回调中处理InputFrame¶
sample中Android 和 iOS 的实现都将camera的回调暴露到了C#。在回调中, InputFrameSink.handle 用来处理从原始图像数据创建的InputFrame。
private void HandleSink(Buffer imageBuffer, PixelFormat format, Vector2 imageSize, int orientation, int cameraType, double timestamp)
{
using (var cameraParams = CameraParameters.createWithDefaultIntrinsics(new Vec2I((int)imageSize.x, (int)imageSize.y), (CameraDeviceType)cameraType, orientation))
using (var image = new Image(imageBuffer, format, (int)imageSize.x, (int)imageSize.y))
using (var frame = InputFrame.createWithImageAndCameraParametersAndTemporal(image, cameraParams, timestamp))
{
if (sink != null)
sink.handle(frame);
}
imageBuffer.Dispose();
}