Delen via


Fotovideocamera in Unity

De mogelijkheid voor cameratoegang inschakelen

De functie 'WebCam' moet worden gedeclareerd voor een app om de camera te kunnen gebruiken.

  1. Ga in de Unity Editor naar de spelerinstellingen door naar de pagina Projectinstellingen > player bewerken > te gaan
  2. Selecteer het tabblad Windows Store
  3. 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:

  1. Een PhotoCapture-object maken
  2. Een CameraParameters-object maken met de gewenste instellingen
  3. Fotomodus starten via StartPhotoModeAsync
  4. Maak de gewenste foto
    • (optioneel) Interactie met die afbeelding
  5. 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:

  1. Een VideoCapture-object maken
  2. Een CameraParameters-object maken met de gewenste instellingen
  3. Videomodus starten via StartVideoModeAsync
  4. Opnamevideo starten
  5. Opnamevideo stoppen
  6. 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 .

Zie ook