@[TOC]我为什么看不见摄像头预览图像
我最近尝试在vb2010环境下引进摄像头模块,阅读了先贤经验后做了个简单例子。目前可以打开和关闭摄像头,但是预览窗口一片黑,更无法发送copy消息进行单帧截图保存(QQ视频交流能用摄像头),请专业人士诊断一下救命,不胜感激!以下是全部代码
Imports System
Imports System.Runtime.InteropServices
Imports System.Drawing
Imports System.Drawing.Imaging
Public Class Form1
Private Const WS_CHILD = &H40000000
Private Const WS_VISIBLE = &H10000000
Private Const WM_USER = &H400
Private Const WM_CAP_START = WM_USER
Private Const WM_CAP_STOP = WM_CAP_START + 68
Private Const WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10
Private Const WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11
Private Const WM_CAP_SAVEDIB = WM_CAP_START + 25
Private Const WM_CAP_GRAB_FRAME = WM_CAP_START + 60
Private Const WM_CAP_SEQUENCE = WM_CAP_START + 62
Private Const WM_CAP_FILE_SET_CAPTURE_FILEA = WM_CAP_START + 20
Private Const WM_CAP_SEQUENCE_NOFILE = WM_CAP_START + 63
Private Const WM_CAP_SET_OVERLAY = WM_CAP_START + 51
Private Const WM_CAP_SET_PREVIEW = WM_CAP_START + 50
Private Const WM_CAP_SET_CALLBACK_VIDEOSTREAM = WM_CAP_START + 6
Private Const WM_CAP_SET_CALLBACK_ERROR = WM_CAP_START + 2
Private Const WM_CAP_SET_CALLBACK_STATUSA = WM_CAP_START + 3
Private Const WM_CAP_SET_CALLBACK_FRAME = WM_CAP_START + 5
Private Const WM_CAP_SET_SCALE = WM_CAP_START + 53
Private Const WM_CAP_SET_PREVIEWRATE = WM_CAP_START + 52
Private Const WM_CAP_EDIT_COPY = (WM_CAP_START + 30)
Public blnRecording As Boolean = False
Public M_Handle As IntPtr
Private Declare Sub Sleep Lib “kernel32” Alias “Sleep” (ByVal dwMilliseconds As Integer)
Private Declare Function capCreateCaptureWindow Lib “avicap32.dll” Alias “capCreateCaptureWindowA” (ByVal lpszWindowName As String, ByVal dwStyle As Integer, ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hWndParent As Integer, ByVal nID As Integer) As Integer
Private Declare Function SendMessage Lib “user32” Alias “SendMessageA” (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As String) As Integer
Function CreateCaptureWindow(ByVal hWndParent As PictureBox, Optional ByVal x As Integer = 0, Optional ByVal y As Integer = 0, Optional ByVal nWidth As Integer = 320, Optional ByVal nHeight As Integer = 240, Optional ByVal nCameraID As Integer = 0) As Integer
Dim Preview_Handle As Integer
Preview_Handle = capCreateCaptureWindow(“Video”, WS_CHILD + WS_VISIBLE, x, y, hWndParent.Width, hWndParent.Height, hWndParent.Handle, 0)
Dim BOOL As Boolean
BOOL = SendMessage(Preview_Handle, WM_CAP_DRIVER_CONNECT, 0, 0) 'ncameraid(视频只有一个为0,多个以此类推)
If (BOOL = False) Then
MsgBox(“没有找到视频设备!”)
End If
SendMessage(Preview_Handle, WM_CAP_SEQUENCE, 0, “d:\tmp.avi”)
SendMessage(Preview_Handle, WM_CAP_SET_PREVIEWRATE, 30, 0)
SendMessage(Preview_Handle, WM_CAP_SET_OVERLAY, 1, 0)
SendMessage(Preview_Handle, WM_CAP_SET_PREVIEW, 1, 0)
M_Handle = Preview_Handle
REM blnRecording = True
Return Preview_Handle
End Function
Public Sub Disconnect()
SendMessage(M_Handle, WM_CAP_DRIVER_DISCONNECT, 0, 0)
End Sub
Public Sub KineScope(ByVal path As String)
If blnRecording Then
Return
Else
blnRecording = True
End If
'path:要保存avi文件的路径
Dim hBmp As IntPtr = Marshal.StringToHGlobalAnsi(path)
SendMessage(M_Handle, WM_CAP_FILE_SET_CAPTURE_FILEA, 0, hBmp.ToInt64())
SendMessage(M_Handle, WM_CAP_SEQUENCE, 0, 0)
End Sub
Public Sub StopKinescope()
If blnRecording Then
SendMessage(M_Handle, WM_CAP_STOP, 0, 0)
End If
blnRecording = False
End Sub
Public Function GrabImage() As Bitmap
'paht:要保存bmp文件的路径
Dim myBool As Boolean
myBool = SendMessage(M_Handle, WM_CAP_GRAB_FRAME, 1, 0)
myBool = SendMessage(M_Handle, WM_CAP_SAVEDIB, 2, "d:\tmp.dib")
myBool = SendMessage(M_Handle, WM_CAP_EDIT_COPY, 0, 0)
Return Clipboard.GetImage
End Function
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
REM es(MyBase.Load)
End Sub
Private Sub Connecty_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Connecty.Click
CreateCaptureWindow(PictureBox2)
Timer1.Start()
End Sub
Private Sub Disconnecty_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Disconnecty.Click
SendMessage(M_Handle, WM_CAP_DRIVER_DISCONNECT, 0, 0)
End Sub
Private Sub Snapshot_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Snapshot.Click
GrabImage()
PictureBox2.Image = Clipboard.GetImage
Dim ix As Integer = 1
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
PictureBox2.Refresh()
End Sub
End Class