BlitzPlus Webcam! Code included.

BlitzPlus Forums/BlitzPlus Programming/BlitzPlus Webcam! Code included.

Hi all, some code curtasy of i cant remember now but his code need a slight correction and i got it working. No dll required just a couple decls which i have included at the end of the code. Have fun :)

Const WM_USER = 1024
Const WS_CHILD = $40000000
Const WS_VISIBLE = $10000000

Const WM_CAP_START = WM_USER
Const WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11
Const WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10
Const WM_CAP_SET_PREVIEW = WM_CAP_START + 50
Const WM_CAP_SET_PREVIEWRATE = WM_CAP_START + 52
Const WM_CAP_SET_SCALE = WM_CAP_START + 53
Const WM_CAP_DLG_VIDEOFORMAT = WM_CAP_START + 41
Const WM_CAP_DLG_VIDEOSOURCE = WM_CAP_START + 42

window = CreateWindow("Capture Window",200,200,326,264,0,17)
hWndC = QueryObject(window,1)

hWndC_API = capCreateCaptureWindow("cap",WS_CHILD Or WS_VISIBLE,0,0,320,240,hWndC,0)

apiSendMessage(hWndC_API,WM_CAP_DRIVER_CONNECT,0,0)
apiSendMessage(hWndC_API,WM_CAP_SET_SCALE,False,0)
apiSendMessage(hWndC_API,WM_CAP_SET_PREVIEW,True,0)
apiSendMessage(hWndC_API,WM_CAP_SET_PREVIEWRATE,1,0)
;apiSendMessage(hWndC_API,WM_CAP_DLG_VIDEOFORMAT,0,0)


Repeat
Delay 40
If WaitEvent()=$803 Then Exit
Forever

apiSendMessage(hWndC_API,WM_CAP_DRIVER_DISCONNECT,0,0)

End

--------------
avicap32.decls
--------------

.lib "avicap32.dll"
capCreateCaptureWindow%(lpszWindowName$,dwStyle%,x%,y%,nWidth%,nHeight%,hWnd%,nID%):"capCreateCaptureWindowA"

------------
user32.decls
------------

.lib "user32.dll"
apiSendMessage%(hwnd%, wMsg%, wParam%, lParam%) : "SendMessageA"

--------------------------------------

Code has been updated to allow proper exit and added format dialog box command

Does this handle multiple cameras?

im not sure, havent tried but if you run 2 copies of the code simultaneously, the second one trigers the windows capture driver dialog. I only have one capture device, my webcam, so if i select same driver it crashes first program. If this happens to you, end blitcc.exe in the task list before trying to run it again.

*EDIT*
Some extra commands. Just add these consts;

Const WM_CAP_DLG_VIDEOFORMAT = WM_CAP_START + 41
Const WM_CAP_DLG_VIDEOSOURCE = WM_CAP_START + 42

and call these for more control;

apiSendMessage(hWndC_API,WM_CAP_DLG_VIDEOSOURCE,0,0) ; will allow you to select the device you want to capture from.

apiSendMessage(hWndC_API,WM_CAP_DLG_VIDEOFORMAT,0,0) ; this will bring up the capture device video format.

Make sure you call these after apiSendMessage(hWndC_API,WM_CAP_DRIVER_CONNECT,0,0)

You should shove this in the archives Andy UK, its a nice bit of code! ;)

Dabz

interessting... but it is possible to grab this video? (fast read pixels with blitzplus)

This might not be the best way to do it, but you can copy a frame to the clipboard:
Const WM_CAP_EDIT_COPY = WM_CAP_START + 30
ApiSendMessage hWndC_api, WM_CAP_EDIT_COPY, 0, 0

I believe there is an PasteFromClipBoard function in the archives by MarkCW, but I don't know if it is B+ compatible.

Yes, this is what i am doing at the moment and it works nice with MarkCW's Clipboard function. Im also using freeimage dll to save out as jpeg. Could make a nice webcam push server :)

Hey Ive been trying to run this and it always crashes at

apiSendMessage(hWndC_API,WM_CAP_DRIVER_CONNECT,0,0)

Anybody know the fix for this? Does anyone have to code to do the same thing in C++?

Have you tried checking the value of hWndC_API ? Because it might be zero. Else, the Window might not be created.
Maybe you could try this:
;-----------------------------------------------------------------------------------------------------
;											Avicap32.dll test
;-----------------------------------------------------------------------------------------------------

Const WM_USER = 1024
Const WS_CHILD = $40000000
Const WS_VISIBLE = $10000000

Const WM_CAP_START = WM_USER
Const WM_CAP_SET_CALLBACK_FRAME = WM_CAP_START + 5
Const WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10
Const WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11
Const WM_CAP_SET_OVERLAY = WM_CAP_START + 51
Const WM_CAP_SET_PREVIEW = WM_CAP_START + 50
Const WM_CAP_SET_PREVIEWRATE = WM_CAP_START + 52
Const WM_CAP_SET_SCALE = WM_CAP_START + 53


