Share via


Fotovideocamera in Unity

De mogelijkheid voor cameratoegang inschakelen

De mogelijkheid '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 > speler bewerken>' te gaan
  2. Selecteer het tabblad 'Windows Store'
  3. Controleer in de sectie Mogelijkheden voor publicatie-instellingen > de mogelijkheden van de webcam en microfoon

Er kan slechts één bewerking tegelijk met de camera worden uitgevoerd. 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 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 foto's maken met de fotovideocamera. 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. De gewenste foto maken
    • (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 om een foto rechtstreeks in een bestand vast te leggen. De foto kan worden opgeslagen als JPG- of PNG-bestand.

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 vervolgens uw 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 naar een Texture2D is het proces vergelijkbaar met het vastleggen 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 het resultaat toe op een patroon en gebruikt u de algemene opschoningscode hierboven.

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 cameramatrices, voegt u de volgende code toe aan OnCapturedPhotoToMemory in het result.success vinkje:

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 arcering op hun forums.

Een foto vastleggen en werken met de onbewerkte bytes

Als u wilt communiceren met de onbewerkte bytes van een in het geheugenframe, volgt u dezelfde installatiestappen als hierboven en OnPhotoModeStarted als bij het vastleggen van een foto op een Texture2D. Het verschil zit in OnCapturedPhotoToMemory , waar u de onbewerkte bytes kunt ophalen en ermee kunt werken.

In dit voorbeeld maakt u een lijst die verder moet worden verwerkt of toegepast op een patroon 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);
}

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. Video-opname starten
  5. Stoppen met het opnemen van video
  6. Videomodus stoppen en resources opschonen

Begin met het maken van het VideoCapture-objectVideoCapture m_VideoCapture = null;

void Start ()
{
    VideoCapture.CreateAsync(false, OnVideoCaptureCreated);
}

Stel vervolgens de gewenste parameters in 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.

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 de opname stoppen met behulp van bijvoorbeeld 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;
}

Problemen oplossen

  • Er zijn geen resoluties beschikbaar
    • Zorg ervoor dat de webcam-mogelijkheid is opgegeven in uw project.

Volgend controlepunt voor ontwikkeling

Als u het traject van het controlepunt voor Unity-ontwikkeling volgt, bent u bezig met het verkennen van de mogelijkheden en API's van het Mixed Reality-platform. Vanaf 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-ontwikkelcontrolepunten .

Zie ook