I've had this problem where I can't clear an image I set to a picture control in a project I started some time ago, I never figured this out w/o having to do things that seem overly coplicated.
My script deals with a user picking an image and then the script displays a smaller version rendered in the pic control, in the script, a user can then select an option to use no pic and in that moment, I never figured out a way to make the script clear the image after setting it the way I do.
I want to avoid writing files to the hard drive so use functions to deal with the image in memory using functions I've found around the forums.
I made an example showing my problem.
If you click set image, a random colored image will be put in the control like how I do it with other images.
But I have no idea how to clear it when pressing clear image.....
My script deals with a user picking an image and then the script displays a smaller version rendered in the pic control, in the script, a user can then select an option to use no pic and in that moment, I never figured out a way to make the script clear the image after setting it the way I do.
I want to avoid writing files to the hard drive so use functions to deal with the image in memory using functions I've found around the forums.
I made an example showing my problem.
If you click set image, a random colored image will be put in the control like how I do it with other images.
But I have no idea how to clear it when pressing clear image.....
[ autoit ]
#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7 #Include <GDIPlus.au3> #include <MemoryConstants.au3> #include <Memory.au3> #include <GUIConstants.au3> #include <StaticConstants.au3> #Region ### START Koda GUI section ### Form= Global $UI_MAIN = GUICreate("some kind of...", 235, 183, 192, 124) Global $Image = GUICtrlCreatePic("", 8, 8, 220, 140, $SS_SUNKEN+$SS_CENTERIMAGE) Global $SetImg = GUICtrlCreateButton("Set Image", 8, 152, 75, 25) Global $ClearScrn = GUICtrlCreateButton("Clear Image", 152, 152, 75, 25) GUICtrlCreateLabel("/)(O ) _( O)(\", 88, 160, 63, 17) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### Global $TempImg _GDIPlus_Startup() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE _GDIPlus_Shutdown() Exit Case $SetImg $TempImg = Load_BMP_From_Mem(Draw("IDS HABBENING!!"), True) _WinAPI_DeleteObject(GUICtrlSendMsg($Image, 0x0172, 0, $TempImg)) $TempImg = 0 Case $ClearScrn ; do something here to clear the image control GUICtrlSetData($Image, "") EndSwitch WEnd Func Draw($sString = "") Local $hGraphic, $hBrush, $hFormat, _ $hFamily, $hFont, $tLayout, _ $aInfo, $hBitmap, $FontSize, _ $iWidth, $iHeight, $fontStyle, _ $NewImage, $hImage $sString = StringProc($sString, 18) $iWidth = 220 $iHeight = 140 $FontSize = 15 $fontStyle = 1 $hImage = _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight) $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage) $hBrush = _GDIPlus_BrushCreateSolid('0xFF' & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2)) _GDIPlus_GraphicsFillRect($hGraphic, 0, 0, $iWidth, $iHeight, $hBrush) _GDIPlus_BrushDispose($hBrush) $hFormat = _GDIPlus_StringFormatCreate() $hFamily = _GDIPlus_FontFamilyCreate("consolas") $hFont = _GDIPlus_FontCreate($hFamily, $FontSize, $fontStyle) $tLayout = _GDIPlus_RectFCreate($iWidth/2/5, $iHeight/3, 0, 0) $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $sString, $hFont, $tLayout, $hFormat) $hBrush = _GDIPlus_BrushCreateSolid('0xFF' & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2)) _GDIPlus_GraphicsDrawStringEx($hGraphic, $sString, $hFont, $aInfo[0], $hFormat, $hBrush) $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage) _GDIPlus_FontDispose($hFont) _GDIPlus_BrushDispose($hBrush) _WinAPI_DeleteObject($hBitmap) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_StringFormatDispose($hFormat) $NewImage = _GDIPlus_SaveImageToStream($hImage, 100, "png") _GDIPlus_ImageDispose($hImage) Return $NewImage EndFunc ;==>Draw Func _GDIPlus_SaveImageToStream($hBitmap, $iQuality = 50, $Encoder = "jpg") ;coded by Andreik, modified by UEZ and me Local $tParams Local $tData Local $pData Local $pParams Local $sImgCLSID = _GDIPlus_EncodersGetCLSID($Encoder) Local $tGUID = _WinAPI_GUIDFromString($sImgCLSID) Local $pEncoder = DllStructGetPtr($tGUID) If $Encoder == "jpg" Or $Encoder == "jpeg" Then $tParams = _GDIPlus_ParamInit(1) $tData = DllStructCreate("int Quality") DllStructSetData($tData, "Quality", $iQuality) ;quality 0-100 $pData = DllStructGetPtr($tData) _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData) $pParams = DllStructGetPtr($tParams) Else $pParams = 0 EndIf Local $hStream = DllCall("ole32.dll", "uint", "CreateStreamOnHGlobal", "ptr", 0, "bool", True, "ptr*", 0) If @error Then Return SetError(1, 0, 0) $hStream = $hStream[3] DllCall($ghGDIPDll, "uint", "GdipSaveImageToStream", "ptr", $hBitmap, "ptr", $hStream, "ptr", $pEncoder, "ptr", $pParams) _GDIPlus_BitmapDispose($hBitmap) Local $hMemory = DllCall("ole32.dll", "uint", "GetHGlobalFromStream", "ptr", $hStream, "ptr*", 0) If @error Then Return SetError(2, 0, 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)) ;http://msdn.microsoft.com/en-us/library/windows/desktop/ms221473(v=vs.85).aspx _MemGlobalFree($hMemory) Return $bData EndFunc ;==>_GDIPlus_SaveImageToStream Func StringProc($StrIn, $SplitMark); i think melba made this Local $StrOut = '', $count, $StrSplit, $StrLen $StrSplit = StringSplit($StrIn, @CRLF, 2) For $X = 0 To UBound($StrSplit) - 1 $StrLen = StringLen($StrSplit[$X]) If $StrLen > 17 Then $count = Ceiling(StringLen($StrSplit[$X]) / $SplitMark) Local $array[$count + 1], $start = 1 For $I = 0 To $count $array[$I] = StringMid($StrSplit[$X], $start, $SplitMark) $start += $SplitMark Next For $I = 0 To $count If $array[$I] = "" Or $array[$I] = " " Then ContinueLoop If StringInStr($array[$I], " ", 0, 1, 1, 1) Then $StrOut &= StringReplace(StringReplace(StringReplace($array[$I], @LF, ""), @CR, ""), " ", "", 1, 1) & @LF Else $StrOut &= StringReplace(StringReplace($array[$I], @LF, ""), @CR, "") & @LF EndIf Next Else If $StrSplit[$X] = "" Then ContinueLoop $StrOut &= StringReplace(StringReplace($StrSplit[$X], @LF, ""), @CR, "") & @LF EndIf Next Return $StrOut EndFunc ;==>StringProc Func _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $iStride = 0, $iPixelFormat = 0x0026200A, $pScan0 = 0) Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", $iStride, "int", $iPixelFormat, "ptr", $pScan0, "int*", 0) If @error Then Return SetError(@error, @extended, 0) Return $aResult[6] EndFunc ;==>_GDIPlus_BitmapCreateFromScan0 ;====================================================================================== ; Function Name: Load_BMP_From_Mem ; Description: Loads an image which is saved as a binary string and converts it to a bitmap or hbitmap ; ; Parameters: $bImage: the binary string which contains any valid image which is supported by GDI+ ; Optional: $hHBITMAP: if false a bitmap will be created, if true a hbitmap will be created ; ; Remark: hbitmap format is used generally for GUI internal images, $bitmap is more a GDI+ image format ; ; Requirement(s): GDIPlus.au3, Memory.au3 and _GDIPlus_BitmapCreateDIBFromBitmap() from WinAPIEx.au3 ; Return Value(s): Success: handle to bitmap or hbitmap, Error: 0 ; Error codes: 1: $bImage is not a binary string ; 2: unable to create stream on HGlobal ; 3: unable to create bitmap from stream ; ; Author(s): UEZ ; Additional Code: thanks to progandy for the MemGlobalAlloc and tVARIANT lines ; Version: v0.97 Build 2012-01-04 Beta ;======================================================================================= Func Load_BMP_From_Mem($bImage, $hHBITMAP = False) If Not IsBinary($bImage) Then Return SetError(1, 0, 0) Local $aResult Local Const $memBitmap = Binary($bImage) ;load image saved in variable (memory) and convert it to binary Local Const $len = BinaryLen($memBitmap) ;get length of image Local Const $hData = _MemGlobalAlloc($len, $GMEM_MOVEABLE) ;allocates movable memory ($GMEM_MOVEABLE = 0x0002) Local Const $pData = _MemGlobalLock($hData) ;translate the handle into a pointer Local $tMem = DllStructCreate("byte[" & $len & "]", $pData) ;create struct DllStructSetData($tMem, 1, $memBitmap) ;fill struct with image data _MemGlobalUnlock($hData) ;decrements the lock count associated with a memory object that was allocated with GMEM_MOVEABLE $aResult = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", "handle", $pData, "int", True, "ptr*", 0) ;Creates a stream object that uses an HGLOBAL memory handle to store the stream contents If @error Then SetError(2, 0, 0) Local Const $hStream = $aResult[3] $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromStream", "ptr", $hStream, "int*", 0) ;Creates a Bitmap object based on an IStream COM interface If @error Then SetError(3, 0, 0) Local Const $hBitmap = $aResult[2] 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)) ;release memory from $hStream to avoid memory leak $tMem = 0 $tVARIANT = 0 If $hHBITMAP Then Local Const $hHBmp = _GDIPlus_BitmapCreateDIBFromBitmap($hBitmap) _GDIPlus_BitmapDispose($hBitmap) Return $hHBmp EndIf Return $hBitmap EndFunc ;==>Load_BMP_From_Mem Func _GDIPlus_BitmapCreateDIBFromBitmap($hBitmap) Local $tBIHDR, $Ret, $tData, $pBits, $hResult = 0 $Ret = DllCall($ghGDIPDll, 'uint', 'GdipGetImageDimension', 'ptr', $hBitmap, 'float*', 0, 'float*', 0) If (@error) Or ($Ret[0]) Then Return 0 $tData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $Ret[2], $Ret[3], $GDIP_ILMREAD, $GDIP_PXF32ARGB) $pBits = DllStructGetData($tData, 'Scan0') If Not $pBits Then Return 0 $tBIHDR = DllStructCreate('dword;long;long;ushort;ushort;dword;dword;long;long;dword;dword') DllStructSetData($tBIHDR, 1, DllStructGetSize($tBIHDR)) DllStructSetData($tBIHDR, 2, $Ret[2]) DllStructSetData($tBIHDR, 3, $Ret[3]) DllStructSetData($tBIHDR, 4, 1) DllStructSetData($tBIHDR, 5, 32) DllStructSetData($tBIHDR, 6, 0) $hResult = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBIHDR), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'dword', 0) If (Not @error) And ($hResult[0]) Then DllCall('gdi32.dll', 'dword', 'SetBitmapBits', 'ptr', $hResult[0], 'dword', $Ret[2] * $Ret[3] * 4, 'ptr', DllStructGetData($tData, 'Scan0')) $hResult = $hResult[0] Else $hResult = 0 EndIf _GDIPlus_BitmapUnlockBits($hBitmap, $tData) Return $hResult EndFunc ;==>_GDIPlus_BitmapCreateDIBFromBitmap