**object : n_webcam**
================================================================================
forward
global type nvo_webcam from nonvisualobject
end type
end forward
global type nvo_webcam from nonvisualobject autoinstantiate
end type
prototype type
function ulong capCreateCaptureWindowA ( string lpszWindowName, ulong dwStyle, long li_x, long li_y, long nWidth, long nHeight, ulong ParentWin, long nId) LIBRARY 'AVICAP32.DLL' alias for "capCreateCaptureWindowA; ansi"
Function ulong GetDC ( ulong hWnd) Library "user32.dll"
Function long ReleaseDC ( ulong hWnd, ulong hdcr) Library "USER32.DLL"
Function ulong CreateCompatibleDC ( ulong hdc) Library "gdi32.dll"
Function ulong CreateCompatibleBitmap ( ulong hdc, ulong nWidth, ulong nHeight) Library "gdi32.dll"
Function boolean DeleteDC ( ulong hDC) Library "Gdi32.dll"
Function boolean BitBlt ( ulong hdcDest, long nXDest, long nYDest, long nWidth, long nHeight, ulong hdcSrc, long nXSrc, long nYSrc, long dwRop) Library "gdi32.dll"
Function boolean StretchBlt ( ulong hdcDest, long nXOriginDest, long nYOriginDest, long nWidthDest, long nHeightDest, ulong hdcSrc, long nXOriginSrc, longnYOriginSrc, long nWidthSrc, long nHeightSrc, long dwRop) Library "gdi32.dll"
Function ulong SelectObject ( ulong hdc, ulong HGDIOBJ) Library "gdi32.dll"
Function along GetDIBits ( ulong hdc, ulong hbmp, uint uStartScan, uint cScanLines, Ref blob lpvBits, Ref BITMAPINFO lpbi, uint uUsage) Library "gdi32.dll" alias for "GetDIBits"
Function long GetDIBits ( ulong hdc, ulong hbmp, uint uStartScan , uint cScanLines, ulong lpvBits, ref bitmapinfo lpbi, uint uUsage) Library "gdi32.dll" alias for "GetDIBits"
Subroutine CopyBitmapFileHeader ( Blob Ref Destination, bitmapfileheader Source, long Length) Library "kernel32.dll" Alias For "RtlMoveMemory" Subroutine CopyBitmapInfo ( Blob Ref Destination, Source bitmapinfo, long Length) Library "kernel32.dll" Alias For "RtlMoveMemory"
Function boolean OpenClipboard ( ulong hWndNewOwner) Library "user32.dll"
Function boolean CloseClipboard () Library "user32.dll"
Function boolean EmptyClipboard () Library "user32.dll"
Function ulong GetClipboardData ( ulong uFormat) Library "user32.dll"
end prototypes
such variables
Uint LHand
Constant long GET_FRAME = 1084
Constant long COPY = 1054
Constant long WM_USER = 1024
Constant long WM_CAP_START = WM_USER
Constant long WM_CAP_STOP = WM_CAP_START + 68
Constant long WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10
Constant long WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11
Constant long WM_CAP_SAVEDIB = WM_CAP_START + 25
Constant Long WM_CAP_GRAB_FRAME = WM_CAP_START + 60
Constant LongWM_CAP_SEQUENCE = WM_CAP_START + 62
Constant long WM_CAP_FILE_SET_CAPTURE_FILEA = WM_CAP_START + 20
Constant long WM_CAP_FILE_SAVEAS = WM_CAP_START + 23
Constant long WM_CAP_SEQUENCE_NOFILE = WM_CAP_START + 63
Constant long WM_CAP_SET_OVERLAY = WM_CAP_START + 51
Constant long WM_CAP_SET_PREVIEW = WM_CAP_START + 50
Constant long WM_CAP_SET_CALLBACK_VIDEOSTREAM = WM_CAP_START +6
Constant long WM_CAP_SET_CALLBACK_ERROR = WM_CAP_START + 2
Constant Long WM_CAP_SET_CALLBACK_STATUSA = WM_CAP_START +3
Long Constant WM_CAP_SET_CALLBACK_FRAME = WM_CAP_START +5
Long Constant WM_CAP_SET_SCALE = WM_CAP_START + 53
Long Constant WM_CAP_SET_PREVIEWRATE = WM_CAP_START + 52
end variables
forward prototypes
public subroutine of_close ()
public subroutine of_initialize_webcam ( unsignedlong a_handle, string a_title, integer a_width, integer a_height)
public function blob of_copy_clipboard_to_blob ()
public subroutine of_capture_pic ()
end prototypes
public subroutine of_close (); send (lhand, WM_CAP_DRIVER_DISCONNECT, 0, 0)
end subroutine
public subroutine of_initialize_webcam ( unsigned long a_handle, string a_title, integer a_width, integer a_height); string lpszName
lpszName = a_title
if lhand = 0 then
lhand = capCreateCaptureWindowA (lpszName, 262144 + 12582912 + 1073741824 + 268435456, 1.40, a_width, a_height, a_handle, 0)
end if
if lhand <> 0 then
send (lhand, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0)
send (lhand, WM_CAP_SET_CALLBACK_ERROR, 0, 0)
send (lhand, WM_CAP_SET_CALLBACK_STATUSA, 0, 0)
send (lhand, WM_CAP_DRIVER_CONNECT, 0, 0)
send (lhand, WM_CAP_SET_SCALE, 1, 0)
send (lhand, WM_CAP_SET_PREVIEWRATE, 66, 0)
send (lhand, WM_CAP_SET_OVERLAY, 1, 0)
send (lhand, WM_CAP_SET_PREVIEW, 1, 0)
end if
end subroutine
public function blob of_copy_clipboard_to_blob (); BitmapInfo lstr_Info
BitmapFileHeader lstr_Header
Blob lblb_header, lblb_info, lblb_bitmap, lbl_final
ULong lul_hdc, lul_hdcMem, lul_hBitmap, lul_hWnd, lul_blpos
UInt DIB_RGB_COLORS
Integer li_pixels
Boolean lb_result
long al_width, ll_height, ll_ret
constant integer BITMAPTYPE = 19778 // 4D42 = BM
constant integer CF_BITMAP = 2
constant integer CF_DIB = 8
lul_hWnd = Handle ( this )
lb_result = OpenClipboard (lul_hWnd)
// Get the device context and allocate memory
lul_hdc = GetDC (lul_hWnd)
lul_hdcMem = CreateCompatibleDC (lul_hdc)
lul_hBitmap = getclipboarddata (CF_BITMAP)
// try to store the bitmap into a blob so we can save it
lstr_Info.bmiHeader.biSize = 40
ll_height = 480 // ... 480 should be enough for everyone? ;)
DIB_RGB_COLORS = 0
// Get the bitmapinfo
If GetDIBits (lul_hdcMem, lul_hBitmap, 0, ll_height, 0, lstr_Info, DIB_RGB_COLORS)> 0 Then
li_pixels = lstr_Info.bmiHeader.biBitCount
lstr_Info.bmiColors [li_pixels] = 0
lblb_bitmap = Blob (Space (lstr_Info.bmiHeader.biSizeImage), EncodingANSI!)
ll_height = lstr_Info.bmiHeader.biheight
// get the actual bits
ll_ret = GetDIBits (lul_hdcMem, lul_hBitmap, 0, ll_height, lblb_bitmap, lstr_Info, DIB_RGB_COLORS)
// ls_msg = hexdump_blob (lblb_bitmap, false)
// create a bitmap header
lstr_Header.bfType = BITMAPTYPE
lstr_Header.bfSize = lstr_Info.bmiHeader.biSizeImage
lstr_Header.bfOffBits = 54 + (li_pixels * 4)
// copy the header structure to a blob
lblb_header = Blob (Space (7)) //
14/2 CopyBitmapFileHeader (lblb_header, lstr_Header, 14)
// copy the info structure to a blob
lblb_Info = Blob (Space (40 + li_pixels * 4) / 2))
CopyBitmapInfo (lblb_Info, lstr_Info, len (lblb_Info))
// add all together and we have a window bitmap in a blob
lbl_final = lblb_header + lblb_info + lblb_bitmap
End If
CloseClipboard ()
ReleaseDC (lul_hwnd, lul_hdc)
DeleteDC (lul_hdcMem)
return lbl_final
end function
public subroutine of_capture_pic (); Send (lhand, GET_FRAME, 0, 0)
Send (lhand, COPY, 0, 0)
end subroutine
we have nvo_webcam. create
call super :: create
TriggerEvent ( this , "constructor" )
end on
we have nvo_webcam. destroy
TriggerEvent ( this , "destructor" )
call super :: destroy
end on
**instantiate the object and initialize it:**
================================================================================
n_webcam.of_initialize_webcam (handle ( this ), "Webcam" , il_width, il_height)
**capture:**
================================================================================
n_webcam.of_capture_pic ()
**image processing:**
================================================================================
lb_blob = n_webcam..of_copy_clipboard_to_blob ()
// reinitialize for the webcam to continue live
i_nvo_webcam.of_initialize_webcam (handle ( this ), "Webcam" , il_width, il_height)
**Close:**
================================================================================
n_webcam.of_close ()
Watch Video https://youtu.be/ojcJs1ajWRc
dark pixel
ratio for a page to be considered as ‘blank’. Eventually I decided to totally skip the blank page omission. Though I don't have that Kodak model available anymore, I believe that it would have no problem. – Azedarach