ビデオデータをキャプチャするには?


あつこ  2004-01-24 19:59:05  No: 81735  IP: [192.*.*.*]

ビデオキャプチャ初期化のcapCreateCaptureWindowは
avicap32.dllに収録されているのはわかったのですが、
以下の3点はどのDLLに収録されているのでしょうか?
capGrabFrame
capEditCopy
capFileSaveDIB
また、Windows API宣言で以下のようなものはどこにあるのでしょうか?

Declare Function capCreateCaptureWindow Lib "avicap32.dll" Alias "capCreateCaptureWindowA" (ByVal a As String, ByVal b As Long, ByVal c As Integer, ByVal d As Integer, ByVal e As Integer, ByVal f As Integer, ByVal g As Long, ByVal h As Integer) As Long

編集 削除
岡田 之仁  2004-01-24 22:16:56  No: 81736  IP: [192.*.*.*]

ヘルプとかちゃんと検索されましたか?

もしくは、ヘルプファイルのインストールで、できれば全て
インストールしておくべきです。

該当のAPIは、Video for Windows API ですネ!

お探しのAPIは、APIではなくコマンドなのです。
で、下記のようにして使います。

※  キャプチャーウィンドウを作成し、そのウィンドウに
    めがけてメッセージをSendすることで実行します。

Public Const WM_USER = &H400
Public Const WM_CAP_START = WM_USER
Public Const WM_CAP_GRAB_FRAME = WM_CAP_START + 60
Public Const WM_CAP_EDIT_COPY = WM_CAP_START + 30
Public Const WM_CAP_FILE_SAVEDIB = WM_CAP_START + 25

Function capGrabFrame(ByVal lwnd As Long) As Boolean
   capGrabFrame = SendMessage(lwnd, WM_CAP_GRAB_FRAME, 0, 0)
End Function

Function capEditCopy(ByVal lwnd As Long) As Boolean
   capEditCopy = SendMessage(lwnd, WM_CAP_EDIT_COPY, 0, 0)
End Function

Function capFileSaveDIB(ByVal lwnd As Long, ByVal szName As Long) As Boolean
   capFileSaveDIB = SendMessage(lwnd, WM_CAP_FILE_SAVEDIB, 0, szName)
End Function

Video for Windows の、ヘルプ部分でAPI・コマンドを確認
された方がいいですヨ!

以上。

編集 削除
あつこ  2004-01-25 03:47:31  No: 81737  IP: [192.*.*.*]

岡田さん:レスありがとうございます。
Video for WindowsのヘルプはMSDNの中にあるのでしょうか?
私のレベルじゃまだ岡田さんみたいにはなれないので・・・

編集 削除
あつこ  2004-01-25 05:14:44  No: 81738  IP: [192.*.*.*]

岡田さんもし見たら、教えてください。

このマクロの使い方ですが、(capFileSaveDIB)
Function capFileSaveDIB(ByVal lwnd As Long, ByVal szName As Long) 
As Boolean
   capFileSaveDIB = SendMessage(lwnd, WM_CAP_FILE_SAVEDIB, 0, szName)
End Function

szNameにはファイルの名前だと思いますが、VBだとファイル名のある配列
を渡せばいいということでしょうか?
また、キャプチャ取り込み後、撮影可能な状態に戻すには
どのようにしたらいいの?

編集 削除
あつこ  2004-01-25 05:23:55  No: 81739  IP: [192.*.*.*]

また、capFileSaveAsはcapFileSaveDIBと同じく
Function capFileSaveAs(ByVal lwnd As Long, ByVal szName As Long) 
As Boolean
   capFileSaveAs = SendMessage(lwnd, WM_CAP_FILE_SAVEDIB, 0, szName)
End Function
でいいということでしょうか?
szNameになのを渡せばいいのかわかりません。

なにからなにまで質問でごめんなさい。
初めて使うのでよくわかりません。

編集 削除
岡田 之仁  2004-01-25 06:53:10  No: 81740  IP: [192.*.*.*]

