nullschritt Posted March 8, 2015 Share Posted March 8, 2015 (edited) Hello all I am working on a webcam broadcast program, and I have all the code I need but I'm having one small problem. The data returned from the webcam is a BITMAP and I need it to be an IMAGE OBJECT, and I'm not sure how to turn the bitmap into an image object(like from _GDIPlus_ImageLoadFromFile() ) so that I can preform my resizing/compression on it. (my resizing/compression works on images loaded with _GDIPlus_ImageLoadFromFile() but doesnt seem to be able to process a regular bitmap data.) Here's my code if it helps you understand what I want to do: (the required DLL is attached) expandcollapse popup;-------------------------------------------------------------------------- ; ESCAPI is a very simple DLL interface to use video capture devices ; (most commonly webcams, but also video in devices and other similar things) ; Get dll from --> [url="http://sol.gfxile.net/escapi/index.html"]http://sol.gfxile.net/escapi/index.html[/url] ; #include <GDIplus.au3> #Include <GUIConstantsEx.au3> #Include <Memory.au3> ;-------------------------------------------------------------------------- ; Local variables Local $Width = 320 ;Escapi seems to use 640x480 (or lower) as webcam resolution and will Local $Height = 260 ; adjust the image size to $Width by $Height ;-------------------------------------------------------------------------- ; variables required for dshow escapi Local $tagSimpleCapParams = _ "ptr mTargetBuf;" & _ "int mWidth;" & _ "int mHeight;" Local $tSimpleCapParams = DllStructCreate($tagSimpleCapParams) Local $tTargetBuf = DllStructCreate("BYTE[" & $Width*$Height*4 & "]") Global $pTargetBuf = DllStructGetPtr($tTargetBuf) DllStructSetData($tSimpleCapParams, 1, $pTargetBuf) DllStructSetData($tSimpleCapParams, 2, $Width) DllStructSetData($tSimpleCapParams, 3, $Height) Local $pSimpleCapParams = DllStructGetPtr($tSimpleCapParams) Local $device = 0 ;change this number to select dshow device Local $sver = "--ERROR--" Local $tCam = DllStructCreate("CHAR v[20]") ;buffer used to get ESCAPI device name DllStructSetData($tCam, 1, $sver) Local $pCam = DllStructGetPtr($tCam) ;--------------------------------------------------------------------------- ;Escapi init and get Information local $_escapi_Dll = DllOpen("escapi.dll") Local $CamInfo ;ESCAPI version $return = DllCall($_escapi_Dll,"int","ESCAPIDLLVersion") $CamInfo &= "Dll version = " & Hex($return[0],3) & @CRLF $return = DllCall($_escapi_Dll,"int","initCOM") ; get number of available devices $return = DllCall($_escapi_Dll,"int","countCaptureDevices") $CamInfo &= "Number of devices = " & $return[0] & @CRLF ; get selected device name, $device = 0 DllCall($_escapi_Dll,"none:cdecl","getCaptureDeviceName", "uint" , $device, "ptr" , $pCam , "int" , 20) Local $vCam = DllStructGetData($tCam , 1) $CamInfo &= "First device name = " & $vCam & @CRLF MsgBox(0,"ESCAPI info", $CamInfo) $return = DllCall($_escapi_Dll,"int:cdecl","initCapture", "int", $device, "ptr", $pSimpleCapParams) ;--------------------------------------------------------------------------- ; GUI and GDI init Global $hwnd = GUICreate("EscApi WebCam", $Width, $Height) GUISetState(@SW_SHOW,$hwnd) _GDIPlus_Startup() Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hwnd) ;--------------------------------------------------------------------------- $frames = 0 While 1 Local $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then ExitLoop sleep(10) DllCall($_escapi_Dll,"none:cdecl","doCapture", "int", $device) Do $return = DllCall($_escapi_Dll,"int:cdecl","isCaptureDone", "int", $device) sleep(10) Until $return[0] = 1 $hBMP = _WinAPI_CreateBitmap($Width, $Height , 1 , 32 , $pTargetBuf) Local $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBMP) Local $iWidth = 300 Local $iHeight = _GDIPlus_ImageGetHeight($hImage) * 300 / _GDIPlus_ImageGetWidth($hImage) Local $Widthx = 100 Local $Heightx = _GDIPlus_ImageGetHeight($hImage) * 100 / _GDIPlus_ImageGetWidth($hImage) $himage = _gdiplus_scaleimage2($hImage, $width, $height) $hImage = _GDIPlus_BitmapCloneArea ( $himage, 0, 0, $widthx, $heightx, $GDIP_PXF16RGB555 ) $file = FileOpen(@scriptdir&"\temp.jpg", 18) FileWrite($file, _gdiplus_saveimage2binary($hImage, 50)) FileClose($file) Local $hImage = _GDIPlus_ImageLoadFromFile(@scriptdir&"\temp.jpg") $himage = _gdiplus_scaleimage2($hImage, $width, $height) $hbitmapxx = _GDIPlus_BitmapCloneArea ( $himage, 0, 0, $width, $height, $GDIP_PXF16RGB555 ) _GDIPlus_GraphicsDrawImageRect($hGraphics, $hbitmapxx, 0, 0, $Width, $Height) _GDIPlus_BitmapDispose($hImage) _WinAPI_DeleteObject($hBMP) $frames += 1 ConsoleWrite("Processed Frame: "&$frames&@CRLF) WEnd ;-------------------------------------------------------------------------- ;Clean up $return = DllCall($_escapi_Dll,"none:cdecl","deinitCapture", "int", $device) DllClose($_escapi_Dll) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_Shutdown() GUIDelete($hwnd) Func _gdiplus_scaleimage2($himage, $inewwidth, $inewheight, $ibgcolor = -986896, $bbgclear = True, $iinterpolationmode = 7) Local $iwidth = _gdiplus_imagegetwidth($himage) Local $iheight = _gdiplus_imagegetheight($himage) Local $iw, $ih, $f, $fratio If $iwidth > $iheight Then $f = $iwidth / $inewwidth Else $f = $iheight / $inewheight EndIf $iw = Int($iwidth / $f) $ih = Int($iheight / $f) If $iw > $inewwidth Then $fratio = $inewwidth / $iw $iw = Int($iw * $fratio) $ih = Int($ih * $fratio) ElseIf $ih > $inewheight Then $fratio = $inewheight / $ih $iw = Int($iw * $fratio) $ih = Int($ih * $fratio) EndIf Local $hbitmap = DllCall($__g_hGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iw, "int", $ih, "int", 0, "int", 2498570, "ptr", 0, "int*", 0) If @error Then Return SetError(3, 0, 0) $hbitmap = $hbitmap[6] Local $hbmpctxt = _gdiplus_imagegetgraphicscontext($hbitmap) If $bbgclear Then _gdiplus_graphicsclear($hbmpctxt, $ibgcolor) DllCall($__g_hGDIPDll, "uint", "GdipSetInterpolationMode", "handle", $hbmpctxt, "int", $iinterpolationmode) _gdiplus_graphicsdrawimagerect($hbmpctxt, $himage, 0, 0, $iw, $ih) _gdiplus_imagedispose($himage) _gdiplus_graphicsdispose($hbmpctxt) Return $hbitmap EndFunc Func _sendmsg($to, $msg) EndFunc Func _gdiplus_saveimage2binary($hbitmap, $iquality = 10) Local $simgclsid = _gdiplus_encodersgetclsid("jpg") Local $tguid = _winapi_guidfromstring($simgclsid) Local $pencoder = DllStructGetPtr($tguid) Local $tparams = _gdiplus_paraminit(1) Local $tdata = DllStructCreate("int Quality") DllStructSetData($tdata, "Quality", $iquality) Local $pdata = DllStructGetPtr($tdata) _gdiplus_paramadd($tparams, $gdip_epgquality, 1, $gdip_eptlong, $pdata) Local $pparams = DllStructGetPtr($tparams) Local $hstream = DllCall("ole32.dll", "uint", "CreateStreamOnHGlobal", "ptr", 0, "bool", True, "ptr*", 0) $hstream = $hstream[3] DllCall($__g_hGDIPDll, "uint", "GdipSaveImageToStream", "ptr", $hbitmap, "ptr", $hstream, "ptr", $pencoder, "ptr", $pparams) Local $hmemory = DllCall("ole32.dll", "uint", "GetHGlobalFromStream", "ptr", $hstream, "ptr*", 0) $hmemory = $hmemory[2] Local $imemsize = _memglobalsize($hmemory) Local $pmem = _memgloballock($hmemory) $tdata = DllStructCreate("byte[" & $imemsize & "]", $pmem) Local $bdata = DllStructGetData($tdata, 1) Local $tvariant = DllStructCreate("word vt;word r1;word r2;word r3;ptr data;ptr") DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $hstream, "dword", 8 + 8 * @AutoItX64, "dword", 4, "dword", 23, "dword", 0, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tvariant)) _memglobalfree($hmemory) Return $bdata EndFunc escapi21.zip Edited March 8, 2015 by nullschritt Link to comment Share on other sites More sharing options...
nullschritt Posted March 8, 2015 Author Share Posted March 8, 2015 Answered my own question by using _GDIPlus_ImageLoadFromStream() If anyone has a faster/better solution feel free to post it. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now