【发布时间】:2019-03-27 13:04:21
【问题描述】:
正如标题所暗示的那样,我在行发生错误时遇到了问题
targetTexture.ReadPixels(new Rect(0, 0, cameraResolution.width, cameraResolution.height), 0, 0);
错误:
ReadPixels 被调用以从系统帧缓冲区中读取像素,而 不在绘图框内。 UnityEngine.Texture2D:ReadPixels(矩形, Int32, Int32)
正如我从其他帖子中了解到的那样,解决此问题的一种方法是创建一个 Ienumerator 方法,该方法产生 return new WaitForSeconds 或其他内容,并将其称为:StartCoroutine(methodname) 以便及时加载帧,以便有将是像素来读取。
我不明白的是在下面的代码中,这种方法最有意义的地方。哪个部分没有及时加载?
PhotoCapture photoCaptureObject = null;
Texture2D targetTexture = null;
public string path = "";
CameraParameters cameraParameters = new CameraParameters();
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.GetKey("k") || Input.GetKey("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
VuforiaBehaviour.Instance.gameObject.SetActive(true);
photoCaptureObject.Dispose();
photoCaptureObject = null;
}
对不起,如果这被视为与 this 重复。
编辑
当我达到这一点时,this 可能会有用。
是不是我根本不需要这三行?
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();
正如 cmets 中所写,使用这三行与不使用这三行的区别在于保存的照片具有黑色背景 + AR-GUI。上面没有第二行代码的是一张带有 AR-GUI 的照片,但背景是我电脑网络摄像头的实时流。我真的不想看到计算机网络摄像头,而是看到 HoloLens 看到的。
【问题讨论】:
-
等一下你要在那里做什么?
targetTexture.ReadPixels(new Rect(0, 0, cameraResolution.width, cameraResolution.height), 0, 0);(尝试)制作屏幕截图 ..因此您必须等到帧结束,所以所有内容都已渲染...您是否真的要制作屏幕截图并覆盖您的纹理用拍照功能拍照后? -
嗯,@derHugo 听起来有点不必要,是 readPixels 行上方的行设置了
cameraResolution吗? (老实说,我想最后从中心裁剪捕获的照片,我想也许这可以用这个代码行来实现?从 0、0 以外的其他像素开始新的矩形) -
不,我的意思是 3 行代码
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();对我来说毫无意义...您尝试用屏幕截图覆盖刚刚从照片捕获中收到的纹理...(并且 cameraResolution 也是设备相机的分辨率不是屏幕分辨率顺便说一句)。裁剪纹理到底需要什么? -
@FearlessFox 我不知道,但我想你可以,但它可能真的很复杂。 HoloLens 有它的设备门户,它提供对设备相机(但包括全息图)的访问。另外我不知道它是否允许您通过套接字或Serial Port 访问它。但最好是直接在设备上部署和测试,而在 PC 上使用网络摄像头代替。