申し訳ないです・・・
どこで間違ったのか、アセアセ・・・

Private Declare Function SendMessageAsString Lib "user32" Alias "SendMessageA" _
                                            (ByVal hWnd As Long, _
                                            ByVal wMsg As Long, _
                                            ByVal wParam As Long, _
                                            ByVal lParam As String) As Long

Function capFileSaveAs(ByVal hCapWnd As Long, ByVal FilePath As String) As Boolean
   capFileSaveAs = SendMessageAsString(hCapWnd, WM_CAP_FILE_SAVEAS, 0&, FilePath)
End Function

Function capFileSaveDIB(ByVal hCapWnd As Long, ByVal FilePath As String) As Boolean
   capFileSaveDIB = SendMessageAsString(hCapWnd, WM_CAP_FILE_SAVEDIB, 0&, FilePath)
End Function

です・・・
カットアンドペーストしたつもりだったのですが・・・

これでエラーが無くなりますので、お試し下さい。

※  もうひとつ・・・
    弊社(私)はマイクロソフトのデベロッパーなので、尋常じゃない
    開発環境を持っています。それもここ15年分・・・
    ですので、一般に無い、もしくはもう入手不可能なものもまだあり
    ますので・・・

    現在、MSDNライブラリでも、技術情報検索でも、Video for Windows
    の情報検索は、情報が無くなっています。(調べました)
    言いすぎもありますた。申し訳ありません。

    元情報は、C言語用のvfw.h からVB6用にコンバートしています。
    Win32 Platform SDK には、まだ含まれています・・・
    VC++ V6 をインストールされていれば、ありますので・・・

    経過としては、Video for Windows から、世代が変わり、NetMeeting
    からDirectX へと進化していますので、DirectX の DirectShow とか
    をご使用になった方が、安全です。
    ですが、提供されているデバイスが、どこまで提供されているか。
    もしくは対応しているかで、DirectXで使えない場合もあります。
    お気をつけ下さい。

    尚、ここの掲示板でもCCDカメラのキャプチャに関しては書き込みを
    していますが、現在、大きく分けて3種類の方法になっています。
    VFW32 API 
    TWAIN32 API
    DirectX API(下層では、VFW32を呼び出しているよう)
    簡単なのは、TWAIN32でしょう。ですが紙芝居になってしまいます。

    お試し下さい。

※  Video for Windows の、32ビット仕様は、ほとんど情報が出回って
    いません。C言語のヘッダーファイルから類推するしかありません。
    が、16ビット版の折は、当時としては画期的だったので、書籍も
    かなり出ていました。ですが、入手不可能です。
    インターネット上での16〜32ビットのVideo for WindowsのAPIで、
    情報検索すれば、まだまだ出てきます。
    ですが、日本国内は少ない・・・海外はやはり多いです。
    英語を恐れず、探してみて下さい。

以上。

編集 削除
あつこ  2004-01-25 14:29:51  No: 81741  IP: [192.*.*.*]

岡田さんってすごい人なんですね!!!!!!
ITの黄門ちゃまって勝手に私の中で想像しちゃいました:)
英語も翻訳ソフトがあるので多少は読めないこともないんだけど
、意味が通じないこともありますからね。
参考までに、私はよく、http://www.nifty.com/globalgate/を利用しています。

ありがとうございました。

編集 削除
あつこ  2004-01-25 15:10:03  No: 81742  IP: [192.*.*.*]

岡田さん

何回もごめんなさい。

capGrabFrameはピクチャーボックスに画像を表示させていました。
capEditCopyはPCのメモリに画像をロードするからいるんですよね?
capFileSaveAsがだめで ret = 0でした。

これで、撮影可能状態に戻す(フォームロードでできているので)のですが、ピクチャーボックスはまっくろなままです。
どうしたら、また撮影可能状態にもどるのでしょうか?

    hwndc = capCreateCaptureWindow("CaptureWindow", ws_child Or ws_visible, 0, 0, PichWnd.Width, PichWnd.Height, PichWnd.hWnd, 0)

