Unity'de FotoğrafLı Video kamera
Kamera erişimi özelliğini etkinleştirme
Bir uygulamanın kamerayı kullanabilmesi için "WebCam" özelliği bildirilmelidir.
- Unity Düzenleyicisi'nde "Proje Ayarlarını Düzenle > Oynatıcı" sayfasına giderek oynatıcı ayarlarına > gidin
- "Windows Mağazası" sekmesini seçin
- "Yayımlama Ayarları > Özellikleri" bölümünde WebCam ve Mikrofon özelliklerini denetleyin
Kamerayla aynı anda yalnızca tek bir işlem gerçekleşiyor. Unity 2018 ve önceki sürümlerde UnityEngine.XR.WSA.WebCam.Mode
veya UnityEngine.Windows.WebCam.Mode
Unity 2019 ve sonraki sürümlerde kameranın şu anda hangi modda olduğunu kontrol edebilirsiniz. Kullanılabilir modlar fotoğraf, video veya hiçbiridir.
Fotoğraf yakalama
Ad Alanı (Unity 2019'dan önce): UnityEngine.XR.WSA.WebCam
Ad Alanı (Unity 2019 ve üzeri): UnityEngine.Windows.WebCam
Tür: PhotoCapture
PhotoCapture türü, Fotoğraf Video Kamerası ile fotoğraf çekmenizi sağlar. Fotoğraf çekmek için PhotoCapture'ı kullanmak için genel desen aşağıdaki gibidir:
- PhotoCapture nesnesi oluşturma
- İstediğiniz ayarlarla CameraParameters nesnesi oluşturma
- StartPhotoModeAsync aracılığıyla Fotoğraf Modu'nu başlatma
- İstediğiniz fotoğrafı çekin
- (isteğe bağlı) Bu resimle etkileşim kurma
- Fotoğraf Modu'nu durdurma ve kaynakları temizleme
PhotoCapture için ortak kurulum
Üç kullanım için de yukarıdaki ilk üç adımla başlayın
PhotoCapture nesnesi oluşturarak başlayın
private void Start()
{
PhotoCapture.CreateAsync(false, OnPhotoCaptureCreated);
}
Ardından nesnenizi depolayın, parametrelerinizi ayarlayın ve Fotoğraf Modu'nu başlatın
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);
}
Sonunda, burada sunulan temizleme kodunun aynısını da kullanacaksınız
void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
{
photoCaptureObject.Dispose();
photoCaptureObject = null;
}
Bu adımlardan sonra, hangi fotoğraf türünü yakalayabileceğinizi seçebilirsiniz.
Dosyaya fotoğraf yakalama
En basit işlem, doğrudan bir dosyaya fotoğraf çekmektir. Fotoğraf JPG veya PNG olarak kaydedilebilir.
Fotoğraf modunu başarıyla başlattıysanız, bir fotoğraf çekin ve bunu diskte depolayın
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!");
}
}
Fotoğrafı diske kaydettikten sonra fotoğraf modundan çıkın ve nesnelerinizi temizleyin
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");
}
}
Konum ile Bir Doku2D'ye fotoğraf yakalama
Doku2D'ye veri yakalama işlemi diske yakalamaya benzer.
Yukarıdaki kurulum işlemini izleyin.
OnPhotoModeStarted'da belleğe bir çerçeve yakalayın.
private void OnPhotoModeStarted(PhotoCapture.PhotoCaptureResult result)
{
if (result.success)
{
photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
}
else
{
Debug.LogError("Unable to start photo mode!");
}
}
Ardından sonucunuzu bir dokuya uygulayacak ve yukarıdaki ortak temizleme kodunu kullanacaksınız.
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
Bu dokuyu görünüme yerleştirmek ve lokatable kamera matrislerini kullanarak görüntülemek için, denetimde OnCapturedPhotoToMemory'ye result.success
aşağıdaki kodu ekleyin:
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, projeksiyon matrisini forumlarındaki belirli bir gölgelendiriciye uygulamak için örnek kod sağlamıştır.
Fotoğraf yakalama ve ham baytlarla etkileşim kurma
Bellek çerçevesindeki bir değerin ham baytlarıyla etkileşim kurmak için yukarıdaki ve OnPhotoModeStarted ile aynı kurulum adımlarını izleyin. Fark, ham baytları alabileceğiniz ve bunlarla etkileşim kurabileceğiniz OnCapturedPhotoToMemory'dir .
Bu örnekte, SetPixels() aracılığıyla daha fazla işlenecek veya bir dokuya uygulanacak bir Liste oluşturacaksınız
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 yakalama
Ad Alanı (Unity 2019'dan önce): UnityEngine.XR.WSA.WebCam
Ad Alanı (Unity 2019 ve üzeri): UnityEngine.Windows.WebCam
Tür: VideoCapture
VideoCapture, PhotoCapture'a benzer şekilde çalışır. Tek iki fark, Saniye Başına Kare (FPS) değeri belirtmeniz gerektiğidir ve yalnızca .mp4 dosyası olarak doğrudan diske kaydedebilirsiniz. VideoCapture'ı kullanma adımları aşağıdaki gibidir:
- VideoCapture nesnesi oluşturma
- İstediğiniz ayarlarla CameraParameters nesnesi oluşturma
- StartVideoModeAsync aracılığıyla Video Modunu Başlat
- Video kaydetmeye başlama
- Video kaydını durdur
- Video Modu'nu durdurma ve kaynakları temizleme
VideoCapture nesnemizi oluşturarak başlayın VideoCapture m_VideoCapture = null;
void Start ()
{
VideoCapture.CreateAsync(false, OnVideoCaptureCreated);
}
Ardından, kayıt için istediğiniz parametreleri ayarlayın ve başlatın.
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!");
}
}
Başlatıldıktan sonra kaydı başlatı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);
}
}
Kayıt başlatıldıktan sonra, durdurmayı etkinleştirmek için kullanıcı arabiriminizi veya davranışlarınızı güncelleştirebilirsiniz. Burada sadece günlüğe kaydet.
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.
}
Daha sonraki bir noktada, örneğin bir zamanlayıcı veya kullanıcı girişi kullanarak kaydı durdurmak isteyeceksiniz.
// The user has indicated to stop recording
void StopRecordingVideo()
{
m_VideoCapture.StopRecordingAsync(OnStoppedRecordingVideo);
}
Kayıt durdurulduktan sonra video modunu durdurun ve kaynaklarınızı temizleyin.
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;
}
Sorun giderme
- Kullanılabilir çözünürlük yok
- Projenizde WebCam özelliğinin belirtildiğinden emin olun.
Sonraki Geliştirme Denetim Noktası
Sunduğumuz Unity geliştirme denetim noktası yolculuğunu takip ediyorsanız, Karma Gerçeklik platformu özelliklerini ve API'lerini keşfetmenin ortasındasınız demektir. Buradan sonraki konuya devam edebilirsiniz:
Veya doğrudan uygulamanızı bir cihaza veya öykünücüye dağıtmaya atlayabilirsiniz:
İstediğiniz zaman Unity geliştirme denetim noktalarına geri dönebilirsiniz.