Page 2 of 3
Posted: Wed Oct 05, 2005 8:43 am
by Kukulkan
do you know another method for store webcam images (without use #WM_CAP_EDIT_COPY"?
Yes, but there is needed a lot of work and effort to do so. You can take a look at this:
http://msdn.microsoft.com/library/defau ... erence.asp
There you can go through the Multimedia Functions and Structures. If you search on some of the topics there (google), you surely can get some examples about how to deal with.
Kukulkan
Posted: Wed Oct 05, 2005 9:35 am
by DoubleDutch
You can save to disk with (instead of copying to clipboard):
Code: Select all
If SendMessage_(CAMhWndC,#WM_CAP_GRAB_FRAME,0,0)
SendMessage_(CAMhWndC,#WM_CAP_FILE_SAVEDIBA,0,Path$+Filename$)
EndIf
Then just reload it into the image you want, it is a bit slower thought
-Anthony
Posted: Wed Oct 05, 2005 12:38 pm
by zikitrake
DoubleDutch wrote:You can save to disk with (instead of copying to clipboard):
Code: Select all
If SendMessage_(CAMhWndC,#WM_CAP_GRAB_FRAME,0,0)
SendMessage_(CAMhWndC,#WM_CAP_FILE_SAVEDIBA,0,Path$+Filename$)
EndIf
Then just reload it into the image you want, it is a bit slower thought
-Anthony
Thank you! DoubleDutch, but I tryed these code too and I don't like, because in each save file, the mouse cursor changed to arrow-wait-arrow-wait... and I do not like it much
(Sorry for my horrible English)
Posted: Wed Oct 05, 2005 12:45 pm
by Nik
Why doesn´t
Code: Select all
Repeat
Event=WaitWindowEvent()
SendMessage_(hWndC, #WM_CAP_EDIT_COPY, 0, 0)
img.l = GetClipboardData(#PB_ClipboardImage)
StartDrawing(WindowOutput())
DrawImage(img.l, 0, 0, 640, 480)
StopDrawing()
Until Event=#PB_EventCloseWindow
result in a moving image what o i hvae to do to get it updated?
Posted: Mon Oct 10, 2005 3:24 pm
by Nik
Nobody wants to tell me how to refresh the image correctly? Another question is how did you do the effects (not the whole formula^^) I just wonder how to draw them Point and Plot seem to be a lot to slow.
bye Nik
Posted: Tue Oct 11, 2005 7:03 am
by Kukulkan
@Nik,
Nobody wants to tell me how to refresh the image correctly?
You should advice the driver to do so:
Code: Select all
SendMessage_(hWndC, #WM_CAP_SET_PREVIEW, #True, 0)
Another question is how did you do the effects (not the whole formula^^) I just wonder how to draw them Point and Plot seem to be a lot to slow.
I copy the whole bitmap into an byte-array with GetBitmapBits_(). Now I can manipulate on an array of bytes (in my case 4 bytes per pixel). After manipulation, I use SetBitmapBits_() to write the pixels back to the image. Now I simply use DrawImage().
The algorithm is, in short words, a replacement-matrix. On program-start I create a matrix (2 two-dimensional arrays) which defines, where the information of the destination-pixels are coming from (positions in the source-picture). Later I can loop through this matrix in realtime. I dont have to do very much calculations while processing the image.
Kukulkan
Posted: Tue Oct 11, 2005 9:51 pm
by Nik
Oh thats really cool indeed

Posted: Tue Oct 11, 2005 9:56 pm
by Nik
Oh thats really cool indeed
Hmm but I still don#t get it working thoughPriewview seems to be activated
Code: Select all
Global hWndC
OpenWindow(0,0,0,640,480,#PB_Window_SystemMenu,"test")
;| #WS_VISIBLE
; initialize webcam
If OpenLibrary(0, "avicap32.dll")
*capAddress = IsFunction(0, "capCreateCaptureWindowA")
hWndC = CallFunctionFast(*capAddress, "test", #WS_CHILD , 695, 12, 40, 30, WindowID(), 1)
Debug hWndc
SendMessage_(hWndC, #WM_CAP_DRIVER_CONNECT, KameraID.l, 0) ; connect driver
SendMessage_(hWndC,#WM_CAP_SET_SCALE, #True, 0) ; no stretching
SendMessage_(hWndC, #WM_CAP_SET_PREVIEW, #True, 0) ;see its activated
SendMessage_(hWndC, #WM_CAP_SET_PREVIEWRATE, 50, 0) ; set preview-rate (milliseconds)
;SendMessage_(hWndC, #WM_CAP_END, 0, 0)
; Else
; MessageRequester("Scotty, we have a problem...","Sorry, but I cant find or open avicap32.dll...", #MB_ICONERROR)
; EndIf
;
; retrieve picture
Repeat
Event=WindowEvent()
If Event=#PB_Event_CloseWindow :End:EndIf
ClearClipboard()
SendMessage_(hWndC, #WM_CAP_EDIT_COPY, 0, 0)
img.l = GetClipboardData(#PB_ClipboardImage)
;SendMessage_(hWndC, #WM_CAP_END, 0, 0)
StartDrawing(WindowOutput())
DrawImage(img.l, 0, 0, 640, 480)
StopDrawing()
Delay(10)
ForEver
EndIf
PS; Sorry but things like that arent my best area^^
Posted: Tue Oct 11, 2005 11:19 pm
by Flype
kukulkan:
i play a little and i found something for manipulating pixels,
is it a good method to do this way ? :
Code: Select all
; important: configure your web cam : 320*240*rgb24
#WM_CAP_START = #WM_USER
#WM_CAP_SET_CALLBACK_FRAME = #WM_CAP_START + 5
#WM_CAP_DRIVER_CONNECT = #WM_CAP_START + 10
#WM_CAP_SET_OVERLAY = #WM_CAP_START + 51
#WM_CAP_SET_PREVIEW = #WM_CAP_START + 50
#WM_CAP_SET_PREVIEWRATE = #WM_CAP_START + 52
#WM_CAP_SET_SCALE = #WM_CAP_START + 53
Structure VIDEOHDR
lpData.l
dwBufferLength.l
dwBytesUsed.l
dwTimeCaptured.l
dwUser.l
dwFlags.l
dwReserved.l[4]
EndStructure
Procedure capFrameCallback(hWnd.l,*lpVHdr.VIDEOHDR)
If hWnd
StartDrawing(WindowOutput())
For y=0 To 239
For x=0 To 319
a=*lpVHdr\lpData+3*((239-y)*320+x)
b=PeekB(a+0)&$FF
g=PeekB(a+1)&$FF
r=PeekB(a+2)&$FF
Plot(x+330,y+5,RGB(r,g,b)) ; <------
Next
Next
StopDrawing()
EndIf
EndProcedure
OpenWindow(0,0,0,655,250,#PB_Window_SystemMenu|#PB_Window_WindowCentered,"cam")
If OpenLibrary(0,"avicap32.dll")
hWndC = CallFunctionFast(IsFunction(0,"capCreateCaptureWindowA"),"cap",#WS_CHILD|#WS_VISIBLE,5,5,320,240,WindowID(),1)
EndIf
SendMessage_(hWndC, #WM_CAP_DRIVER_CONNECT, 0, 0)
SendMessage_(hWndC, #WM_CAP_SET_SCALE, #True, 0)
SendMessage_(hWndC, #WM_CAP_SET_OVERLAY, #True, 0)
SendMessage_(hWndC, #WM_CAP_SET_PREVIEW, #True, 0)
SendMessage_(hWndC, #WM_CAP_SET_PREVIEWRATE, 24, 0)
SendMessage_(hWndC, #WM_CAP_SET_CALLBACK_FRAME, 0, @capFrameCallback())
ActivateWindow()
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
SendMessage_(hWndC, #WM_CAP_SET_CALLBACK_FRAME, 0, 0)
Break
EndSelect
ForEver
End
Posted: Wed Oct 12, 2005 8:28 am
by Kukulkan
Hi Flype,
This is great way to avoid using the clipboard. Thank you for this Idea.
In this case, maybe you can use SetBitmapBits_() to copy all pixels into a predefined bitmap and then simply use DrawImage(). This may be faster than using Plot() for every pixel. You have to take care about, how many bytes representing a pixel in this way (idea is untested).
Kukulkan
Posted: Wed Oct 12, 2005 8:42 am
by Flype
Cool... But i don't know at all how to use SetBitmapBits_()...

Maybe you can show me an example using mine
Remark:
Do you know the capture software DScaler4 ?
I'm a bit confused because in DScaler the video refresh-time is much faster than using our method. I don't know why... but anyway... maybe WDM drivers are slower than the others.
thanks for helping us.
Posted: Wed Oct 12, 2005 8:56 am
by Kukulkan
Try
http://www.google.de/search?q=SetBitmapBits and
http://www.google.de/search?q=SetDIBits. You will find everything you need in the first returned results.
Kukulkan
Posted: Wed Oct 12, 2005 9:24 am
by dige
you could do it like this:
Code: Select all
; important: configure your web cam : 320*240*rgb24
#WM_CAP_START = #WM_USER
#WM_CAP_SET_CALLBACK_FRAME = #WM_CAP_START + 5
#WM_CAP_DRIVER_CONNECT = #WM_CAP_START + 10
#WM_CAP_SET_OVERLAY = #WM_CAP_START + 51
#WM_CAP_SET_PREVIEW = #WM_CAP_START + 50
#WM_CAP_SET_PREVIEWRATE = #WM_CAP_START + 52
#WM_CAP_SET_SCALE = #WM_CAP_START + 53
Structure VIDEOHDR
lpData.l
dwBufferLength.l
dwBytesUsed.l
dwTimeCaptured.l
dwUser.l
dwFlags.l
dwReserved.l[4]
EndStructure
Procedure capFrameCallback(hWnd.l, *lpVHdr.VIDEOHDR)
If hWnd
hBmp = UseImage( 1 )
w = ImageWidth()
h = ImageHeight()
bmi.BITMAPINFO
bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
bmi\bmiHeader\biWidth = w
bmi\bmiHeader\biHeight = h
bmi\bmiHeader\biPlanes = 1
bmi\bmiHeader\biBitCount = 32
bmi\bmiHeader\biCompression = #BI_RGB
hdc = StartDrawing(ImageOutput())
If hdc
SetDIBits_( hdc, hBmp, 0, h, *lpVHdr\lpData, bmi, #DIB_RGB_COLORS)
StopDrawing()
EndIf
If StartDrawing(WindowOutput())
DrawImage(UseImage(1), 0, 0)
StopDrawing()
EndIf
EndIf
EndProcedure
OpenWindow(0,0,0,655,250,#PB_Window_SystemMenu|#PB_Window_WindowCentered,"cam")
If OpenLibrary(0,"avicap32.dll")
hWndC = CallFunctionFast(IsFunction(0,"capCreateCaptureWindowA"),"cap",#WS_CHILD|#WS_VISIBLE,5,5,320,240,WindowID(),1)
EndIf
CreateImage(1, 320, 240)
SendMessage_(hWndC, #WM_CAP_DRIVER_CONNECT, 0, 0)
SendMessage_(hWndC, #WM_CAP_SET_SCALE, #True, 0)
SendMessage_(hWndC, #WM_CAP_SET_OVERLAY, #True, 0)
SendMessage_(hWndC, #WM_CAP_SET_PREVIEW, #True, 0)
SendMessage_(hWndC, #WM_CAP_SET_PREVIEWRATE, 24, 0)
SendMessage_(hWndC, #WM_CAP_SET_CALLBACK_FRAME, 0, @capFrameCallback())
ActivateWindow()
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
SendMessage_(hWndC, #WM_CAP_SET_CALLBACK_FRAME, 0, 0)
Break
EndSelect
ForEver
End
Posted: Wed Oct 12, 2005 9:43 am
by FloHimself
interesting!
this could be a good base to do motion-, croma-, edge-detection.
Posted: Wed Oct 12, 2005 9:44 am
by Kukulkan
Hi dige,
This is exactly what I meant! Thank you!
Kukulkan