トップ回答者
カメラ制御に関して

質問
-
Windows8.1, Visual Studio 2013 VBでの開発を行っています。
カメラ制御を行いたいのですが。Windowsストアアプリではできるのですが、訳あって、Windowsフォームでの開発を行っています。
どのように行うかを教えていただけないでしょうか。出来ないのであれば、WindowsフォームからWindowsストアアプリの呼び出し方法でもかまいません。
よろしくお願いします。
下記の内容はWindows8.1 Windowsストアアプリで調べた結果です。これは問題ありません。
dim dialog = New Windows.Media.Capture.CameraCaptureUI()
dialog.PhotoSettings.Format = Windows.Media.Capture.CameraCaptureUIPhotoFormat.Png
dim file = Await dialog.CaptureFileAsync(Windows.Media.Capture.CameraCaptureUIMode.Photo)
If (File IsNot Nothing) Then
dim MsgBox = New Windows.UI.Popups.MessageDialog(File.Path, "撮影結果)
Awaint MsgBox.ShowAsync()
End If
回答
-
WindowsFormからWinRTのdllを呼んでカメラ撮影できます。
http://blogs.msdn.com/b/eternalcoding/archive/2013/10/29/how-to-use-specific-winrt-api-from-desktop-apps-capturing-a-photo-using-your-webcam-into-a-wpf-app.aspx
を参考にしました。- TargetPlatformVersionを設定してWinRTのdllを使用することを宣言
- System.Runtime.WindowsRuntime.dll
- System.Runtime.dll
- System.Runtime.InteropServices.WindowsRuntime.dll
- System.Threading.Tasks.dll
- System.IO.dll
- Windows.winmd
などの参照を追加するとWindows.Media.Captureを使用してのカメラ撮影が行えました。
Imports Windows.Devices.Enumeration Imports Windows.Media.Capture Imports Windows.Media.MediaProperties Imports Windows.Storage.Streams Public Class Form1 Dim pictureBox1 As PictureBox Dim listBox1 As ListBox Sub New() InitializeComponent() ' InitializeComponent() 呼び出しの後で初期化を追加します。 Me.Width = 600 Me.Height = 600 Dim panel1 = New System.Windows.Forms.Panel() panel1.Width = 100 panel1.Dock = DockStyle.Left Me.Controls.Add(panel1) Dim label1 = New Label() label1.Text = "カメラ一覧" panel1.Controls.Add(label1) listBox1 = New ListBox() listBox1.Width = 100 listBox1.Top = label1.Height listBox1.DisplayMember = "Name" AddHandler listBox1.SelectedIndexChanged, Sub(s, e) CaptureImage() End Sub panel1.Controls.Add(listBox1) Dim button1 = New Button() button1.Text = "Capture" button1.Top = listBox1.Top + listBox1.Height + 5 button1.AutoSize = True AddHandler button1.Click, Sub(s, e) CaptureImage() End Sub panel1.Controls.Add(button1) pictureBox1 = New PictureBox() pictureBox1.Dock = DockStyle.Fill pictureBox1.BackColor = Color.White Me.Controls.Add(pictureBox1) AddHandler Me.Shown, AddressOf Form1_Shown End Sub Private Async Sub Form1_Shown(sender As Object, e As EventArgs) '利用可能なビデオデバイス(カメラ)を探す Dim devices = Await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(DeviceClass.VideoCapture) If (devices.Count = 0) Then MessageBox.Show("カメラが見つかりませんでした", "Error", MessageBoxButtons.OK) Return End If Me.listBox1.DataSource = devices.ToArray() End Sub Private Async Sub CaptureImage() Me.Enabled = False Try Dim di = DirectCast(listBox1.SelectedItem, DeviceInformation) Using mediaCapture1 As New MediaCapture() AddHandler mediaCapture1.Failed, Sub(s, errorEventArgs) MessageBox.Show("キャプチャできませんでした:" + errorEventArgs.Message, "Error", MessageBoxButtons.OK) End Sub Dim setting As New MediaCaptureInitializationSettings() setting.VideoDeviceId = di.Id 'カメラ選択 setting.StreamingCaptureMode = StreamingCaptureMode.Video Await mediaCapture1.InitializeAsync(setting) Dim pngProperties = ImageEncodingProperties.CreatePng() pngProperties.Width = CType(pictureBox1.Width, UInteger) pngProperties.Height = CType(pictureBox1.Height, UInteger) Using randomAccessStream As New InMemoryRandomAccessStream() Await mediaCapture1.CapturePhotoToStreamAsync(pngProperties, randomAccessStream) randomAccessStream.Seek(0) 'ビットマップにして表示 Dim stream = System.IO.WindowsRuntimeStreamExtensions.AsStream(randomAccessStream) Dim img = System.Drawing.Image.FromStream(stream) Me.pictureBox1.Image = img End Using End Using Catch ex As Exception MessageBox.Show(ex.Message) End Try Me.Enabled = True End Sub End Class
VB.NetとC#を、それぞれWindowsFormsとWPFで書いてみました。
GithubとZipファイル。
Windows8.1 32bitでプロジェクトを作ったので64bitだとうまくファイル参照ができないかも。その場合はProgramFiles(x86)のReference AssembliesとWindows Kitsにあるファイルを参照しなおしてみてください。個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
-
カメラの露出調整などを設定しないと周囲の明るさによっては上手く撮影できません。
Private Async Sub CaptureImage() Me.Enabled = False Try Dim di = DirectCast(listBox1.SelectedItem, DeviceInformation) Using mediaCapture1 As New MediaCapture() AddHandler mediaCapture1.Failed, Sub(s, errorEventArgs) MessageBox.Show("キャプチャできませんでした:" + errorEventArgs.Message, "Error", MessageBoxButtons.OK) End Sub Dim setting As New MediaCaptureInitializationSettings() setting.VideoDeviceId = di.Id 'カメラ選択 setting.StreamingCaptureMode = StreamingCaptureMode.Video Await mediaCapture1.InitializeAsync(setting) 'ビデオの露出などの調整がたぶん自動になっていないので自動に設定する Dim vcon = mediaCapture1.VideoDeviceController vcon.Brightness.TrySetAuto(True) vcon.Contrast.TrySetAuto(True) Dim pngProperties = ImageEncodingProperties.CreatePng() pngProperties.Width = CType(pictureBox1.Width, UInteger) pngProperties.Height = CType(pictureBox1.Height, UInteger) Using randomAccessStream As New InMemoryRandomAccessStream() Await mediaCapture1.CapturePhotoToStreamAsync(pngProperties, randomAccessStream) randomAccessStream.Seek(0) 'ビットマップにして表示 Dim stream = System.IO.WindowsRuntimeStreamExtensions.AsStream(randomAccessStream) Dim img = System.Drawing.Image.FromStream(stream) Me.pictureBox1.Image = img End Using End Using Catch ex As Exception MessageBox.Show(ex.Message) End Try Me.Enabled = True End Sub
WindowsRTのライブラリでのカメラ制御なので
https://msdn.microsoft.com/ja-jp/library/windows/hardware/dn265153.aspx
のカメラオプションあたりを参考にしてください。
それでもわからない場合はキーワードをいろいろ変えて検索してみるしかないです。
最初に質問した内容が解決したなら放置せずに、解決となるのに役立った返信に回答マークをつけましょう。いくつでもつけられます。
質問の内容が当初の内容から変わってきたら判り易いタイトルの新規の質問にしましょう。後で同じ悩みの人が探しやすくなります。#名前の後ろの(MVP)は勝手につく所属名のようなものなので不要です。
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク MS初心者 2015年2月5日 1:10
すべての返信
-
CryEarth tomoyuki sasaki 様
ありがとうございます。
http://msdn.microsoft.com/ja-jp/library/dd188521.aspxを参照したのですが、良く分かりません。
ダウンロードの必要があるみたいですが、何をどうすべきか、良く分かりません。
出来れば、方法を教えていただければ助かるのですが。
-
申し訳ありませんDirectShowはDirectX SDK ではなくWindows SDKに移動しています。
ダウンロードは"WindowsR Server 2003 SP1 Platform SDK Full Download"「http://www.microsoft.com/downloads/en/details.aspx?FamilyID=EBA0128F-A770-45F1-86F3-7AB010B398A3」から行えるのですが、導入方法が特殊です。
コマンドプロンプトの使用方法などがわからない場合は、お勧めできなので、申し訳ありませんが私の書き込みを忘れてください。
英語でですが、DirectShow.NET を使用したWPFでのCapture方法を見つけましたので、これではいかがでしょうか?
http://www.codeproject.com/Articles/18511/Webcam-using-DirectShow-NET -
WindowsFormからWinRTのdllを呼んでカメラ撮影できます。
http://blogs.msdn.com/b/eternalcoding/archive/2013/10/29/how-to-use-specific-winrt-api-from-desktop-apps-capturing-a-photo-using-your-webcam-into-a-wpf-app.aspx
を参考にしました。- TargetPlatformVersionを設定してWinRTのdllを使用することを宣言
- System.Runtime.WindowsRuntime.dll
- System.Runtime.dll
- System.Runtime.InteropServices.WindowsRuntime.dll
- System.Threading.Tasks.dll
- System.IO.dll
- Windows.winmd
などの参照を追加するとWindows.Media.Captureを使用してのカメラ撮影が行えました。
Imports Windows.Devices.Enumeration Imports Windows.Media.Capture Imports Windows.Media.MediaProperties Imports Windows.Storage.Streams Public Class Form1 Dim pictureBox1 As PictureBox Dim listBox1 As ListBox Sub New() InitializeComponent() ' InitializeComponent() 呼び出しの後で初期化を追加します。 Me.Width = 600 Me.Height = 600 Dim panel1 = New System.Windows.Forms.Panel() panel1.Width = 100 panel1.Dock = DockStyle.Left Me.Controls.Add(panel1) Dim label1 = New Label() label1.Text = "カメラ一覧" panel1.Controls.Add(label1) listBox1 = New ListBox() listBox1.Width = 100 listBox1.Top = label1.Height listBox1.DisplayMember = "Name" AddHandler listBox1.SelectedIndexChanged, Sub(s, e) CaptureImage() End Sub panel1.Controls.Add(listBox1) Dim button1 = New Button() button1.Text = "Capture" button1.Top = listBox1.Top + listBox1.Height + 5 button1.AutoSize = True AddHandler button1.Click, Sub(s, e) CaptureImage() End Sub panel1.Controls.Add(button1) pictureBox1 = New PictureBox() pictureBox1.Dock = DockStyle.Fill pictureBox1.BackColor = Color.White Me.Controls.Add(pictureBox1) AddHandler Me.Shown, AddressOf Form1_Shown End Sub Private Async Sub Form1_Shown(sender As Object, e As EventArgs) '利用可能なビデオデバイス(カメラ)を探す Dim devices = Await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(DeviceClass.VideoCapture) If (devices.Count = 0) Then MessageBox.Show("カメラが見つかりませんでした", "Error", MessageBoxButtons.OK) Return End If Me.listBox1.DataSource = devices.ToArray() End Sub Private Async Sub CaptureImage() Me.Enabled = False Try Dim di = DirectCast(listBox1.SelectedItem, DeviceInformation) Using mediaCapture1 As New MediaCapture() AddHandler mediaCapture1.Failed, Sub(s, errorEventArgs) MessageBox.Show("キャプチャできませんでした:" + errorEventArgs.Message, "Error", MessageBoxButtons.OK) End Sub Dim setting As New MediaCaptureInitializationSettings() setting.VideoDeviceId = di.Id 'カメラ選択 setting.StreamingCaptureMode = StreamingCaptureMode.Video Await mediaCapture1.InitializeAsync(setting) Dim pngProperties = ImageEncodingProperties.CreatePng() pngProperties.Width = CType(pictureBox1.Width, UInteger) pngProperties.Height = CType(pictureBox1.Height, UInteger) Using randomAccessStream As New InMemoryRandomAccessStream() Await mediaCapture1.CapturePhotoToStreamAsync(pngProperties, randomAccessStream) randomAccessStream.Seek(0) 'ビットマップにして表示 Dim stream = System.IO.WindowsRuntimeStreamExtensions.AsStream(randomAccessStream) Dim img = System.Drawing.Image.FromStream(stream) Me.pictureBox1.Image = img End Using End Using Catch ex As Exception MessageBox.Show(ex.Message) End Try Me.Enabled = True End Sub End Class
VB.NetとC#を、それぞれWindowsFormsとWPFで書いてみました。
GithubとZipファイル。
Windows8.1 32bitでプロジェクトを作ったので64bitだとうまくファイル参照ができないかも。その場合はProgramFiles(x86)のReference AssembliesとWindows Kitsにあるファイルを参照しなおしてみてください。個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
-
gekka(MVP)様
ありがとうございます。
下記の3点でエラーとなります。
Dim devices = Await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(DeviceClass.VideoCapture)
Await mediaCapture1.InitializeAsync(setting)
Await mediaCapture1.CapturePhotoToStreamAsync(pngProperties, randomAccessStream)
待機可能ではありません、と。
何か宣言、やり方が間違っているのでしょうか?
-
必要なdllが正しく参照ができていないとそのエラーが出ます。
GithubとZipにあるプロジェクトでそのエラーが出るのでしょうか?
その場合はプロジェクトの参照で失敗している参照がないか確認して環境に合わせて訂正してください。プロジェクトを使っていないなら、先のレスの頭に記述してあるdllとwinmdをすべて参照に追加してください。
まずはzipファイルのプロジェクトで動作確認することを推奨します。#64bit環境でも正常にビルドが通ることは確認できた
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 編集済み gekkaMVP 2015年2月2日 3:48
-
カメラの露出調整などを設定しないと周囲の明るさによっては上手く撮影できません。
Private Async Sub CaptureImage() Me.Enabled = False Try Dim di = DirectCast(listBox1.SelectedItem, DeviceInformation) Using mediaCapture1 As New MediaCapture() AddHandler mediaCapture1.Failed, Sub(s, errorEventArgs) MessageBox.Show("キャプチャできませんでした:" + errorEventArgs.Message, "Error", MessageBoxButtons.OK) End Sub Dim setting As New MediaCaptureInitializationSettings() setting.VideoDeviceId = di.Id 'カメラ選択 setting.StreamingCaptureMode = StreamingCaptureMode.Video Await mediaCapture1.InitializeAsync(setting) 'ビデオの露出などの調整がたぶん自動になっていないので自動に設定する Dim vcon = mediaCapture1.VideoDeviceController vcon.Brightness.TrySetAuto(True) vcon.Contrast.TrySetAuto(True) Dim pngProperties = ImageEncodingProperties.CreatePng() pngProperties.Width = CType(pictureBox1.Width, UInteger) pngProperties.Height = CType(pictureBox1.Height, UInteger) Using randomAccessStream As New InMemoryRandomAccessStream() Await mediaCapture1.CapturePhotoToStreamAsync(pngProperties, randomAccessStream) randomAccessStream.Seek(0) 'ビットマップにして表示 Dim stream = System.IO.WindowsRuntimeStreamExtensions.AsStream(randomAccessStream) Dim img = System.Drawing.Image.FromStream(stream) Me.pictureBox1.Image = img End Using End Using Catch ex As Exception MessageBox.Show(ex.Message) End Try Me.Enabled = True End Sub
WindowsRTのライブラリでのカメラ制御なので
https://msdn.microsoft.com/ja-jp/library/windows/hardware/dn265153.aspx
のカメラオプションあたりを参考にしてください。
それでもわからない場合はキーワードをいろいろ変えて検索してみるしかないです。
最初に質問した内容が解決したなら放置せずに、解決となるのに役立った返信に回答マークをつけましょう。いくつでもつけられます。
質問の内容が当初の内容から変わってきたら判り易いタイトルの新規の質問にしましょう。後で同じ悩みの人が探しやすくなります。#名前の後ろの(MVP)は勝手につく所属名のようなものなので不要です。
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク MS初心者 2015年2月5日 1:10
-
gekka様
何度もすみません。
>ビデオの露出などの調整がたぶん自動になっていないので自動に設定する
>Dim vcon = mediaCapture1.VideoDeviceController
>vcon.Brightness.TrySetAuto(True)
>vcon.Contrast.TrySetAuto(True)
とか、設定を自動以外で自分で設定しても何も変わりませんでした。
動画として表示し、撮影はできないのでしょうか。
>WindowsRTのライブラリでのカメラ制御なので
>https://msdn.microsoft.com/ja-jp/library/windows/hardware/dn265153.aspx
>のカメラオプションあたりを参考にしてください。参考にしたのですが、良く分かりませんでした。
教えていただけると助かります。