Taking a picture with my webcam

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Tyrone Malick

Taking a picture with my webcam

24 Oct 2017, 13:22

Just got done searching the documentation but found nothing about webcam / camera controls.

On my GUI I have a button that says take a photo. IS there anyway to do this and if so what is the method?

I tried https://autohotkey.com/board/topic/1627 ... om-webcam/
https://autohotkey.com/board/topic/9637 ... thout-gui/
https://autohotkey.com/board/topic/62379-logon-camera/ (the code itself doesn't work for anything on windows 10)
Tradesxi

Re: Taking a picture with my webcam

16 Aug 2018, 16:17

That works very poorly

no script that takes a photo without asking for source after the second run and saves the photo? I do not mind if gui must show but something that works
User avatar
Masonjar13
Posts: 1555
Joined: 20 Jul 2014, 10:16
Location: Не Россия
Contact:

Re: Taking a picture with my webcam

16 Aug 2018, 17:55

Easy enough to just remove the gui elements and have it automate everything instead. But note that the stream needs to be opened first, so the cam control still needs to be in a gui, but you can just hide it.
OS: Windows 10 Pro | Editor: Notepad++
My Personal Function Library | Old Build - New Build
Tradesxi

Re: Taking a picture with my webcam

16 Aug 2018, 18:48

Masonjar13 wrote:Easy enough to just remove the gui elements and have it automate everything instead. But note that the stream needs to be opened first, so the cam control still needs to be in a gui, but you can just hide it.
I have this code doing it, but sometimes it pops up the box asking for the camera source, usually the first time it works great, the second time it asks for camera source even if i quit the program and run it again, can you please test it?

Code: Select all

SetWorkingDir %A_ScriptDir%

hModule := DllCall("LoadLibrary", "str", "avicap32.dll")

Gui, -caption
Gui, Add, Text, w1 h1 vVidPlaceholder
GuiControl, +0x7, VidPlaceholder ; frame


foundDriver = 0
LV_Delete()
Loop
{
  thisInfo := Cap_GetDriverDescription(A_Index-1)
  If thisInfo
  {
    foundDriver = 1
    LV_Add("", A_Index-1, thisInfo)
  }
  Else
    Break
}
If !foundDriver
{
  LV_Delete()
  msgbox, driver not found
  ExitApp
}
Gui +LastFound
hwndParent := WinExist()
Gui, Show, w1 h1, Smile
SelectedDriver = 0    ;change to suit
  capHwnd := Cap_CreateCaptureWindow(hwndParent, 0, 0, 1, 1)
  WM_USER = 0x0400
  WM_CAP_START := WM_USER
  WM_CAP_GRAB_FRAME_NOSTOP := WM_USER + 61
  WM_CAP_FILE_SAVEDIB := WM_CAP_START + 25
  WM_CAP := 0x400
  WM_CAP_DRIVER_CONNECT := WM_CAP + 10
  WM_CAP_DRIVER_DISCONNECT := WM_CAP + 11
  WM_CAP_EDIT_COPY := WM_CAP + 30
  WM_CAP_SET_PREVIEW := WM_CAP + 50
  WM_CAP_SET_PREVIEWRATE := WM_CAP + 52
  WM_CAP_SET_SCALE := WM_CAP + 53
  
  SendMessage, WM_CAP_DRIVER_CONNECT, %SelectedDriver%, 0, , ahk_id %capHwnd%
  SendMessage, WM_CAP_SET_SCALE, 1, 0, , ahk_id %capHwnd%
  SendMessage, WM_CAP_SET_PREVIEWRATE, 40, 0, , ahk_id %capHwnd%
  SendMessage, WM_CAP_SET_PREVIEW, 1, 0, , ahk_id %capHwnd%
  SendMessage, WM_CAP_FILE_SAVEDIB, 0, "Z", , ahk_id %capHwnd%  
  FileMove, Z, photo9876.png
  SendMessage, WM_CAP_DRIVER_DISCONNECT, 1, 0, , ahk_id %capHwnd%
  DllCall("FreeLibrary", "str", hModule)
  run, photo9876.png
  ExitApp