;-----------------------------------------------------------------------------------------------------
;													Main Program
;-----------------------------------------------------------------------------------------------------

	Graphics3D 	320, 240, 0, 2
	SetBuffer 	BackBuffer()
	
	;create window
	hWnd		= MakeWindow("capture")
	
	;convert window to capture window
	hWndC		= capCreateCaptureWindow("cap", WS_CHILD + WS_VISIBLE, 0, 0, 320, 240, hWnd, 1)
	
	;connect to capturedriver
	ApiSendMessage 	hWndC, WM_CAP_DRIVER_CONNECT, 0, 0
	;set capturedriver properties
	ApiSendMessage 	hWndC, WM_CAP_SET_SCALE, True, 0
	ApiSendMessage 	hWndC, WM_CAP_SET_PREVIEW, True, 0
	ApiSendMessage 	hWndC, WM_CAP_SET_PREVIEWRATE, 24, 0
	
	Api_SetFocus	SystemProperty$("AppHwnd")
	
;-----------------------------------------------------------------------------------------------------
;													Main Loop
;-----------------------------------------------------------------------------------------------------

While Not KeyHit(1)

 	Cls
 	Text 0, 0, "Please use ESC to end program.."
	Flip
	
Wend

	;disconnect to capturedriver
	ApiSendMessage 	hWndC, WM_CAP_DRIVER_DISCONNECT, 0, 0

	;destory child window
	Api_DestroyWindow	hwnd

End




;-------------------------------------------------------------------------------------------------------
;												MakeWindow()
;-------------------------------------------------------------------------------------------------------
;creates a basic window
Function MakeWindow%(name$)

	;create empty bank b
	b = CreateBank(4)
	
	;create child window
	window = api_CreateWindowEx(0, GetBlitzClassName$(), name$, $10000000, 0, 0, 320, 240, 0, 0, 0, b)
	
	;free bank b
	FreeBank b
	
	;show child window	
	api_ShowWindow	window, 1
	
	;return new window handle
	Return window

End Function


;-------------------------------------------------------------------------------------------------------
;										    GetBlitzClassName$()
;-------------------------------------------------------------------------------------------------------
;get blitz class name
Function GetBlitzClassName$()

	;get blitz window handle
	Local hwnd = SystemProperty$("AppHwnd")
	
	;create empty bank p
	p = CreateBank(255)
	
	;get class name via API
	s = api_GetClassName(hwnd, p, 255)
	
	;convert bank to string
	d$ = ""
	For i = 0 To 254
		;read char
		ok = PeekByte(p, i)
		;if char is empty, exit loop
		If ok = 0 Then Exit
		;add to "d$"
		d$ = d$ + Chr$(ok)
	Next
	
	;release bank p	
	FreeBank p
	
	Return d$
	
End Function


;-----------------------------------------------------------------------------------------------------
;insert these files into the \userlibs directory of Blitz
;ie in "C:\PROGRAM FILES\BLITZ3D\USERLIBS"
;-----------------------------------------------------------------------------------------------------

;------------------------------------------------------------------------------------------------------
;avicap32.decls
;------------------------------------------------------------------------------------------------------
;.lib "Avicap32.dll"
;capCreateCaptureWindow%(lpszWindowName$,dwStyle%,x%,y%,nWidth%,nHeight%,hWnd%,nID%):"capCreateCaptureWindowA"
;------------------------------------------------------------------------------------------------------

;------------------------------------------------------------------------------------------------------
;user32.decls
;------------------------------------------------------------------------------------------------------
;.lib "user32.dll"
;
;apiSendMessage%(hwnd%, wMsg%, wParam%, lParam%) : "SendMessageA"
;api_SetFocus% (hwnd%) : "SetFocus"
;api_DestroyWindow% (hwnd%) : "DestroyWindow"
;api_CreateWindowEx% (dwExStyle%, lpClassName$, lpWindowName$, dwStyle%, x%, y%, nWidth%, nHeight%, hWndParent%, hMenu%, hInstance%, lpParam*) : "CreateWindowExA"
;api_ShowWindow% (hwnd%, nCmdShow%) : "ShowWindow"
;api_GetClassName% (hwnd%, lpClassName*, nMaxCount%) : "GetClassNameA"
;------------------------------------------------------------------------------------------------------


For finding a similair code in c++, search for a common c++ term, like 'public void' and one of the terms in this program, like 'wm_cap_driver_connect':
http://www.google.com/search?hl=en&q=WM_CAP_DRIVER_CONNECT+public+void&btnG=Google+Search

OK, so it doesn't work on B+ only B3D. Read some where that it has to do with B+ not being abel to handle function callbacks... Does anyone know of a work around or will I have to give Mark the reach around and just buy B3d. Well I think I almost have it figured out in C++. (still haveing some linking errors, this is my first time dealing with a lib in DevC++) If I do get it going, I'll try porting to B+ via DLL and sharing it with all.

This is for a robotics project. I'm trying to create a low level object recognition app so the bot can locate traffic cones for a competition. Cross your fingers! :)

Update on B+ WebCam DLL...
Well, I got the preview window and format dialog box to open in C++. But once I close the format dialog box the preview stops. I think this is because I have not provided a win proc for the capture window. I will try doing that next. After a bit of research I have found means of capturing to a file but not to a buffer. There is one macro/msg for WM_CAP_GRAB_FRAME. Which grabs one frame to the capture window.... now to figure out how to get it, hehe. Oh joy!

I am in the process of making a dll with purebasic because i couldnt make blitz read the frame events. Does anyone know how to make B+ read windows events?

I need to know a couple of things if anyone knows the answers:

1. Is there a way that you can write directly to the capture screen so i could put words or something on it?

2. Is there a way to test if a capture device was removed while the program was running or inserted while the program was running? Also, is there a way to see if the device is connected at all?