Fotovideocamera in Unity
De mogelijkheid voor cameratoegang inschakelen
De functie 'WebCam' moet worden gedeclareerd voor een app om de camera te kunnen gebruiken.
- Ga in de Unity Editor naar de spelerinstellingen door naar de pagina Projectinstellingen > player bewerken > te gaan
- Selecteer het tabblad Windows Store
- Controleer in de sectie Publicatie-instellingen > de mogelijkheden van WebCam en Microfoon
Er kan slechts één bewerking tegelijk plaatsvinden met de camera. U kunt controleren in welke modus de camera zich momenteel bevindt UnityEngine.XR.WSA.WebCam.Mode
in Unity 2018 en eerder of UnityEngine.Windows.WebCam.Mode
in Unity 2019 en hoger. Beschikbare modi zijn foto, video of geen.
Foto's vastleggen
Naamruimte (vóór Unity 2019): UnityEngine.XR.WSA.WebCam
Naamruimte (Unity 2019 en hoger): UnityEngine.Windows.WebCam
Type: PhotoCapture
Met het type PhotoCapture kunt u nog steeds foto's maken met de fotocamera. Het algemene patroon voor het gebruik van PhotoCapture om een foto te maken is als volgt:
- Een PhotoCapture-object maken
- Een CameraParameters-object maken met de gewenste instellingen
- Fotomodus starten via StartPhotoModeAsync
- Maak de gewenste foto
- (optioneel) Interactie met die afbeelding
- Fotomodus stoppen en resources opschonen
Algemene instellingen voor PhotoCapture
Voor alle drie de toepassingen begint u met dezelfde eerste drie stappen hierboven
Begin met het maken van een PhotoCapture-object
private void Start()
{
PhotoCapture.CreateAsync(false, OnPhotoCaptureCreated);
}
Sla vervolgens uw object op, stel uw parameters in en start de fotomodus
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);
}
Uiteindelijk gebruikt u ook dezelfde opschooncode die hier wordt weergegeven
void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
{
photoCaptureObject.Dispose();
photoCaptureObject = null;
}
Na deze stappen kunt u kiezen welk type foto u wilt vastleggen.
Een foto vastleggen in een bestand
De eenvoudigste bewerking is het rechtstreeks vastleggen van een foto in een bestand. De foto kan worden opgeslagen als JPG of PNG.
Als u de fotomodus hebt gestart, maakt u een foto en slaat u deze op schijf op
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!");
}
}
Nadat u de foto op schijf hebt vastgelegd, sluit u de fotomodus af en schoont u de objecten op
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");
}
}
Een foto vastleggen op een Texture2D met locatie
Bij het vastleggen van gegevens in een Texture2D is het proces vergelijkbaar met het vastleggen van gegevens op schijf.
Volg het bovenstaande installatieproces.
Leg in OnPhotoModeStarted een frame vast in het geheugen.
private void OnPhotoModeStarted(PhotoCapture.PhotoCaptureResult result)
{
if (result.success)
{
photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
}
else
{
Debug.LogError("Unable to start photo mode!");
}
}
Vervolgens past u uw resultaat toe op een patroon en gebruikt u de bovenstaande algemene opschoningscode.
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);
}
Locatable camera
Als u dit patroon in de scène wilt plaatsen en wilt weergeven met behulp van de matrices van de locatable camera, voegt u de volgende code toe aan OnCapturedPhotoToMemory in de result.success
controle:
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 heeft voorbeeldcode verstrekt voor het toepassen van de projectiematrix op een specifieke shader op hun forums.
Een foto vastleggen en werken met de onbewerkte bytes
Als u wilt communiceren met de onbewerkte bytes van een geheugenframe, volgt u dezelfde installatiestappen als hierboven en OnPhotoModeStarted als bij het vastleggen van een foto in een Texture2D. Het verschil is in OnCapturedPhotoToMemory , waar u de onbewerkte bytes kunt ophalen en ermee kunt werken.
In dit voorbeeld maakt u een lijst om verder te worden verwerkt of toegepast op een patroon via Set Pixels()
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);
}
Video-opname
Naamruimte (vóór Unity 2019): UnityEngine.XR.WSA.WebCam
Naamruimte (Unity 2019 en hoger): UnityEngine.Windows.WebCam
Type: VideoCapture
VideoCapture werkt op dezelfde manier als PhotoCapture. De enige twee verschillen zijn dat u een fps-waarde (frames per seconde) moet opgeven en u alleen rechtstreeks op schijf kunt opslaan als een .mp4 bestand. De stappen voor het gebruik van VideoCapture zijn als volgt:
- Een VideoCapture-object maken
- Een CameraParameters-object maken met de gewenste instellingen
- Videomodus starten via StartVideoModeAsync
- Opnamevideo starten
- Opnamevideo stoppen
- Videomodus stoppen en resources opschonen
Begin met het maken van ons VideoCapture-object VideoCapture m_VideoCapture = null;
void Start ()
{
VideoCapture.CreateAsync(false, OnVideoCaptureCreated);
}
Stel vervolgens de parameters in die u nodig hebt voor de opname en start.
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!");
}
}
Zodra de opname is gestart, begint u met de opname
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);
}
}
Nadat de opname is gestart, kunt u uw gebruikersinterface of gedrag bijwerken om stoppen in te schakelen. Hier log je gewoon in.
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.
}
Op een later moment wilt u bijvoorbeeld de opname stoppen met behulp van een timer of gebruikersinvoer.
// The user has indicated to stop recording
void StopRecordingVideo()
{
m_VideoCapture.StopRecordingAsync(OnStoppedRecordingVideo);
}
Zodra de opname is gestopt, stopt u de videomodus en schoont u uw resources op.
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;
}
Probleemoplossing
- Er zijn geen oplossingen beschikbaar
- Zorg ervoor dat de WebCam-mogelijkheid is opgegeven in uw project.
Volgend controlepunt voor ontwikkeling
Als u het controlepunt voor Unity-ontwikkeling volgt dat we hebben opgesteld, bevindt u zich midden in het verkennen van de mogelijkheden en API's van het Mixed Reality-platform. Hier kunt u doorgaan naar het volgende onderwerp:
Of ga rechtstreeks naar het implementeren van uw app op een apparaat of emulator:
U kunt altijd op elk gewenst moment teruggaan naar de Unity-ontwikkelingscontrolepunten .