Return




Cap_CreateCaptureWindow(hWndParent, x, y, w, h)
{
  WS_CHILD := 0x40000000
  WS_VISIBLE := 0x10000000
 
  lpszWindowName := "test"
 
  lwndC := DLLCall("avicap32.dll\capCreateCaptureWindowA"
                  , "Str", lpszWindowName
                  , "UInt", WS_VISIBLE | WS_CHILD ; dwStyle
                  , "Int", x
                  , "Int", y
                  , "Int", w
                  , "Int", h
                  , "UInt", hWndParent
                  , "Int", 0)
 
  ;msgbox % lwndC " | " errorlevel " | " lpszWindowName " | " hwndParent
  Return lwndC
}

Cap_GetDriverDescription(wDriver)
{
  VarSetCapacity(lpszName, 100)
  VarSetCapacity(lpszVer, 100)
  res := DLLCall("avicap32.dll\capGetDriverDescriptionA"
                  , "Short", wDriver
                  , "Str", lpszName
                  , "Int", 100
                  , "Str", lpszVer
                  , "Int", 100)
  If res
    capInfo := lpszName ; " | " lpszVer
  Return capInfo
}
User avatar
Masonjar13
Posts: 1555
Joined: 20 Jul 2014, 10:16
Location: Не Россия
Contact:

Re: Taking a picture with my webcam

17 Aug 2018, 02:45

Tradesxi wrote:the box asking for the camera source
What "box" are you referring to?

Anyways, works fine as-is. Cleaned it up a bit, though.

Code: Select all

SetWorkingDir %A_ScriptDir%
detectHiddenWindows,on
onExit,clean

hModule := DllCall("LoadLibrary", "str", "avicap32.dll")

Gui, -caption
Gui, Add, Text, w1 h1 vVidPlaceholder
GuiControl, +0x7, VidPlaceholder ; frame


foundDriver = 0
LV_Delete()
Loop
{
  thisInfo := Cap_GetDriverDescription(A_Index-1)
  If thisInfo
  {
    foundDriver = 1
    LV_Add("", A_Index-1, thisInfo)
  }
  Else
    Break
}
If !foundDriver
{
  LV_Delete()
  msgbox, driver not found
  ExitApp
}
Gui +LastFound
hwndParent := WinExist()
Gui, Show, w1 h1 hide, Smile
SelectedDriver = 0    ;change to suit
capHwnd := Cap_CreateCaptureWindow(hwndParent, 0, 0, 1, 1)
WM_USER = 0x0400
WM_CAP_START := WM_USER
WM_CAP_GRAB_FRAME_NOSTOP := WM_USER + 61
WM_CAP_FILE_SAVEDIB := WM_CAP_START + 25
WM_CAP := 0x400
WM_CAP_DRIVER_CONNECT := WM_CAP + 10
WM_CAP_DRIVER_DISCONNECT := WM_CAP + 11
WM_CAP_EDIT_COPY := WM_CAP + 30
WM_CAP_SET_PREVIEW := WM_CAP + 50
WM_CAP_SET_PREVIEWRATE := WM_CAP + 52
WM_CAP_SET_SCALE := WM_CAP + 53
return

F1::
SendMessage, WM_CAP_DRIVER_CONNECT, %SelectedDriver%, 0, , ahk_id %capHwnd%
SendMessage, WM_CAP_SET_SCALE, 1, 0, , ahk_id %capHwnd%
SendMessage, WM_CAP_SET_PREVIEWRATE, 40, 0, , ahk_id %capHwnd%
SendMessage, WM_CAP_SET_PREVIEW, 1, 0, , ahk_id %capHwnd%
SendMessage, WM_CAP_FILE_SAVEDIB, 0, "Z.png", , ahk_id %capHwnd%  
FileMove, Z, photo9876.png,1
fileDelete,Z
SendMessage, WM_CAP_DRIVER_DISCONNECT, 1, 0, , ahk_id %capHwnd%
run, photo9876.png
Return

