分类
关于视频摄取的一个令人十分头痛的问题,请高手指教---大恩不言谢
我最近在做一个通过摄像头社区图像然后分析的程序
但遇到一个问题
就是如果那个显示图像的窗口被遮住的话,那么摄像头就开始偷懒,不工作了,也就是说内存中关于图像的这块数据就不再变化
而我只要把遮住显示图像的窗口另一个窗口移开---只要显示图像的窗口露出一点的话,它又工作了
我使用vb.net
请问如何解决
ps:本人现在高二,热爱编程,热爱vb,我以后走上怎样的一条道路就全看个位达人指点啦...
高二啊!佩服!
还有你的名字我喜欢,可以加血和恢复系的人物,是组队的绝佳选择啊!
支持楼主,虽然我也不会,希望c/c++的高手来指点!
加分,给例子,分值太少了,高手一般不告诉你的
不知道你说的意思
你好象没有说明白啊
一下程序是我正常使用的一个类,运行正常的,你试试!
Imports System
Imports System.Runtime.InteropServices
Imports System.Drawing
Imports System.Drawing.Imaging
Public Class AviCapture
'.Net里一个用于驱动摄像头的类
'本类是借助avicap32.dll库来驱动摄像头。做到了抓图、录像功能
Private Declare Function capCreateCaptureWindowA Lib "avicap32.dll" (ByVal strWindowName As String, ByVal dwStyle As Int32, ByVal x As Int32, ByVal y As Int32, ByVal width As Int32, ByVal height As Int32, ByVal hwdParent As IntPtr, ByVal nID As Int32) As IntPtr
Private Declare Function capGetVideoFormat Lib "avicap32.dll" (ByVal hWnd As IntPtr, ByVal psVideoFormat As IntPtr, ByVal wSize As Int32) As Integer
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As IntPtr, ByVal wMsg As Int32, ByVal wParam As Int32, ByVal lParam As Long) As Int32
Private Const WM_USER = &H400
Private Const WS_CHILD = &H40000000
Private Const WS_VISIBLE = &H10000000
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
Dim blnRunning As Boolean = False
Dim hWndC As IntPtr
Dim mCaptureObject As Object
Public Sub New()
'
End Sub
Public Sub New(ByVal m_CaptureObject As Object)
mCaptureObject = m_CaptureObject
End Sub
Public Property CaptureObject() As Object
Get
Return mCaptureObject
End Get
Set(ByVal Value As Object)
mCaptureObject = Value
End Set
End Property
'开始显示图像
Public Sub Start()
If (blnRunning) Then
Return
Else
blnRunning = True
End If
If mCaptureObject Is Nothing Then
Return
End If
Dim lpszName As String = Space(100)
hWndC = capCreateCaptureWindowA(lpszName, WS_CHILD Or WS_VISIBLE, 0, 0, mCaptureObject.width, mCaptureObject.height, mCaptureObject.Handle, 0)
If (hWndC.ToInt32 <> 0) Then
SendMessage(hWndC, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0)
SendMessage(hWndC, WM_CAP_SET_CALLBACK_ERROR, 0, 0)
SendMessage(hWndC, WM_CAP_SET_CALLBACK_STATUSA, 0, 0)
SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0)
SendMessage(hWndC, WM_CAP_SET_SCALE, 1, 0)
SendMessage(hWndC, WM_CAP_SET_PREVIEWRATE, 66, 0)
SendMessage(hWndC, WM_CAP_SET_OVERLAY, 1, 0)
SendMessage(hWndC, WM_CAP_SET_PREVIEW, 1, 0)
End If
End Sub
'停止显示
Public Sub Stoped()
If blnRunning Then
SendMessage(hWndC, WM_CAP_DRIVER_DISCONNECT, 0, 0)
End If
blnRunning = False
End Sub
'抓图
Public Sub GrabImage(ByVal path As String)
'paht:要保存bmp文件的路径
Dim hBmp As IntPtr = Marshal.StringToHGlobalAnsi(path)
SendMessage(hWndC, WM_CAP_SAVEDIB, 0, hBmp.ToInt64())
End Sub
Dim blnRecording As Boolean = False
'录像
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(hWndC, WM_CAP_FILE_SET_CAPTURE_FILEA, 0, hBmp.ToInt64())
SendMessage(hWndC, WM_CAP_SEQUENCE, 0, 0)
End Sub
'停止录像
Public Sub StopKinescope()
If blnRecording Then
SendMessage(hWndC, WM_CAP_STOP, 0, 0)
End If
blnRecording = False
End Sub
End Class
终于见到明白人了,不管代码有用否,先收藏一个
既然见到明白人了,就给我些分吧,我正申请本板块的版主,如果支持投我一票,也好让我更好的帮助大家,我的b语言开发龄11年,前期用basic,中期用vb6,现在用vb.net也3年了
UP
有一点明白,找机会仔细看看。先mark
在这先谢谢林达电子
马上试试
新人,刚到这,不懂规矩,还请各位多多指教
现在在学校,没有摄像头,所以,只能晚上回家再试
我学b断断续续的,小学时学了两年qb---只是应付比赛,学得糊里糊涂的;初中时彻底丢下了,初中毕业后暑假重拾编程考了NCRE的二级vb6,过了;然后高一下自学了vb.net,现在一年了。目前正在自学vb.net的视频图像处理技术---晕死了,那些高等数学的式子把我搞死了
现在在学校,没有摄像头,所以,只能晚上回家再试
我学b断断续续的,小学时学了两年qb---只是应付比赛,学得糊里糊涂的;初中时彻底丢下了,初中毕业后暑假重拾编程考了NCRE的二级vb6,过了;然后高一下自学了vb.net,现在一年了。目前正在自学vb.net的视频图像处理技术---晕死了,那些高等数学的式子把我搞死了
还是正常点学些扎实的基础知识,比如数学,语文。钻研技术不是说没有用,只是在修炼外功,而且现在技术更新太快,就算以前QB学的再精终究会被赶死,但基础知识(内功)不一样,有了基础随时可以从高层次切入。。即使短期看不到效果,沉闷了点,还是踏实点啊,小弟弟
前天晚上没试,作业太多
昨晚试了,但是由于本人太菜了吧,在form中把class new过后,再调用start没反应
所以,能不能给一个例程啊,一小段调用的代码就够了
谢谢
以下是我编得那个程序中关于摄像头的代码---自己根据一位外国达人的vb6的程序改编的,现在放出来,请大家多指教
private sub newcap()
Dim lpszName As String
Dim lpszVer As String
lpszName = New String(CChar(""), 100)
lpszVer = New String(CChar(""), 100)
Dim Caps As CAPDRIVERCAPS
capGetDriverDescriptionA(0, lpszName, 100, lpszVer, 100)
lwndC = capCreateCaptureWindowA(lpszName, WS_CAPTION Or WS_THICKFRAME Or WS_VISIBLE Or WS_CHILD, 0, 0, 160, 120, Me.Handle.ToInt32, 0)
SetWindowText(lwndC, lpszName)
capSetCallbackOnStatus(lwndC, AddressOf MyStatusCallback)
capSetCallbackOnError(lwndC, AddressOf MyErrorCallback)
If capDriverConnect(lwndC, 0) Then
capDriverGetCaps(lwndC, VarPtr(Caps), Len(Caps))
capPreviewScale(lwndC, True)
capPreviewRate(lwndC, 66)
capPreview(lwndC, True)
ResizeCaptureWindow(lwndC)
End If
SetWindowPos(Me.Handle.ToInt32, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE Or SWP_NOMOVE)
capPreview(lwndC, True)
SetWindowLong(lwndC, GWL_STYLE, WS_THICKFRAME Or WS_CAPTION Or WS_VISIBLE Or WS_CHILD)
End Sub
Module ProSubAndFun
Public Function capSetCallbackOnErrorO(ByVal lwnd As Integer, ByVal lpProc As Integer) As Boolean
capSetCallbackOnErrorO = SendMessage(lwnd, WM_CAP_SET_CALLBACK_ERROR, 0, lpProc)
End Function
Public Function capSetCallbackOnError(ByVal lwnd As Integer, ByVal lpProc As MyErrorCallbackDelegate) As Boolean
capSetCallbackOnError = SendMessage(lwnd, WM_CAP_SET_CALLBACK_ERROR, 0, lpProc)
End Function
Public Function capSetCallbackOnStatusO(ByVal lwnd As Integer, ByVal lpProc As Integer) As Boolean
capSetCallbackOnStatusO = SendMessage(lwnd, WM_CAP_SET_CALLBACK_STATUS, 0, lpProc)
End Function
Public Function capSetCallbackOnStatus(ByVal lwnd As Integer, ByVal lpProc As MyStatusCallbackDelegate) As Boolean
capSetCallbackOnStatus = SendMessage(lwnd, WM_CAP_SET_CALLBACK_STATUS, 0, lpProc)
End Function
Public Function capSetCallbackOnYield(ByVal lwnd As Integer, ByVal lpProc As Integer) As Boolean
capSetCallbackOnYield = SendMessage(lwnd, WM_CAP_SET_CALLBACK_YIELD, 0, lpProc)
End Function
Public Function capSetCallbackOnFrame(ByVal lwnd As Integer, ByVal lpProc As Integer) As Boolean
capSetCallbackOnFrame = SendMessage(lwnd, WM_CAP_SET_CALLBACK_FRAME, 0, lpProc)
End Function
Public Function capSetCallbackOnVideoStream(ByVal lwnd As Integer, ByVal lpProc As Integer) As Boolean
capSetCallbackOnVideoStream = SendMessage(lwnd, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, lpProc)
End Function
Public Function capSetCallbackOnWaveStream(ByVal lwnd As Integer, ByVal lpProc As Integer) As Boolean
capSetCallbackOnWaveStream = SendMessage(lwnd, WM_CAP_SET_CALLBACK_WAVESTREAM, 0, lpProc)
End Function
Public Function capSetCallbackOnCapControl(ByVal lwnd As Integer, ByVal lpProc As Integer) As Boolean
capSetCallbackOnCapControl = SendMessage(lwnd, WM_CAP_SET_CALLBACK_CAPCONTROL, 0, lpProc)
End Function
Public Function capDriverConnect(ByVal lwnd As Integer, ByVal i As Short) As Boolean
capDriverConnect = SendMessage(lwnd, WM_CAP_DRIVER_CONNECT, i, 0)
End Function
Public Function capDriverGetCaps(ByVal lwnd As Integer, ByVal s As Integer, ByVal wSize As Short) As Boolean
capDriverGetCaps = SendMessage(lwnd, WM_CAP_DRIVER_GET_CAPS, wSize, s)
End Function
Public Function capPreviewScale(ByVal lwnd As Integer, ByVal f As Boolean) As Boolean
capPreviewScale = SendMessage(lwnd, WM_CAP_SET_SCALE, f, 0)
End Function
Public Function capPreview(ByVal lwnd As Integer, ByVal f As Boolean) As Boolean
capPreview = SendMessage(lwnd, WM_CAP_SET_PREVIEW, f, 0)
End Function
Public Function capPreviewRate(ByVal lwnd As Integer, ByVal wMS As Short) As Boolean
capPreviewRate = SendMessage(lwnd, WM_CAP_SET_PREVIEWRATE, wMS, 0)
End Function
Public Function capGetStatus(ByVal lwnd As Integer, ByVal s As Integer, ByVal wSize As Short) As Boolean
capGetStatus = SendMessage(lwnd, WM_CAP_GET_STATUS, wSize, s)
End Function
Public Function capDlgVideoFormat(ByVal lwnd As Integer) As Boolean
capDlgVideoFormat = SendMessage(lwnd, WM_CAP_DLG_VIDEOFORMAT, 0, 0)
End Function
Public Function capDlgVideoSource(ByVal lwnd As Integer) As Boolean
capDlgVideoSource = SendMessage(lwnd, WM_CAP_DLG_VIDEOSOURCE, 0, 0)
End Function
Public Function capEditCopy(ByVal lwnd As Integer) As Boolean
capEditCopy = SendMessage(lwnd, WM_CAP_EDIT_COPY, 0, 0)
End Function
Public Function MyStatusCallback(ByVal lwnd As Integer, ByVal iID As Integer, ByVal ipstrStatusText As Integer)
If iID = 0 Then Exit Function
Dim sStatusText As String
Dim usStatusText As String
sStatusText = New String(Chr(0), 255)
lStrCpy(StrPtr(sStatusText), ipstrStatusText)
sStatusText = Left$(sStatusText, InStr(sStatusText, Chr(0)) - 1)
usStatusText = StrConv(sStatusText, vbUnicode)
' Debug.print("Status:", usStatusText, iID)
End Function
Delegate Function MyStatusCallbackDelegate(ByVal lwnd As Integer, ByVal iID As Integer, ByVal ipstrStatusText As Integer)
Public Function MyErrorCallback(ByVal lwnd As Integer, ByVal iID As Integer, ByVal ipstrStatusText As Integer)
If iID = 0 Then Exit Function
Dim sStatusText As String
Dim usStatusText As String
sStatusText = New String(Chr(0), 255)
lStrCpy(StrPtr(sStatusText), ipstrStatusText)
sStatusText = Left$(sStatusText, vbUnicode)
'logerror(usStatusText, iID)
End Function
Delegate Function MyErrorCallbackDelegate(ByVal lwnd As Integer, ByVal iID As Integer, ByVal ipstrStatusText As Integer)
Public Sub ResizeCaptureWindow(ByVal lwnd As Integer) '似乎未发挥作用
Dim CAPSTATUS As CAPSTATUS
Dim lCaptionHeight As Integer
Dim lX_Border As Integer
Dim lY_Border As Integer
lCaptionHeight = GetSystemMetrics(SM_CYCAPTION)
lX_Border = GetSystemMetrics(SM_CXFRAME)
lY_Border = GetSystemMetrics(SM_CYFRAME)
If capGetStatus(lwnd, VarPtr(CAPSTATUS), Len(CAPSTATUS)) Then
SetWindowPos(lwnd, HWND_BOTTOM, 0, 0, CAPSTATUS.uiImageWidth + (lX_Border * 2), CAPSTATUS.uiImageHeight + lCaptionHeight + (lY_Border * 2), SWP_NOMOVE Or SWP_NOZORDER)
End If
System.Diagnostics.Debug.WriteLine("Resize Window.")
End Sub
Public Function VarPtr(ByVal obj As Object) As Integer
Dim GC As System.Runtime.InteropServices.GCHandle = System.Runtime.InteropServices.GCHandle.Alloc(obj, Runtime.InteropServices.GCHandleType.Pinned)
Dim ret As Integer = GC.AddrOfPinnedObject.ToInt32
GC.Free()
Return ret
End Function
Public Function StrPtr(ByVal str As String) As Integer
Dim GC As System.Runtime.InteropServices.GCHandle = System.Runtime.InteropServices.GCHandle.Alloc(str, Runtime.InteropServices.GCHandleType.Pinned)
Dim ret As Integer = GC.AddrOfPinnedObject.ToInt32
GC.Free()
Return ret
End Function
End Module
还有
由于本人是自学的,对于api中功能强大的sendmessage最感兴趣,但也最晕
常常改几个常数功能就发生了翻天覆地的变化
所以,渴求于它的详细解析中---在网上一直没找到
希望大哥大姐多多指点
谢先
顶一下,楼主喜欢底层的东西还是看windows编程。C++
你仔细看这段代码了吗?
Public Sub New(ByVal m_CaptureObject As Object)
mCaptureObject = m_CaptureObject
End Sub
Public Property CaptureObject() As Object
Get
Return mCaptureObject
End Get
Set(ByVal Value As Object)
mCaptureObject = Value
End Set
End Property
我给你的2种方法设置对象的,也就是你要显示视频的控件,而你没有设置他们呀,
你的程序不是没有反应,绝对有反应,只是你没有看到,他在内存中反应的,所以...
你只有给他显示的控件对象了,他才会给你反应出来呀!我晕了,你联系我吧,注明你的问题,我记性不好qq379988928 psongchao@yahoo.com.cn
收到
晚上回家试
多谢指点
谢谢,高手代码好用.
果然还是不行啊
按林达电子的方法,是可以用
可是,哎
效果跟我的那个一样
有可能我的意思表达的不是很清楚
如果你有摄像头的话,这样试一下吧
加一个timer控件
每一秒拍一张照片
然后随便找一个窗体把那个显示摄像头拍到图像的那个窗体遮住
然后你在摄像头前跳一支舞
然后你会发现不管你舞跳得多美,没有一张照片会拍到你的
照片全都是那个窗体背遮住前最后的图像,不会改变
这下应该知道我的意思了吧