Photo Video kamera a Unityben

Kamera-hozzáférés engedélyezése

A "WebCam" képességet deklarálni kell ahhoz, hogy egy alkalmazás használhassa a kamerát.

  1. A Unity-szerkesztőben lépjen a lejátszóbeállításokra a "Projektbeállítások > lejátszójának szerkesztése>" lapra lépve
  2. Válassza a "Windows Áruház" lapot
  3. A "Közzétételi beállítások > képességei" szakaszban ellenőrizze a WebCam és a Mikrofon képességeit

Egyszerre csak egyetlen művelet történhet a kamerával. A Unity 2018-ban és korábbi verzióiban, illetve UnityEngine.Windows.WebCam.Mode a Unity 2019-ben és újabb verzióiban UnityEngine.XR.WSA.WebCam.Mode ellenőrizheti, hogy a kamera jelenleg melyik üzemmódban van. Az elérhető módok: fénykép, videó vagy nincs.

Fényképfelvétel

Névtér (a Unity 2019 előtt):UnityEngine.XR.WSA.WebCam
Névtér (Unity 2019 és újabb verziók):UnityEngine.Windows.WebCam
Típus:PhotoCapture

A PhotoCapture típus lehetővé teszi, hogy állóképeket készítsen a Fotóvideó kamerával. A PhotoCapture fénykép készítésére való használatának általános mintája a következő:

  1. PhotoCapture objektum létrehozása
  2. CameraParameters objektum létrehozása a kívánt beállításokkal
  3. Fénykép mód indítása a StartPhotoModeAsync használatával
  4. A kívánt fénykép készítése
    • (nem kötelező) A kép használata
  5. Fénykép mód leállítása és erőforrások törlése

A PhotoCapture gyakori beállítása

Mindhárom felhasználási mód esetén kezdje ugyanazzal az első három lépéssel

Első lépésként hozzon létre egy PhotoCapture objektumot

private void Start()
{
    PhotoCapture.CreateAsync(false, OnPhotoCaptureCreated);
}

Ezután tárolja az objektumot, állítsa be a paramétereket, és indítsa el a Fénykép módot

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);
}

Végül ugyanazt a tisztítási kódot fogja használni, amelyet itt is bemutatunk.

void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
{
    photoCaptureObject.Dispose();
    photoCaptureObject = null;
}

A lépések után kiválaszthatja, hogy milyen típusú fényképet szeretne rögzíteni.

Fénykép rögzítése fájlba

A legegyszerűbb művelet egy fénykép rögzítése közvetlenül egy fájlba. A fénykép jpg vagy PNG formátumban menthető.

Ha sikeresen elindította a fénykép módot, készítsen egy fényképet, és tárolja a lemezen

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!");
    }
}

Miután rögzítette a fényképet a lemezre, lépjen ki a fénykép módból, majd törölje az objektumokat

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");
    }
}

Fénykép rögzítése Textúra2D-hez helymeghatározással

Az adatok Texture2D-be való rögzítésekor a folyamat hasonló a lemezhez való rögzítéshez.

Kövesse a fenti beállítási folyamatot.

Az OnPhotoModeStarted fájlban rögzítsen egy keretet a memóriába.

private void OnPhotoModeStarted(PhotoCapture.PhotoCaptureResult result)
{
    if (result.success)
    {
        photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
    }
    else
    {
        Debug.LogError("Unable to start photo mode!");
    }
}

Ezután alkalmazza az eredményt egy anyagmintára, és használja a fenti közös tisztítási kódot.

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 kamera

Ha ezt az anyagmintát a jelenetbe szeretné helyezni, és a lekérhető kameramátricák használatával szeretné megjeleníteni, adja hozzá a következő kódot az OnCapturedPhotoToMemory elemhez az result.success ellenőrzéshez:

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);
}

A Unity mintakódot biztosított a vetítési mátrix egy adott árnyékolóra való alkalmazásához a fórumaikon.

Fénykép rögzítése és a nyers bájtok kezelése

Egy memóriakeret nyers bájtjainak használatához kövesse a fenti beállítási lépéseket és az OnPhotoModeStarted parancsot, mint egy fénykép Texture2D-hez való rögzítéséhez. A különbség az OnCapturedPhotoToMemoryban van, ahol lekérheti a nyers bájtokat, és kezelheti őket.

Ebben a példában létrehoz egy listát, amelyet a SetPixels() használatával további feldolgozásra vagy anyagmintára alkalmaz.

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);
}

Videórögzítés

Névtér (a Unity 2019 előtt):UnityEngine.XR.WSA.WebCam
Névtér (Unity 2019 és újabb verziók):UnityEngine.Windows.WebCam
Típus:VideoCapture

A VideoCapture a PhotoCapture-hez hasonlóan működik. Az egyetlen két különbség az, hogy meg kell adnia egy Frame Per Second (FPS) értéket, és csak .mp4 fájlként menthet közvetlenül a lemezre. A VideoCapture használatának lépései a következők:

  1. VideoCapture-objektum létrehozása
  2. CameraParameters objektum létrehozása a kívánt beállításokkal
  3. Videomód indítása a StartVideoModeAsync használatával
  4. Videó felvételének megkezdése
  5. Videó rögzítésének leállítása
  6. A Videó mód leállítása és az erőforrások törlése

Először hozza létre a VideoCapture objektumot VideoCapture m_VideoCapture = null;

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

Ezután állítsa be a felvételhez használni kívánt paramétereket, és indítsa el.

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!");
    }
}

A felvétel indítása után kezdje el a felvételt

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);
    }
}

A rögzítés megkezdése után frissítheti a felhasználói felületet vagy a működést a leállítás engedélyezéséhez. Itt csak naplóznia kell.

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.
}

Egy későbbi időpontban le kell állítania a felvételt egy időzítő vagy felhasználói bevitel használatával, például.

// The user has indicated to stop recording
void StopRecordingVideo()
{
    m_VideoCapture.StopRecordingAsync(OnStoppedRecordingVideo);
}

A felvétel leállítása után állítsa le a videomódot, és törölje az erőforrásokat.

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;
}

Hibaelhárítás

  • Nincs elérhető megoldás
    • Győződjön meg arról, hogy a WebCam képesség meg van adva a projektben.

Következő fejlesztési ellenőrzőpont

Ha követi a Unity fejlesztési ellenőrzőpontokkal kapcsolatos, általunk meghatározott útját, akkor a Mixed Reality platform képességeinek és API-jainak felfedezésén van túl. Innen folytathatja a következő témakört:

Vagy közvetlenül az alkalmazás eszközre vagy emulátorra való üzembe helyezéséhez:

Bármikor visszatérhet a Unity fejlesztési ellenőrzőpontjaihoz .

Lásd még