clean:
DllCall("FreeLibrary", "str", hModule)
exitApp

Cap_CreateCaptureWindow(hWndParent, x, y, w, h)
{
  WS_CHILD := 0x40000000
  WS_VISIBLE := 0x10000000
 
  lpszWindowName := "test"
 
  lwndC := DLLCall("avicap32.dll\capCreateCaptureWindowA"
                  , "Str", lpszWindowName
                  , "UInt", WS_VISIBLE | WS_CHILD ; dwStyle
                  , "Int", x
                  , "Int", y
                  , "Int", w
                  , "Int", h
                  , "UInt", hWndParent
                  , "Int", 0)
 
  ;msgbox % lwndC " | " errorlevel " | " lpszWindowName " | " hwndParent
  Return lwndC
}

Cap_GetDriverDescription(wDriver)
{
  VarSetCapacity(lpszName, 100)
  VarSetCapacity(lpszVer, 100)
  res := DLLCall("avicap32.dll\capGetDriverDescriptionA"
                  , "Short", wDriver
                  , "Str", lpszName
                  , "Int", 100
                  , "Str", lpszVer
                  , "Int", 100)
  If res
    capInfo := lpszName ; " | " lpszVer
  Return capInfo
}
OS: Windows 10 Pro | Editor: Notepad++
My Personal Function Library | Old Build - New Build
Tradesxi

Re: Taking a picture with my webcam

17 Aug 2018, 04:26

thank you for the cleanup, let me tell you that for years now people tried to find solution and still as hard as i tried and posted so much begging, nobody can find solution that is reasonable

i will give one example https://autohotkey.com/board/topic/2666 ... ce-dialog/

your code that you posted will work on many machines even if you run it many times again and again, but on many machines, after you run it once or twice it will ask for a source like the post i just shared shows.

The first time it runs it works very well, second time it sometimes asks for video source and many case if you click ok it will take blank photo.

It is as if the first time it runs it grabs onto some dll resource and does not let go of it even after program exists, but if u wait a while like 20 minutes it will work again without asking for source

even after all this time of trying to get help, i stay hoping someone will figure it out
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: Taking a picture with my webcam

17 Aug 2018, 10:13

Here is a working example using TesoSeeu.ocx:

Code: Select all

#NoEnv
SetWorkingDir %A_ScriptDir%
SetBatchLines -1

RegCOM("TesoSeeu.ocx.manifest")
global CamaOcx, g_nImgFmt := 1

Gui, Add, ActiveX, w500 h400 vCamaOcx, {7EEAA4B5-DE19-493F-950C-4053B77195D2}
Gui, Add, DDL, xm vDevIdx w200 gOpenCamera AltSubmit, 
Gui, Add, Button, x+50 gSavePhoto, Save Photo
Gui, Show
AddDevsToDDL()
Return

OpenCamera:
	if DevIdx
		CamaOcx.CloseCapDev(0)

	GuiControlGet, DevIdx
	CamaOcx.openCapDev(DevIdx, 0)
return

SavePhoto:
	hBuffer := CamaOcx.SnapOne(g_nImgFmt)
	nIsz := CamaOcx.GetImgLen(g_nImgFmt)

	; FileOpen("OneSnap.bmp", "w").RawWrite(hBuffer+0, nIsz)

	pToken := Gdip_Startup()
	pBitmap := GDIPlus_pBitmapFromhBuffer(hBuffer, nIsz)
	Gdip_SaveBitmapToFile(pBitmap, "OneSnap.jpg")
	Gdip_Shutdown(pToken)
return

AddDevsToDDL() {
	Loop % CamaOcx.GetDevCnt(0)
	{
		v .= CamaOcx.GetDevNam(A_Index) "|"
	}
	if v
	{
		GuiControl,, DevIdx, % "|" RegExReplace(v, "\|", "||",, 1)
		SetTimer, OpenCamera, -1
	}
}

