我想用我的PhotoCapture统一脚本通过Hololens拍照。我想使用Vuforia Engine ARCamera在我看到我创建的AR-GUI(未来的功能)的同时看到现实的可能性。
我得到的主要错误是:
拍摄照片失败(小时= 0xC00D3704)
它为什么会发生?我如何解决它?
FocusManager单例尚未初始化。 UnityEngine.Debug:Assert(Boolean,String)HoloToolkit.Unity.Singleton`1:AssertIsInitialized()(在Assets / HoloToolkit / Common / Scripts / Singleton.cs:51)HoloToolkit.Unity.CanvasHelper:Start()(在Assets / HoloToolkit /工具/脚本/ CanvasHelper.cs:30)
在开始统一场景时也会发生错误,但我之前没有...
这是我正在使用的代码,放在ARCamera上(还尝试了带有vuforia行为脚本的混合现实相机,它没有得到第二个错误)。此外,我想向借用此代码的人道歉,因为我不记得您网站的链接。
public class PhotoCaptureExample : MonoBehaviour
{
PhotoCapture photoCaptureObject = null;
Texture2D targetTexture = null;
public string path = "";
CameraParameters cameraParameters = new CameraParameters();
void Start()
{
}
void Update()
{
if (Input.GetKeyDown("k"))
{
Debug.Log("k was pressed");
Resolution cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();
targetTexture = new Texture2D(cameraResolution.width, cameraResolution.height);
// Create a PhotoCapture object
PhotoCapture.CreateAsync(false, delegate (PhotoCapture captureObject)
{
photoCaptureObject = captureObject;
cameraParameters.hologramOpacity = 0.0f;
cameraParameters.cameraResolutionWidth = cameraResolution.width;
cameraParameters.cameraResolutionHeight = cameraResolution.height;
cameraParameters.pixelFormat = CapturePixelFormat.BGRA32;
// Activate the camera
photoCaptureObject.StartPhotoModeAsync(cameraParameters, delegate (PhotoCapture.PhotoCaptureResult result)
{
// Take a picture
photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
});
});
}
}
string FileName(int width, int height)
{
return string.Format("screen_{0}x{1}_{2}.png", width, height, DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"));
}
void OnCapturedPhotoToMemory(PhotoCapture.PhotoCaptureResult result, PhotoCaptureFrame photoCaptureFrame)
{
// Copy the raw image data into the target texture
photoCaptureFrame.UploadImageDataToTexture(targetTexture);
Resolution cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();
targetTexture.ReadPixels(new Rect(0, 0, cameraResolution.width, cameraResolution.height), 0, 0);
targetTexture.Apply();
byte[] bytes = targetTexture.EncodeToPNG();
string filename = FileName(Convert.ToInt32(targetTexture.width), Convert.ToInt32(targetTexture.height));
//save to folder under assets
File.WriteAllBytes(Application.dataPath + "/Snapshots/" + filename, bytes);
Debug.Log("The picture was uploaded");
// Deactivate the camera
photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
}
void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
{
// Shutdown the photo capture resource
photoCaptureObject.Dispose();
photoCaptureObject = null;
}
}
似乎我无法访问OnCapturedPhotoToMemory
或者它是否已经被方法调用打破了。现在再试一次,代码偶尔也不会注册,我已经推动了k
......
任何帮助表示赞赏!!
问题是:相机上的Vuforia的VuforiaBehaviour
可以访问设备真正的相机硬件=>其他任何东西都不能同时使用它。
为了解决这个问题,你可以使用Vuforia的专用相机(只需在场景中放置一个新的GameObject,例如VuforiaCamera
,并附加一个Camera
组件以及一个VuforiaBehaviour
。
在Vuforia相机上设置Culling Mask
到Nothing
(我们不用那个相机渲染任何东西)和Depth
到例如-2
(较高的值呈现在顶部 - >将其置于所有其他相机之后)。
你必须这样做,因为否则Vuforia会自动将它添加到主摄像头(我们不想禁用它,因为我们没有看到任何东西)。通过手动将一个添加到场景中,Vuforia会自动使用该场景。
在您需要摄像机的场景中,您可以使用Holo-Tookit的原始相机(通常的MainCamera
)。问题你不能完全依赖于脚本中的Camera.main
,因为在运行时VuforiaBehaviour
自动将其Camera
标记为MainCamera
...( - _-)Vuforia ...所以另外我总是禁用并启用VuforiaBehaviour
以及GameObject但是也许已经足够只能禁用和启用GameObject。至少在GameStart它应该被禁用我猜,直到所有依赖Camera.main
完成。
然后你可以简单地禁用那个有VuforiaCamera
的VuforiaBehaviour
。
VuforiaBehaviour.Instance.gameObject.SetActive(false);
// Note: that part I'm just inventing since I did it different
// using reference etc. I hope vuforia does not destroy the Instance
// OnDisable .. otherwise you would need the reference instead of using Instance here
// but maybe it is already enough to just enable and disable the GameObject
VuforiaBehaviour.Instance.enabled = false;
通过这样做,设备的相机是“免费的”,PhotoCapture现在可以使用它。
PhotoCapture.StartPhotoModeAsync(....
如果您再次需要相机用于vuforia,请先停止PhotoCapture
PhotoCapture.StopPhotoModeAsync(..
然后在回调中停止后再次启用ARCamera
(VuforiaBehaviour
的对象)和VuforiaBehaviour
。
就像是
private void Awake()
{
var cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();
targetTexture = new Texture2D(cameraResolution.width, cameraResolution.height);
// Create a PhotoCapture object
PhotoCapture.CreateAsync(false, captureObject =>
{
photoCaptureObject = captureObject;
cameraParameters.hologramOpacity = 0.0f;
cameraParameters.cameraResolutionWidth = cameraResolution.width;
cameraParameters.cameraResolutionHeight = cameraResolution.height;
cameraParameters.pixelFormat = CapturePixelFormat.BGRA32;
});
}
private void Update()
{
// if not initialized yet don't take input
if (photoCaptureObject == null) return;
if (Input.GetKeyDown("k"))
{
Debug.Log("k was pressed");
VuforiaBehaviour.Instance.gameObject.SetActive(false);
// Activate the camera
photoCaptureObject.StartPhotoModeAsync(cameraParameters, result =>
{
if (result.success)
{
// Take a picture
photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
}
else
{
Debug.LogError("Couldn't start photo mode!", this);
}
});
}
}
private static string FileName(int width, int height)
{
return $"screen_{width}x{height}_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.png";
}
private void OnCapturedPhotoToMemory(PhotoCapture.PhotoCaptureResult result, PhotoCaptureFrame photoCaptureFrame)
{
// Copy the raw image data into the target texture
photoCaptureFrame.UploadImageDataToTexture(targetTexture);
Resolution cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();
targetTexture.ReadPixels(new Rect(0, 0, cameraResolution.width, cameraResolution.height), 0, 0);
targetTexture.Apply();
byte[] bytes = targetTexture.EncodeToPNG();
string filename = FileName(Convert.ToInt32(targetTexture.width), Convert.ToInt32(targetTexture.height));
//save to folder under assets
File.WriteAllBytes(Application.streamingAssetsPath + "/Snapshots/" + filename, bytes);
Debug.Log("The picture was uploaded");
// Deactivate the camera
photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
}
private void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
{
// Shutdown the photo capture resource
photoCaptureObject.Dispose();
photoCaptureObject = null;
VuforiaBehaviour.Instance.gameObject.SetActive(true);
}
然而,例外也可能与this issue有关。