nullschritt Posted March 8, 2015 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
nullschritt Posted March 8, 2015 Author Posted March 8, 2015 Answered my own question by using _GDIPlus_ImageLoadFromStream() If anyone has a faster/better solution feel free to post it.
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