GuiClose:
ExitApp

;GdiPlus_SaveImageToBuffer() - Scripts and Functions - AutoHotkey Community
;https://autohotkey.com/board/topic/85523-gdiplus-saveimagetobuffer/
GDIPlus_pBitmapFromhBuffer( ByRef hBuffer, nSize ) { ;  Last Modifed : 21-Jun-2011
	; Adapted version by SKAN www.autohotkey.com/forum/viewtopic.php?p=383863#383863
	; Original code   by Sean www.autohotkey.com/forum/viewtopic.php?p=147029#147029
	hData := DllCall("GlobalAlloc", UInt,2, UInt,nSize )
	pData := DllCall("GlobalLock",  UInt,hData )
	DllCall( "RtlMoveMemory", UInt,pData, UInt,hBuffer, UInt,nSize )
	DllCall( "GlobalUnlock" , UInt,hData )
	DllCall( "ole32\CreateStreamOnHGlobal", UInt,hData, Int,True, UIntP,pStream )
	DllCall( "gdiplus\GdipCreateBitmapFromStream",  UInt,pStream, UIntP,pBitmap )
	DllCall( NumGet( NumGet(1*pStream)+8 ), UInt,pStream ) ; IStream::Release
	Return pBitmap
}
Or a simple example without showing GUI window:

Code: Select all

RegCOM("TesoSeeu.ocx.manifest")

Gui, Add, ActiveX, w0 h0 vCamaOcx, {7EEAA4B5-DE19-493F-950C-4053B77195D2}
CamaOcx.openCapDev(DevIdx:=1, 0)
Sleep, 100

g_nImgFmt := 1
hBuffer := CamaOcx.SnapOne(g_nImgFmt)
nIsz := CamaOcx.GetImgLen(g_nImgFmt)
FileOpen("OneSnap.bmp", "w").RawWrite(hBuffer+0, nIsz)
ExitApp
Attachments
TesoSeeu.ocx example.zip
(33.41 KiB) Downloaded 140 times
Tradesxi

Re: Taking a picture with my webcam

17 Aug 2018, 10:51

tmplinshi wrote:Here is a working example using TesoSeeu.ocx
Thank you for that one, that is too many things to ask someone to do just to take a picture

I still am hopeful someone will fix the current solution i posted
User avatar
Frosti
Posts: 426
Joined: 27 Oct 2017, 14:30
Contact:

Re: Taking a picture with my webcam

21 Aug 2018, 13:20

I had an equal issue like you. The first thing I changed was my DLLCall. If you use Unicode version of Autohotkey use unicode DllCall of this function:

Code: Select all

Cap_GetDriverDescription(wDriver)
{
  VarSetCapacity(lpszName, 100)
  VarSetCapacity(lpszVer, 100)
  res := DLLCall("avicap32.dll\capGetDriverDescriptionW"   <- A is ANSI, W is Unicode
    .
    .
    .
    .
The second cause came from the webcam driver. I must check the existence of an ongoing service process and start this process previously if it does not exist.
Tradesxi

Re: Taking a picture with my webcam

21 Aug 2018, 16:08

Frosti wrote: The second cause came from the webcam driver. I must check the existence of an ongoing service process and start this process previously if it does not exist.
so happy you replied, can you tell me what you mean and how to check for that service?
User avatar
Frosti
Posts: 426
Joined: 27 Oct 2017, 14:30
Contact:

Re: Taking a picture with my webcam

22 Aug 2018, 06:34

It's a hauppage usb stick to capture the output of a sonography device. If this service isn't started properly I have only a black screen or in worst case my little script is hanging. In the last case I have to restart the computer. Hauppauge uses their own capture gui. So I start this hauppauge program and wait for video stream. Then I close this program and start my script. That's all.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Google [Bot], Greg_Roberts, inseption86, Lamron750, Rohwedder and 184 guests