やりたいことは、ボタンを押して撮影した画像をファイルにセーブして
また、撮影可能状態にもどしたんです。

おねがいします。

Sub Command6_Click()

    Dim ret     As Long
    Dim FileName     As String

    ret = capGrabFrame(hwndc)
    ret = capEditCopy(hwndc)
    FileName = "c:\child\atuko.jpg"
    ret = capFileSaveAs(hwndc, FileName)
    If ret = True Then
        MsgBox "ok"
    End If

    '撮影可能状態の戻す。

    hwndc = 0
    hwndc = capCreateCaptureWindow("CaptureWindow", ws_child Or ws_visible, 0, 0, PichWnd.Width, PichWnd.Height, PichWnd.hWnd, 0)
    If (hwndc <> 0) Then
        temp = SendMessage(hwndc, wm_cap_driver_connect, 0, 0)
        temp = SendMessage(hwndc, wm_cap_set_preview, 1, 0)
        temp = SendMessage(hwndc, WM_CAP_SET_PREVIEWRATE, PREVIEWRATE, 0)

        temp = SendMessage(Me.hWnd, WM_CAP_EDIT_COPY, 1, 0)
        PichWnd.Picture = Clipboard.GetData
        Clipboard.Clear
    Else
        MsgBox "つかわないで!!!"
    End If

End Sub

編集 削除
あつこ  2004-01-25 15:38:53  No: 81743  IP: [192.*.*.*]

ちなみに、PCカメラで撮影した画像を携帯電話のメールアドレスに送る
んです。最初は、市販のものを買ったのですが、使い勝手が悪くて
、学校でVBの授業があったので、自作しちゃえ!ということで今にいたっています。

編集 削除
岡田 之仁  2004-01-26 07:54:03  No: 81744  IP: [192.*.*.*]

この投稿以外に、CCDカメラのキャプチャの件がありましたが
そこにも、私がレスしています。

で、わざわざVideo for Windows使わなくても、TWAIN32 ででも
可能ですが・・・今さら方法の変更は大変?

因みに、対象OSは?
TWAIN32 を持っていない場合もありますので・・・

以上。

編集 削除
岡田 之仁  2004-01-26 15:49:28  No: 81745  IP: [192.*.*.*]

まず・・・
capFileSaveAs でのファイルセーブは、もう随分昔のことで
現在、なぜできないのかサッパリ・・・
こちらでも確認しましたが、できませんでした。
何かおまじないが必要かも・・・

で、やはりクリップボード経由でキャプチャした画像をファイル
に保存するやり方で、動作確認できました。

それと懸案の・・・PreView中に、ボタンをクリックしたら、
キャピチャ画像を保存し、画面はそのまま継続してPreViewする
と言う部分ですが・・・

以下、ソース・・・

Option Explicit

Private Const WS_CHILD As Long = &H40000000
Private Const WS_VISIBLE As Long = &H10000000
Private Const SWP_NOMOVE As Integer = &H2
Private Const SWP_NOSIZE As Integer = 1
Private Const SWP_NOZORDER As Integer = &H4
Private Const HWND_BOTTOM As Integer = 1

Private Const WM_USER As Long = &H400
Private Const WM_CAP_START As Long = WM_USER
Private Const WM_CAP_DRIVER_CONNECT As Long = WM_CAP_START + 10
Private Const WM_CAP_DRIVER_DISCONNECT As Long = WM_CAP_START + 11
Private Const WM_CAP_SET_PREVIEW As Long = WM_CAP_START + 50
Private Const WM_CAP_SET_PREVIEWRATE As Long = WM_CAP_START + 52
Private Const WM_CAP_SET_SCALE As Long = WM_CAP_START + 53
Private Const WM_CAP_EDIT_COPY As Long = WM_CAP_START + 30

Private iDevice As Long
Private hHwnd As Long

Private Declare Function SetWindowPos Lib "user32" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Declare Function DestroyWindow Lib "user32" (ByVal hndw As Long) As Boolean

