Appareil photo et caméra vidéo dans Unity
Activation de la fonctionnalité d’accès à la caméra
La fonctionnalité « WebCam » doit être déclarée pour qu’une application utilise la caméra.
- Dans l’Éditeur Unity, accédez aux paramètres du lecteur en accédant à la page « Modifier > le lecteur des paramètres > du projet ».
- Sélectionnez l’onglet « Windows Store »
- Dans la section « Fonctionnalités des paramètres > de publication », consultez les fonctionnalités webCam et Microphone
Une seule opération peut se produire avec la caméra à la fois. Vous pouvez vérifier le mode avec lequel la caméra est actuellement activée UnityEngine.XR.WSA.WebCam.Mode
dans Unity 2018 et versions antérieures ou UnityEngine.Windows.WebCam.Mode
dans Unity 2019 et versions ultérieures. Les modes disponibles sont photo, vidéo ou aucun.
Capture de photos
Espace de noms (avant Unity 2019) : UnityEngine.XR.WSA.WebCam
Espace de noms (Unity 2019 et versions ultérieures) : UnityEngine.Windows.WebCam
Type : PhotoCapture
Le type PhotoCapture vous permet de prendre des photos avec l’appareil photo photo. Le modèle général d’utilisation de PhotoCapture pour prendre une photo est le suivant :
- Créer un objet PhotoCapture
- Créer un objet CameraParameters avec les paramètres souhaités
- Démarrer le mode photo via StartPhotoModeAsync
- Prenez la photo souhaitée
- (facultatif) Interagir avec cette image
- Arrêter le mode photo et nettoyer les ressources
Configuration commune pour PhotoCapture
Pour les trois utilisations, commencez par les trois premières étapes ci-dessus
Commencer par créer un objet PhotoCapture
private void Start()
{
PhotoCapture.CreateAsync(false, OnPhotoCaptureCreated);
}
Ensuite, stockez votre objet, définissez vos paramètres et démarrez le mode Photo
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);
}
À la fin, vous allez également utiliser le même code de nettoyage présenté ici
void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
{
photoCaptureObject.Dispose();
photoCaptureObject = null;
}
Après ces étapes, vous pouvez choisir le type de photo à capturer.
Capture d’une photo dans un fichier
L’opération la plus simple consiste à capturer une photo directement dans un fichier. La photo peut être enregistrée en tant que JPG ou PNG.
Si vous avez démarré le mode photo, prenez une photo et stockez-la sur le disque
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!");
}
}
Après avoir capturé la photo sur disque, quittez le mode photo, puis nettoyez vos objets
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");
}
}
Capturer une photo dans une texture2D avec emplacement
Lors de la capture de données dans une texture2D, le processus est similaire à la capture sur disque.
Suivez le processus d’installation ci-dessus.
Dans OnPhotoModeStarted, capturez un frame en mémoire.
private void OnPhotoModeStarted(PhotoCapture.PhotoCaptureResult result)
{
if (result.success)
{
photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
}
else
{
Debug.LogError("Unable to start photo mode!");
}
}
Vous allez ensuite appliquer votre résultat à une texture et utiliser le code de nettoyage courant ci-dessus.
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);
}
Appareil photo localisable
Pour placer cette texture dans la scène et l’afficher à l’aide des matrices de caméra locatables, ajoutez le code suivant à OnCapturedPhotoToMemory dans la result.success
vérification :
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 a fourni un exemple de code pour appliquer la matrice de projection à un nuanceur spécifique sur leurs forums.
Capturer une photo et interagir avec les octets bruts
Pour interagir avec les octets bruts d’une trame mémoire, suivez les mêmes étapes de configuration que ci-dessus et OnPhotoModeStarted comme lors de la capture d’une photo sur une texture2D. La différence est dans OnCapturedPhotoToMemory où vous pouvez obtenir les octets bruts et interagir avec eux.
Dans cet exemple, vous allez créer une liste à traiter ou appliquer à une texture via 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);
}
Capture vidéo
Espace de noms (avant Unity 2019) : UnityEngine.XR.WSA.WebCam
Espace de noms (Unity 2019 et versions ultérieures) : UnityEngine.Windows.WebCam
Type : VideoCapture
VideoCapture fonctionne de la même façon que PhotoCapture. Les deux seules différences sont que vous devez spécifier une valeur frames par seconde (FPS) et vous ne pouvez enregistrer directement sur le disque qu’en tant que fichier .mp4. Les étapes à suivre pour utiliser VideoCapture sont les suivantes :
- Créer un objet VideoCapture
- Créer un objet CameraParameters avec les paramètres souhaités
- Démarrer le mode vidéo via StartVideoModeAsync
- Démarrer l’enregistrement vidéo
- Arrêter l’enregistrement vidéo
- Arrêter le mode vidéo et nettoyer les ressources
Commencez par créer notre objet VideoCapture VideoCapture m_VideoCapture = null ;
void Start ()
{
VideoCapture.CreateAsync(false, OnVideoCaptureCreated);
}
Ensuite, configurez les paramètres souhaités pour l’enregistrement et démarrez.
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!");
}
}
Une fois démarré, commencez l’enregistrement
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);
}
}
Une fois l’enregistrement démarré, vous pouvez mettre à jour votre interface utilisateur ou vos comportements pour activer l’arrêt. Ici, vous venez de vous connecter.
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.
}
À un stade ultérieur, vous souhaiterez arrêter l’enregistrement à l’aide d’un minuteur ou d’une entrée utilisateur, par exemple.
// The user has indicated to stop recording
void StopRecordingVideo()
{
m_VideoCapture.StopRecordingAsync(OnStoppedRecordingVideo);
}
Une fois l’enregistrement arrêté, arrêtez le mode vidéo et nettoyez vos ressources.
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;
}
Dépannage
- Aucune résolution n’est disponible
- Vérifiez que la fonctionnalité WebCam est spécifiée dans votre projet.
Point de contrôle de développement suivant
Si vous suivez le parcours de point de contrôle de développement Unity que nous avons mis en place, vous êtes en train d’explorer les fonctionnalités et LES API de plateforme de réalité mixte. À partir d’ici, vous pouvez passer au sujet suivant :
Ou accéder directement au déploiement de votre application sur un appareil ou un émulateur :
Vous pouvez revenir aux points de contrôle de développement Unity à tout moment.