#c# #unity3d
#c# #unity3d
Вопрос:
Я могу сделать одну фотографию с помощью этого скрипта. Как я должен изменить этот скрипт для непрерывной съемки фотографий, чтобы отображать их в 3D плоскости? Я хочу постоянно передавать эту «targetTexture» некоторой функции.
public class PhotoCaptureExample : MonoBehaviour
{
PhotoCapture photoCaptureObject = null;
// Use this for initialization
void Start ()
{
PhotoCapture.CreateAsync(false, OnPhotoCaptureCreated);
}
void OnPhotoCaptureCreated(PhotoCapture captureObject)
{
photoCaptureObject = captureObject;
Resolution cameraResolution = PhotoCapture.SupportedResolutions
.OrderByDescending((res) => res.width * res.height).First();
CameraParameters c = new CameraParameters();
c.hologramOpacity = 0.0f;
c.cameraResolutionWidth = cameraResolution.width;
c.cameraResolutionHeight = cameraResolution.height;
c.pixelFormat = CapturePixelFormat.BGRA32;
captureObject.StartPhotoModeAsync(c, OnPhotoModeStarted);
}
void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
{
photoCaptureObject.Dispose();
photoCaptureObject = null;
}
private void OnPhotoModeStarted(PhotoCapture.PhotoCaptureResult result)
{
if (result.success)
{
photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
}
else
{
Debug.LogError("Unable to start photo mode!");
}
}
void OnCapturedPhotoToMemory(PhotoCapture.PhotoCaptureResult result,
PhotoCaptureFrame photoCaptureFrame)
{
if (result.success)
{
// Create our Texture2D for use and set the correct resolution
Resolution cameraResolution = PhotoCapture.SupportedResolutions
.OrderByDescending((res) => res.width * res.height).First();
Texture2D targetTexture = new Texture2D(cameraResolution.width,
cameraResolution.height);
// Copy the raw image data into our target texture
photoCaptureFrame.UploadImageDataToTexture(targetTexture);
// Do as we wish with the texture such as apply it to a material, etc.
}
// Clean up
photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
}
// Update is called once per frame
void Update ()
{
}
}
Комментарии:
1. Возможно, это звучит как-то связано gamedev.stackexchange.com/q/158518/99708
Ответ №1:
Afaik вы не можете создавать новый TakePhotoAsync
вызов для каждого кадра, но должны дождаться завершения текущего процесса. Это требует высокой производительности, и afaik также получает эксклюзивное разрешение на доступ к устройству камеры, поэтому любой другой вызов тем временем завершается неудачей.
Чтобы подождать со следующей фотографией до тех пор, пока одна из них не будет завершена в OnCapturedPhotoToMemory
, вы могли бы просто вместо
photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
вызовите следующую фотографию
photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
Возможно, вам следует добавить условие выхода прямо перед ним, как private bool shouldStop
подобное
if(shouldStop)
{
photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
}
else
{
photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
}
Однако имейте в виду, что это значительно замедлит работу вашего приложения! Поскольку большая часть Texture2D
работы происходит в основном потоке и требует довольно высокой производительности!
Ответ №2:
Это далеко от совершенства, и я не тестировал это, но что-то вроде этого должно сработать. Однако вам может понадобиться цикл while внутри метода async void, чтобы он не замораживал ваше приложение.
public class PhotoCaptureExample : MonoBehaviour
{
PhotoCapture photoCaptureObject = null;
bool capturing = false;
// Use this for initialization
void Start ()
{
PhotoCapture.CreateAsync(false, OnPhotoCaptureCreated);
}
void OnPhotoCaptureCreated(PhotoCapture captureObject)
{
photoCaptureObject = captureObject;
Resolution cameraResolution = PhotoCapture.SupportedResolutions
.OrderByDescending((res) => res.width * res.height).First();
CameraParameters c = new CameraParameters();
c.hologramOpacity = 0.0f;
c.cameraResolutionWidth = cameraResolution.width;
c.cameraResolutionHeight = cameraResolution.height;
c.pixelFormat = CapturePixelFormat.BGRA32;
captureObject.StartPhotoModeAsync(c, OnPhotoModeStarted);
}
void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
{
photoCaptureObject.Dispose();
photoCaptureObject = null;
}
private void OnPhotoModeStarted(PhotoCapture.PhotoCaptureResult result)
{
if (result.success)
{
capturing = true
while(capturing)
{
try
{
photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
}
catch (Exception e)
{
// Do something
capturing = false;
// Clean up
photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
}
}
}
else
{
Debug.LogError("Unable to start photo mode!");
}
}
void OnCapturedPhotoToMemory(PhotoCapture.PhotoCaptureResult result,
PhotoCaptureFrame photoCaptureFrame)
{
if (result.success)
{
// Create our Texture2D for use and set the correct resolution
Resolution cameraResolution = PhotoCapture.SupportedResolutions
.OrderByDescending((res) => res.width * res.height).First();
Texture2D targetTexture = new Texture2D(cameraResolution.width,
cameraResolution.height);
// Copy the raw image data into our target texture
photoCaptureFrame.UploadImageDataToTexture(targetTexture);
// Do as we wish with the texture such as apply it to a material, etc.
}
}
// Update is called once per frame
void Update ()
{
if(!capturing)
{
// to ensure the photos are continuously being captured
Start();
}
}
}
Комментарии:
1. Возможно, вы захотите еще раз взглянуть на код. Он создает photoCaptureObject один раз. Затем устанавливает для захвата значение true и запускает цикл while. Это останавливает захват и удаляет photoCaptureObject только в случае исключения. Тогда метод Update вызывает его для повторного запуска только в том случае, если значение capture равно false. Что означало бы, что возникло исключение. Я что-то упускаю?
2. Да, извините, только что понял это 😉 проблема в любом случае: Afaik TakePhotoAsync будет сохранять эксклюзивное разрешение на чтение на устройстве, поэтому я думаю, что вам всегда нужно дождаться завершения одного процесса съемки, прежде чем начинать новый, и вы не сможете отправлять фотоснимки в спам с заданием takePhoto в каждом кадре.. в любом случае, определенно не в
while
цикле!