Фото- и видеокамера в Unity
Включение возможности доступа к камере
Возможность WebCam должна быть объявлена для приложения, чтобы использовать камеру.
- В редакторе Unity перейдите к параметрам проигрывателя, перейдя на страницу "Изменить > проигрыватель параметров > проекта"
- Перейдите на вкладку "Магазин Windows"
- В разделе "Возможности публикации параметров>" проверьте возможности веб-камеры и микрофона
Одновременно с камерой может выполняться только одна операция. Вы можете проверить, в каком режиме камера находится в настоящее время в UnityEngine.XR.WSA.WebCam.Mode
Unity 2018 и более ранних версиях или UnityEngine.Windows.WebCam.Mode
в Unity 2019 и более поздних версий. Доступные режимы: фото, видео или нет.
Фотосъемка
Пространство имен (до Unity 2019): UnityEngine.XR.WSA.WebCam
Пространство имен (Unity 2019 и более поздние версии): UnityEngine.Windows.WebCam
Тип: PhotoCapture
Тип PhotoCapture позволяет сфотографироваться с камерой фото. Общий шаблон использования PhotoCapture для создания фотографии выглядит следующим образом:
- Создание объекта PhotoCapture
- Создание объекта CameraParameters с нужными параметрами
- Запуск режима фотографии с помощью StartPhotoModeAsync
- Сделайте фотографию, которую вы хотите
- (необязательно) Взаимодействие с этим рисунком
- Остановка режима фото и очистка ресурсов
Общая настройка для PhotoCapture
Для всех трех используется, начните с одного и того же первого трех шагов выше
Начните с создания объекта PhotoCapture
private void Start()
{
PhotoCapture.CreateAsync(false, OnPhotoCaptureCreated);
}
Затем сохраните объект, задайте параметры и запустите режим фото
private PhotoCapture photoCaptureObject = null;
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, false, OnPhotoModeStarted);
}
В конце концов вы также будете использовать тот же код очистки, представленный здесь.
void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
{
photoCaptureObject.Dispose();
photoCaptureObject = null;
}
После выполнения этих действий можно выбрать тип фотографии для записи.
Запись фотографии в файл
Простейшая операция заключается в том, чтобы записать фотографию непосредственно в файл. Фотографию можно сохранить в формате JPG или PNG.
Если вы успешно запустили режим фотографии, сделайте фотографию и сохраните ее на диске
private void OnPhotoModeStarted(PhotoCapture.PhotoCaptureResult result)
{
if (result.success)
{
string filename = string.Format(@"CapturedImage{0}_n.jpg", Time.time);
string filePath = System.IO.Path.Combine(Application.persistentDataPath, filename);
photoCaptureObject.TakePhotoAsync(filePath, PhotoCaptureFileOutputFormat.JPG, OnCapturedPhotoToDisk);
}
else
{
Debug.LogError("Unable to start photo mode!");
}
}
После записи фотографии на диск выйдите из режима фотографии, а затем очистите объекты
void OnCapturedPhotoToDisk(PhotoCapture.PhotoCaptureResult result)
{
if (result.success)
{
Debug.Log("Saved Photo to disk!");
photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
}
else
{
Debug.Log("Failed to save Photo to disk");
}
}
Запись фотографии в Текстур2D с расположением
При записи данных в Текстур2D процесс аналогичен захвату на диск.
Следуйте приведенному выше процессу установки.
В OnPhotoModeStarted зафиксировать кадр в память.
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);
}
Камера с определяемым местоположением
Чтобы поместить эту текстуру в сцену и отобразить ее с помощью матриц камеры с неуловимыми, добавьте следующий код в OnCapturedPhotoToMemory в проверке result.success
:
if (photoCaptureFrame.hasLocationData)
{
photoCaptureFrame.TryGetCameraToWorldMatrix(out Matrix4x4 cameraToWorldMatrix);
Vector3 position = cameraToWorldMatrix.GetColumn(3) - cameraToWorldMatrix.GetColumn(2);
Quaternion rotation = Quaternion.LookRotation(-cameraToWorldMatrix.GetColumn(2), cameraToWorldMatrix.GetColumn(1));
photoCaptureFrame.TryGetProjectionMatrix(Camera.main.nearClipPlane, Camera.main.farClipPlane, out Matrix4x4 projectionMatrix);
}
Unity предоставил пример кода для применения матрицы проекции к определенному шейдеру на своих форумах.
Запись фотографии и взаимодействие с необработанными байтами
Чтобы взаимодействовать с необработанными байтами кадра памяти, выполните те же действия по настройке, что и в OnPhotoModeStarted , как при записи фотографии в Texture2D. Разница в OnCapturedPhotoToMemory , где можно получить необработанные байты и взаимодействовать с ними.
В этом примере вы создадите список для дальнейшей обработки или применения к текстуре с помощью SetPixels()
void OnCapturedPhotoToMemory(PhotoCapture.PhotoCaptureResult result, PhotoCaptureFrame photoCaptureFrame)
{
if (result.success)
{
List<byte> imageBufferList = new List<byte>();
// Copy the raw IMFMediaBuffer data into our empty byte list.
photoCaptureFrame.CopyRawImageDataIntoBuffer(imageBufferList);
// In this example, we captured the image using the BGRA32 format.
// So our stride will be 4 since we have a byte for each rgba channel.
// The raw image data will also be flipped so we access our pixel data
// in the reverse order.
int stride = 4;
float denominator = 1.0f / 255.0f;
List<Color> colorArray = new List<Color>();
for (int i = imageBufferList.Count - 1; i >= 0; i -= stride)
{
float a = (int)(imageBufferList[i - 0]) * denominator;
float r = (int)(imageBufferList[i - 1]) * denominator;
float g = (int)(imageBufferList[i - 2]) * denominator;
float b = (int)(imageBufferList[i - 3]) * denominator;
colorArray.Add(new Color(r, g, b, a));
}
// Now we could do something with the array such as texture.SetPixels() or run image processing on the list
}
photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
}
Запись видео
Пространство имен (до Unity 2019): UnityEngine.XR.WSA.WebCam
Пространство имен (Unity 2019 и более поздние версии): UnityEngine.Windows.WebCam
Тип: VideoCapture
Функции VideoCapture аналогично PhotoCapture. Единственными двумя различиями являются то, что необходимо указать значение кадров в секунду (FPS), и вы можете сохранить только непосредственно на диск в виде файла .mp4. Ниже приведены действия по использованию VideoCapture .
- Создание объекта VideoCapture
- Создание объекта CameraParameters с нужными параметрами
- Запуск режима видео с помощью StartVideoModeAsync
- Начать запись видео
- Остановка записи видео
- Остановка режима видео и очистка ресурсов
Начните с создания объекта VideoCapture VideoCapture m_VideoCapture = null;
void Start ()
{
VideoCapture.CreateAsync(false, OnVideoCaptureCreated);
}
Затем настройте параметры для записи и запуска.
void OnVideoCaptureCreated(VideoCapture videoCapture)
{
if (videoCapture != null)
{
m_VideoCapture = videoCapture;
Resolution cameraResolution = VideoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();
float cameraFramerate = VideoCapture.GetSupportedFrameRatesForResolution(cameraResolution).OrderByDescending((fps) => fps).First();
CameraParameters cameraParameters = new CameraParameters();
cameraParameters.hologramOpacity = 0.0f;
cameraParameters.frameRate = cameraFramerate;
cameraParameters.cameraResolutionWidth = cameraResolution.width;
cameraParameters.cameraResolutionHeight = cameraResolution.height;
cameraParameters.pixelFormat = CapturePixelFormat.BGRA32;
m_VideoCapture.StartVideoModeAsync(cameraParameters,
VideoCapture.AudioState.None,
OnStartedVideoCaptureMode);
}
else
{
Debug.LogError("Failed to create VideoCapture Instance!");
}
}
После запуска начните запись
void OnStartedVideoCaptureMode(VideoCapture.VideoCaptureResult result)
{
if (result.success)
{
string filename = string.Format("MyVideo_{0}.mp4", Time.time);
string filepath = System.IO.Path.Combine(Application.persistentDataPath, filename);
m_VideoCapture.StartRecordingAsync(filepath, OnStartedRecordingVideo);
}
}
После начала записи можно обновить пользовательский интерфейс или поведение, чтобы включить остановку. Здесь вы только зайдите в журнал.
void OnStartedRecordingVideo(VideoCapture.VideoCaptureResult result)
{
Debug.Log("Started Recording Video!");
// We will stop the video from recording via other input such as a timer or a tap, etc.
}
В более позднюю точку необходимо остановить запись с помощью таймера или ввода пользователя, например.
// The user has indicated to stop recording
void StopRecordingVideo()
{
m_VideoCapture.StopRecordingAsync(OnStoppedRecordingVideo);
}
После остановки записи остановите режим видео и очистите ресурсы.
void OnStoppedRecordingVideo(VideoCapture.VideoCaptureResult result)
{
Debug.Log("Stopped Recording Video!");
m_VideoCapture.StopVideoModeAsync(OnStoppedVideoCaptureMode);
}
void OnStoppedVideoCaptureMode(VideoCapture.VideoCaptureResult result)
{
m_VideoCapture.Dispose();
m_VideoCapture = null;
}
Устранение неполадок
- Нет доступных разрешений
- Убедитесь, что в проекте указана возможность WebCam .
Следующий этап разработки
Если вы следите за этапом разработки Unity, который мы изложили, вы находитесь в разгар изучения возможностей платформы Смешанная реальность и API. Вы можете перейти к следующей статье:
Или сразу перейдите к развертыванию приложения на устройстве или эмуляторе:
Вы можете в любой момент вернуться к этапам разработки для Unity.