Private Declare Function capCreateCaptureWindow Lib "avicap32.dll" Alias "capCreateCaptureWindowA" _
                                        (ByVal lpszWindowName As String, _
                                        ByVal dwStyle As Long, _
                                        ByVal x As Long, _
                                        ByVal y As Long, _
                                        ByVal nWidth As Long, _
                                        ByVal nHeight As Long, _
                                        ByVal hwndParent As Long, _
                                        ByVal nID As Long) As Long 'returns HWND

Private Declare Function capGetDriverDescription Lib "avicap32.dll" Alias "capGetDriverDescriptionA" _
                                        (ByVal dwDriverIndex As Long, _
                                        ByVal lpszName As String, _
                                        ByVal cbName As Long, _
                                        ByVal lpszVer As String, _
                                        ByVal cbVer As Long) As Long 'returns C BOOL

Private Declare Function SendMessageAsLong Lib "user32" Alias "SendMessageA" _
                                            (ByVal hWnd As Long, _
                                            ByVal wMsg As Long, _
                                            ByVal wParam As Long, _
                                            ByVal lParam As Long) As Long

Private Sub Form_Load()

    Call LoadDeviceList
    
    If List1.ListCount > 0 Then
        Command1.Enabled = True
        List1.ListIndex = 0
    Else
        List1.AddItem ("No Video Capture Device Found")
        Command1.Enabled = False
    End If
    
    Command2.Enabled = False
    Command3.Enabled = False
    
End Sub

Private Sub LoadDeviceList()

    Dim strName As String
    Dim strVer As String
    Dim bReturn As Boolean
    Dim x As Integer
    
    strName = Space(100)
    strVer = Space(100)
    x = 0
            
    Do
        bReturn = capGetDriverDescription(x, strName, 100, strVer, 100)
        If bReturn Then
            List1.AddItem (Trim(strName))
        End If
        x = x + 1
    Loop Until bReturn = False
    
End Sub

Private Sub OpenPreviewWindow()

    Dim iHeight As Long
    Dim iWidth As Long
    
    iHeight = Picture1.Height / 16
    iWidth = Picture1.Width / 16
    
    hHwnd = capCreateCaptureWindow(iDevice, WS_VISIBLE Or WS_CHILD, 0, 0, 320, 240, Picture1.hWnd, 0)
    
    If capDriverConnect(hHwnd, iDevice) Then
        Call capPreviewScale(hHwnd, True)
        Call capPreviewRate(hHwnd, 66)
        Call capPreview(hHwnd, True)
        Call SetWindowPos(hHwnd, HWND_BOTTOM, 0, 0, iWidth, iHeight, SWP_NOMOVE Or SWP_NOZORDER)
        
        Command1.Enabled = False
        Command2.Enabled = True
        Command3.Enabled = True
    Else
        DestroyWindow (hHwnd)
    End If

End Sub

Private Sub ClosePreviewWindow()
        
    Call capDriverDisconnect(hHwnd, iDevice)
    Call DestroyWindow(hHwnd)

End Sub

Private Sub Command1_Click()
        
    iDevice = List1.ListIndex
    Call OpenPreviewWindow
    
End Sub

Private Sub Command2_Click()

    Call ClosePreviewWindow
    
    Command1.Enabled = True
    Command2.Enabled = False
    Command3.Enabled = False
    
End Sub

Private Sub Command3_Click()

    Dim bRet As Boolean
    Dim szTest As String

    szTest = App.Path & "\TEST.bmp" & Chr$(0)

    bRet = capEditCopy(hHwnd)
    If bRet Then
        DoEvents
        If Clipboard.GetFormat(vbCFBitmap) Then
            Picture1.Picture = Clipboard.GetData(vbCFBitmap)
            SavePicture Picture1.Image, szTest
            DoEvents
            Clipboard.Clear
        End If
    End If

End Sub

Private Sub Command4_Click()

    Call ClosePreviewWindow

    Me.Hide
    Unload Me
    
    End
    
End Sub

