C# - PCのWebカメラで静止画を撮影する / C#(csc.exe)からWinRTを使う (Windows10環境)

# 参考サイト

ソースコードは2個目のサイトからほぼ持ってきたのですが、今見たらアクセスできなくなってました。。

- [カメラ制御](https://social.msdn.microsoft.com/Forums/vstudio/ja-JP/ebc89f7d-d6d6-4490-9602-088d84501d01/124591251312521210462448112395383061237512390)
- [サイト消えとる・・](https://blogs.msdn.microsoft.com/eternalcoding/2013/10/29/how-to-use-specific-winrt-api-from-desktop-apps-capturing-a-photo-using-your-webcam-into-a-wpf-app/)

# コンパイルバッチ

csc.exeでコンパイルするケースはあまり情報がないので苦労するところ。
※デフォルト環境ではWindows Kitsないかも。

```

csc /r:C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Runtime.WindowsRuntime\v4.0_4.0.0.0__b77a5c561934e089\system.runtime.windowsruntime.dll ^
/r:C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Runtime.InteropServices.WindowsRuntime\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Runtime.InteropServices.WindowsRuntime.dll ^
/r:C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Runtime\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Runtime.dll ^
"/r:C:\Program Files (x86)\Windows Kits\8.1\References\CommonConfiguration\Neutral\Annotated\Windows.winmd" %*
```

# ソースコード

起動するといきなり撮影するので注意。

```csharp

using System;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

using Windows.Devices.Enumeration;
using Windows.Media.Capture;
using Windows.Media.MediaProperties;
using Windows.Storage.Streams;

namespace CSFormsCamera
{
    public partial class Form1 : Form
    {
        PictureBox pictureBox1;
        ListBox listBox1;

        public Form1()
        {
            this.Width = 600;
            this.Height = 600;

            var panel1 = new System.Windows.Forms.Panel();
            panel1.Width = 100;
            panel1.Dock = DockStyle.Left;
            this.Controls.Add(panel1);

            Label label1 = new Label();
            label1.Text = "カメラ一覧";
            panel1.Controls.Add(label1);

            listBox1 = new ListBox();
            listBox1.Width = 100;
            listBox1.Top = label1.Height;
            listBox1.DisplayMember = "Name";
            listBox1.SelectedIndexChanged += (s, e) => { CaptureImage(); };
            panel1.Controls.Add(listBox1);

            Button button1 = new Button();
            button1.Text = "Capture";
            button1.Top = listBox1.Top + listBox1.Height + 5;
            button1.AutoSize = true;
            button1.Click += (s, e) => { CaptureImage(); };
            panel1.Controls.Add(button1);

            pictureBox1 = new PictureBox();
            pictureBox1.Dock = DockStyle.Fill;
            pictureBox1.BackColor = Color.White;
            this.Controls.Add(pictureBox1);

            this.Shown += Form1_Shown;
        }

        async void Form1_Shown(object sender, EventArgs e)
        {
            //利用可能なビデオデバイス(カメラ)を探す
            var devices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
            if (devices.Count == 0)
            {
                MessageBox.Show("カメラが見つかりませんでした", "Error", MessageBoxButtons.OK);
                return;
            }
            this.listBox1.DataSource = devices.ToArray();
        }

        async void CaptureImage()
        {
            this.Enabled = false;
            try
            {
                var di = (DeviceInformation)listBox1.SelectedItem;
                if (di != null)
                {
                    using (MediaCapture mediaCapture = new MediaCapture())
                    {
                        mediaCapture.Failed += (s, e) =>
                        {
                            MessageBox.Show("キャプチャできませんでした:" + e.Message, "Error", MessageBoxButtons.OK);
                        };

                        MediaCaptureInitializationSettings setting = new MediaCaptureInitializationSettings();
                        setting.VideoDeviceId = di.Id;//カメラ選択
                        setting.StreamingCaptureMode = StreamingCaptureMode.Video;
                        await mediaCapture.InitializeAsync(setting);

                        //調整しないと暗い場合があるので
                        var vcon = mediaCapture.VideoDeviceController;

                        double max = vcon.Brightness.Capabilities.Max;
                        Console.WriteLine(max);

                        bool brightnessAutoResult = vcon.Brightness.TrySetAuto(true);
                        if ( !brightnessAutoResult ) {
                            Console.WriteLine("Brightness is manually set.");
                            Console.WriteLine(vcon.Brightness.TrySetValue(max));
                        }
                        Console.WriteLine(vcon.Contrast.TrySetAuto(true));
                        
                        var pngProperties = ImageEncodingProperties.CreatePng();
                        pngProperties.Width = (uint)pictureBox1.Width;
                        pngProperties.Height = (uint)pictureBox1.Height;

                        using (var randomAccessStream = new InMemoryRandomAccessStream())
                        {
                            await mediaCapture.CapturePhotoToStreamAsync(pngProperties, randomAccessStream);

                            randomAccessStream.Seek(0);

                            //ビットマップにして表示
                            System.IO.Stream stream = System.IO.WindowsRuntimeStreamExtensions.AsStream(randomAccessStream);
                            var img = System.Drawing.Image.FromStream(stream);
                            this.pictureBox1.Image = img;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            this.Enabled = true;
        }

        [STAThread]
        static void Main()
        {
            Application.Run(new Form1());
        }
    }
}
```