天天看點

在Windows IoT上使用網絡攝像頭

在樹莓派上可以使用它官方标配的攝像頭,但是這個攝像頭似乎不能被Windows IoT識别和使用。但是,可以在樹莓派的USB口上插入任意型号的攝像頭,就可以實作樹莓派的拍攝功能。

關于攝像頭的尋找和拍攝,我将其封裝成一個類,如下:

public class WebCamHelper
    {
        public MediaCapture mediaCapture;

        private bool initialized = false;

        /// <summary>
        /// 異步初始化網絡攝像頭
        /// </summary>
        public async Task InitializeCameraAsync()
        {
            if (mediaCapture == null)
            {
                // 嘗試發現攝像頭
                var cameraDevice = await FindCameraDevice();

                if (cameraDevice == null)
                {
                    // 沒有發現攝像頭
                    Debug.WriteLine("No camera found!");
                    initialized = false;
                    return;
                }

                // Creates MediaCapture initialization settings with foudnd webcam device
                var settings = new MediaCaptureInitializationSettings { VideoDeviceId = cameraDevice.Id };

                mediaCapture = new MediaCapture();
                await mediaCapture.InitializeAsync(settings);
                initialized = true;
            }
        }

        /// <summary>
        /// 異步尋找攝像頭,如果沒有找到,傳回null,否則傳回DeviceInfomation
        /// </summary>
        private static async Task<DeviceInformation> FindCameraDevice()
        {
            // Get available devices for capturing pictures
            var allVideoDevices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);


            if (allVideoDevices.Count > 0)
            {
                // 如果發現,傳回
                return allVideoDevices[0];
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 開啟攝像頭預覽
        /// </summary>
        public async Task StartCameraPreview()
        {
            try
            {
                await mediaCapture.StartPreviewAsync();
            }
            catch
            {
                initialized = false;
                Debug.WriteLine("Failed to start camera preview stream");
            }
        }

        /// <summary>
        /// 關閉攝像頭預覽
        /// </summary>
        public async Task StopCameraPreview()
        {
            try
            {
                await mediaCapture.StopPreviewAsync();
            }
            catch
            {
                Debug.WriteLine("Failed to stop camera preview stream");
            }
        }


        /// <summary>
        /// 拍攝照片,傳回StorageFile,檔案将被存儲到臨時檔案夾
        /// </summary>
        public async Task<StorageFile> CapturePhoto()
        {
            // Create storage file in local app storage
            string fileName = GenerateNewFileName() + ".jpg";
            CreationCollisionOption collisionOption = CreationCollisionOption.GenerateUniqueName;
            StorageFile file = await ApplicationData.Current.TemporaryFolder.CreateFileAsync(fileName, collisionOption);

            // 拍攝并且存儲
            await mediaCapture.CapturePhotoToStorageFileAsync(ImageEncodingProperties.CreateJpeg(), file);

            //await Task.Delay(500);

            return file;
        }

        /// <summary>
        /// 産生檔案名稱
        /// </summary>
        private string GenerateNewFileName()
        {
            return " IoTSample" + DateTime.Now.ToString("yyyy.MMM.dd HH-mm-ss");
        }

        public string GenerateUserNameFileName(string userName)
        {
            return userName + DateTime.Now.ToString("yyyy.MM.dd HH-mm-ss") + ".jpg";
        }

        /// <summary>
        /// 如果攝像頭初始化成功,傳回true,否則傳回false
        /// </summary>
        public bool IsInitialized()
        {
            return initialized;
        }      

使用示例:

1.初始化

private WebCamHelper camera;
        if(camera==null)
            {
                camera = new WebCamHelper();
                await camera.InitializeCameraAsync();
            }
            if(camera.IsInitialized())
            {
                tbMessage.Text = "Camera啟動成功...";
            }
            else
            {
                tbMessage.Text = "Camera啟動失敗...";
            }          

2.拍攝

if (!camera.IsInitialized()) return;
            StorageFile imgFile = await camera.CapturePhoto();      

拍攝完成的圖檔檔案就存儲在上面的imgFile中。

3.視訊預覽

如果想開啟視訊預覽,實時檢視攝像頭捕獲的圖像,可以在XAML中先添加一個CaptureElement控件:

<CaptureElement x:Name="cameraElement"
                        Loaded="cameraElement_Loaded"/>      

在CaptureElement的Loaded事件中執行source綁定:

cameraElement.Source = camera.mediaCapture;      

然後在想要開始視訊預覽的地方,執行:

await camera.StartCameraPreview();      

關閉視訊預覽:

await camera.StopCameraPreview();