Private Function capDriverConnect(ByVal hCapWnd As Long, Optional ByVal i As Long = 0&) As Boolean

   capDriverConnect = SendMessageAsLong(hCapWnd, WM_CAP_DRIVER_CONNECT, i, 0&)
   
End Function

Private Function capDriverDisconnect(ByVal hCapWnd As Long, Optional ByVal i As Long = 0&) As Boolean

   capDriverDisconnect = SendMessageAsLong(hCapWnd, WM_CAP_DRIVER_DISCONNECT, i, 0&)
   
End Function

Private Function capPreview(ByVal hCapWnd As Long, ByVal f As Boolean) As Boolean

   capPreview = SendMessageAsLong(hCapWnd, WM_CAP_SET_PREVIEW, -(f), 0&) 'convert the VB Boolean to a C BOOL with the - sign
   
End Function

Private Function capPreviewRate(ByVal hCapWnd As Long, ByVal wMS As Long) As Boolean

   capPreviewRate = SendMessageAsLong(hCapWnd, WM_CAP_SET_PREVIEWRATE, wMS, 0&)
   
End Function

Private Function capPreviewScale(ByVal hCapWnd As Long, ByVal f As Boolean) As Boolean

   capPreviewScale = SendMessageAsLong(hCapWnd, WM_CAP_SET_SCALE, -(f), 0&)
   
End Function

Private Function capEditCopy(ByVal hCapWnd As Long) As Boolean

   capEditCopy = SendMessageAsLong(hCapWnd, WM_CAP_EDIT_COPY, 0&, 0&)
   
End Function

編集 削除
岡田 之仁  2004-01-26 15:55:51  No: 81746  IP: [192.*.*.*]

書き忘れました。

リストボックス、コマンドボタン×4個、ピクチャッボクスを配置
して下さい。

起動時に、使用可能なキャプチャデバイスが、リストボックスに
列挙されます。で、そのひとつを選択し・・・

Command1  表示開始
Command2  表示停止
Command3  キャプチャ&保存
Command4  終了

※  Video for Windows の書籍資料がもう整理してしまっており
    見つかりませんでした。capFileSaveAs が動かないのが気に
    なります。

    多分、もしかして、ビットマップファイルの各設定を毎回し
    てやらないと、保存されないのかもしれません・・・
    まだまだAPIありますので・・・

以上。

編集 削除
あつこ  2004-01-26 18:49:15  No: 81747  IP: [192.*.*.*]

岡田さん!!!ありがとうございます。
なんだか、岡田さんって、どらえもんみたいで、
手元において置きたいっておもっちゃいました。。。
岡田さんの名前を見ちゃうと、ついうれしくなっちゃいます。

それで、OSはXPでWindows下にTWAIN32がありました。
これですかね???

ただ、携帯電話にJPEG画像を送るので、写メール程度の
サイズの写真が鮮明に撮影できればいいんですよ。
調べたところ、PCカメラで30万画素で、お手ごろな値段で
CATCH EYEがあたりがいいんではと思っています。

撮影して、保存できれば、TWAINでもいいんです。

私、保育園でせんせいやってて、まだ経験が浅いのですが、
おかあさんたちに信頼されてて、でも、離れていると心配だろうなぁ
と思って、じゃぁ写真おくっちゃえと考えついたんです!!!!!

編集 削除
岡田 之仁  2004-01-26 19:44:54  No: 81748  IP: [192.*.*.*]

先生様でしたか・・・

幼稚園・保育園では、インターネットを使ったライブも
ぼちぼち始まっていますので・・・新聞には、京都の
保育園で、園での遊び風景や講堂での行事をライブする
記事が掲載されました。機材費用が約220万円

どこもこの記事にカジリツイテ、問い合わせがかなりあ
ったようですが・・・

ご自身で為されると言う『頑張り屋』さんには、ボラン
ティアでも協力したいですネ〜

公共の掲示板で、どうの・・・としても他の方の迷惑な
ので、メールアドレス公開していますので・・・

※  出張と、多忙な納品作業の前なので、大量にレス
    書いてますが・・・

以上。

編集 削除