Sdílet prostřednictvím


Photo Video camera in Unity

Povolení funkce pro přístup k fotoaparátu

Funkce WebCam musí být deklarována, aby aplikace používala kameru.

  1. V Unity Editoru přejděte na nastavení přehrávače tak, že přejdete na stránku Upravit > přehrávač nastavení > projektu.
  2. Vyberte kartu Windows Store.
  3. V části Možnosti nastavení > publikování zkontrolujte možnosti WebCam a Mikrofon .

S kamerou může najednou dojít pouze k jedné operaci. V Unity 2018 a starších verzích nebo UnityEngine.Windows.WebCam.Mode v Unity 2019 a novějších verzích můžete zkontrolovat, ve kterém režimu je fotoaparát aktuálně zapnutýUnityEngine.XR.WSA.WebCam.Mode. Dostupné režimy jsou fotka, video nebo žádný.

Snímek fotek

Obor názvů (před Unity 2019): UnityEngine.XR.WSA.WebCam
Obor názvů (Unity 2019 a novější): UnityEngine.Windows.WebCam
Typ: PhotoCapture

Typ PhotoCapture umožňuje pořizovat fotografie pomocí fotoaparátu fotokamery. Obecný vzor použití PhotoCapture k pořízení fotky je následující:

  1. Vytvoření objektu PhotoCapture
  2. Vytvoření objektu CameraParameters s požadovaným nastavením
  3. Spuštění režimu fotky přes StartPhotoModeAsync
  4. Pořídit požadovanou fotku
    • (volitelné) Interakce s tímto obrázkem
  5. Zastavení režimu fotek a vyčištění prostředků

Běžná nastavení pro PhotoCapture

U všech tří použití začněte stejnými prvními třemi kroky výše.

Začněte vytvořením objektu PhotoCapture

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

Dále uložte objekt, nastavte parametry a spusťte režim fotky.

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

Nakonec použijete také stejný kód pro vyčištění, který tady najdete.

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

Po provedení těchto kroků můžete zvolit, jaký typ fotky chcete zachytit.

Zachycení fotky do souboru

Nejjednodušší operací je zachytit fotku přímo do souboru. Fotku můžete uložit ve formátu JPG nebo PNG.

Pokud jste úspěšně spustili režim fotky, udělejte fotku a uložte ji na disk.

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

Po zachycení fotky na disk ukončete režim fotky a pak objekty vyčistíte.

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

Zachycení fotky do textury2D s umístěním

Při zachytávání dat do texture2D se proces podobá zachytávání na disk.

Postupujte podle výše uvedeného procesu instalace.

V OnPhotoModeStarted zachyťte rámeček do paměti.

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

Výsledek pak použijete na texturu a použijete výše uvedený běžný kód čištění.

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

Lokatable camera

Pokud chcete tuto texturu umístit do scény a zobrazit ji pomocí lokovatelných matic fotoaparátu, přidejte do kontroly následující kód: result.success

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 poskytla vzorový kód pro použití matice projekce na konkrétní shader na jejich fórech.

Zachycení fotky a interakce s nezpracovanými bajty

Pokud chcete pracovat s nezpracovanými bajty v rámci paměti, postupujte podle stejných kroků nastavení jako výše a OnPhotoModeStarted jako při zachycení fotky do textury2D. Rozdíl je v OnCapturedPhotoToMemory , kde můžete získat nezpracované bajty a pracovat s nimi.

V tomto příkladu vytvoříte seznam , který se bude dále zpracovávat nebo používat na texturu pomocí 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);
}

Zachycení videa

Obor názvů (před Unity 2019): UnityEngine.XR.WSA.WebCam
Obor názvů (Unity 2019 a novější): UnityEngine.Windows.WebCam
Typ: VideoCapture

Funkce VideoCapture fungují podobně jako PhotoCapture. Jedinými dvěma rozdíly jsou, že je nutné zadat hodnotu snímků za sekundu (FPS) a můžete uložit pouze přímo na disk jako .mp4 soubor. Postup použití VideoCapture je následující:

  1. Vytvoření objektu VideoCapture
  2. Vytvoření objektu CameraParameters s požadovaným nastavením
  3. Spuštění režimu videa přes StartVideoModeAsync
  4. Zahájení nahrávání videa
  5. Zastavit nahrávání videa
  6. Zastavení režimu videa a vyčištění prostředků

Začněte vytvořením objektu VideoCapture Objekt VideoCapture m_VideoCapture = null;

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

Dále nastavte parametry, které budete chtít pro záznam a spustit.

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

Po spuštění zahajte nahrávání.

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

Po spuštění záznamu můžete aktualizovat uživatelské rozhraní nebo chování a povolit zastavení. Tady se jen zapíšete.

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

Později budete chtít záznam zastavit například pomocí časovače nebo uživatelského vstupu.

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

Jakmile se nahrávání zastaví, zastavte režim videa a vyčistěte prostředky.

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

Řešení problému

  • Nejsou k dispozici žádná řešení.
    • Ujistěte se, že je ve vašem projektu zadána funkce WebCam .

Kontrolní bod dalšího vývoje

Pokud sledujete cestu kontrolního bodu vývoje Unity, kterou jsme probrali, jste uprostřed zkoumání možností platformy hybridní reality a rozhraní API. Odsud můžete pokračovat k dalšímu tématu:

Nebo přejděte přímo k nasazení aplikace do zařízení nebo emulátoru:

Kdykoli se můžete vrátit k kontrolním bodům vývoje Unity.

Viz také