Sign in to follow this  
Followers 0
UritOR

Change wallpaper

2 posts in this topic

#1 ·  Posted

Hi all,

I'm trying to find how to draw an image (create a label in mspaint) and save it as .bmp. And set it to be a wallpaper

I also need to know what wallpaper is use now, for restore it when the script is closed.

What is the best way to do it? Do I need Gdi+ for it?  I use this code (which I found here in forum) to set a .bmp file as wallpaper:

Func _ChangeWallpaper($sFile,$iType)
    ; Changes the wallpaper to $sFilename using $iType as:
    ; 1 Tiled
    ; 2 Centered
    ; 3 Stretched
    ; any other value (usually 0) unchanged
    ;
    ; Returns
    ; 0 if everything is allright.
    ; -1 if $sFile does not exist. @error is set to 1
    ; -2 if £sFile is not a .bmp file. @error is set to 2

    If Not FileExists($sFile) Then
        SetError(1)
        Return -1
    EndIf
    If StringTrimLeft($sFile,StringInStr($sFile,'.',0,-1)) <> 'bmp' Then
        SetError(2)
        Return -2
    EndIf

    Select
        Case $iType = 1
            RegWrite('HKCU\Control Panel\Desktop','TileWallpaper','reg_sz','1')
            RegWrite('HKCU\Control Panel\Desktop','WallpaperStyle','reg_sz','0')
        Case $iType = 2
            RegWrite('HKCU\Control Panel\Desktop','TileWallpaper','reg_sz','0')
            RegWrite('HKCU\Control Panel\Desktop','WallpaperStyle','reg_sz','0')
        Case $iType = 3
            RegWrite('HKCU\Control Panel\Desktop','TileWallpaper','reg_sz','0')
            RegWrite('HKCU\Control Panel\Desktop','WallpaperStyle','reg_sz','2')
        Case Else

    EndSelect
    RegWrite('HKCU\Control Panel\Desktop','Wallpaper','reg_sz',$sFile)
    DllCall("User32.dll","int","SystemParametersInfo","int",20,"int",0,"str",$sFile,"int",0)
    Return 0
EndFunc

 

The flow that I understand should be:

1) Check what wallpaper is in use now. I can find the path to it by going to registry  key named "wallpaper" here :[HKEY_CURRENT_USER\Control Panel\Desktop]

2) Create a file mspaint

3) Create a label with its properties (size,color) in this file

3) Save this file in some temporary directory

4) Set a created file as a wallpaper using the above code

5) When the script is closed restore the old wallpaper.

 

So again, my question is how to create a .bmp file with label in it?

Share this post


Link to post
Share on other sites



#2 ·  Posted

Maybe this is something for you.
I made this a while ago but never finnished it.

#Include <GDIPlus.au3>

_GDIPlus_Startup ()
ConsoleWrite(@AppDataDir & "\Microsoft\Windows\Themes\TranscodedWallpaper" & @CRLF)
FileCopy(@AppDataDir & "\Microsoft\Windows\Themes\TranscodedWallpaper", @AppDataDir & "\Nend Software\Weerstation Online\Current Wallpaper.bmp", 8)
_setwallpaper(@AppDataDir & "\Nend Software\Weerstation Online\Current Wallpaper.bmp", 10, 1)
_GDIPlus_ShutDown()


Func _setwallpaper($pic, $style = 0, $warn = 1)
    If $warn = 1 then
        $m1 = @DesktopHeight/2
        $m2 = @DeskTopWidth/2
    EndIf
    If Not FileExists($pic) Then Return -1

    $sString = "Hello world"

    $hImage = _GDIPlus_ImageLoadFromFile($pic)
    $sCLSID = _GDIPlus_EncodersGetCLSID ("BMP")

    $GC = _GDIPlus_ImageGetGraphicsContext($hImage)


    $hFormat = _GDIPlus_StringFormatCreate()
    $hFamily = _GDIPlus_FontFamilyCreate("Arial")
    $hBrush = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
    $hFont = _GDIPlus_FontCreate($hFamily, 62, 2)
    $tLayout = _GDIPlus_RectFCreate(600, 110, 0, 0)
    $aInfo = _GDIPlus_GraphicsMeasureString($GC, $sString, $hFont, $tLayout, $hFormat)
    _GDIPlus_GraphicsDrawStringEx($GC, $sString, $hFont, $aInfo[0], $hFormat, $hBrush)

    $newBmp = _GDIPlus_BitmapCreateFromGraphics(@DeskTopWidth, @DesktopHeight, $GC)
    $newGC = _GDIPlus_ImageGetGraphicsContext($newBmp)
    _GDIPlus_GraphicsDrawImageRect($newGC, $hImage, 0, 0, @DeskTopWidth, @DesktopHeight)

    _GDIPlus_ImageSaveToFileEx($newBmp, @AppDataDir & "\Nend Software\Weerstation Online\Current Wallpaper set.bmp", $sCLSID)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_ImageDispose($newBmp)
    _GDIPlus_GraphicsDispose($GC)
    _GDIPlus_GraphicsDispose($newGC)

    Local $SPI_SETDESKWALLPAPER = 20
    Local $SPIF_UPDATEINIFILE = 1
    Local $SPIF_SENDCHANGE = 2
        RegWrite("HKEY_CURRENT_USER\Control Panel\Desktop\", "TileWallPaper", "REG_SZ", 0)
        RegWrite("HKEY_CURRENT_USER\Control Panel\Desktop\", "WallpaperStyle", "REG_SZ", $style)

    DllCall("user32.dll", "int", "SystemParametersInfo", _
         "int", $SPI_SETDESKWALLPAPER, _
         "int", 0, _
         "str", @AppDataDir & "\Nend Software\Weerstation Online\Current Wallpaper set.bmp", _
         "int", BitOR($SPIF_UPDATEINIFILE, $SPIF_SENDCHANGE))
    Return 0

    If $warn = 1 then
        Sleep(2000)
    EndIf
EndFunc ;==>_setwallpaper

 

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0

  • Similar Content

    • SimTheNo1
      By SimTheNo1
      I am busy with building a solution for change monitoring of VOIP call program and to be properly automated means among others need for some limited OCR functionality. Current works of others are way too much overkill for this case what makes the need to build it myself. But to do it properly I significantly have to increase my knowledge about digital graphics management.
      For now I already have discovered here and there some mind blowing  Autoit miracles what can be achieved with Windows own possibilities to manipulate that what is output to the monitor. And as far I can judge there are 2 options to process graphics without use of any external libraries like ImageMagick, FreeImage and so on. These are:
       WinAPI  GDIPlus It is for me quite obvious to have various holes in general understanding of graphics and it is once more very clear what advantages gives consistent general study in 1 or another official institutions like University.  Cause there you are introduced into certain domain of knowledge in a way which usually has been perfected over long period of time. So you are not overloaded by stuff which requires a certain amount of information to be initially clear for you. For example, before starting to solve physics you first learn to read, count and so on and then move to subjects like physics.
      Though in my case opportunity to study in such educational system I had only for 8 years, from my 7th to 15th year of age in the country that was falling apart now Ukraine but used to be USSR, was all what it was. After have immigrated to Netherlands possibilities to study further haven't occur. And this therefor causes often various implications when going deep in that or another field of practical knowledge acquiring for any needed physical result, like programming to perform enormous amount of tasks. In this particular case automating VOIP call program.
      Anyway, right now I think the best direction to move is to concentrate on as basic as possible image management and if someone would maybe explain in general what is a pixel will definitely help. Particularly I am very curious about how to do picture manipulations in Autoit. Especially would help a lot to produce eventually following functions:
      createImage($imageFileName, $width, $height, $color) readImagePixel($imageFileName, $x, $y)  writeImagePixel($imageFileName, $x, $y) I do not know exactly how image is handled in computer but preferably above mentioned functions should deal with so far possible origin of graphics creation on computer. But nevertheless I definitely would love to hear any proposition for solution.
      The problem with explaining screenshots:
       VOIPConnect full Window  Part of Window with control to monitor for changes  Exact location of area where actual changes occur and have to be processed  It comes down to a rectangle of approximately 51 pixel wide and 7 pixel high. In fact if I get to learn as far as to be able exactly read, write and compare 2 images consistently across different computers I could narrow down then even further the area to watch as little as a square of 2-5 pixels wide. 
      To finish here is last detail about particularly no need for ultra fast solution at all. This because it is needed only once when it is first run on a new computer and to have to wait few minutes while it is being set instead of just a few seconds make no sence.
      This is it and what I too think to do beside this very particular case is to purify out beautiful generic Autoit functions for core image manipulation by using WinAPI or/and GDIPlus. 
    • UEZ
      By UEZ
      Here a small function to mark a region on the desktop and capture that region to a bitmap handle or to the clipboard:
      #include-once #include <Clipboard.au3> #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <WinAPIGdi.au3> #include <WindowsConstants.au3> #Region Example ;capture manual coordinates FileDelete(@ScriptDir & "\Captured.bmp") Global $hHBitmap = _WinAPI_MarkScreenRegionAndCapture(0, False, True, 0, 0, 99, 99) _WinAPI_SaveHBITMAPToFile(@ScriptDir & "\Captured.bmp", $hHBitmap) _WinAPI_DeleteObject($hHBitmap) If FileExists(@ScriptDir & "\Captured.bmp") Then ShellExecute(@ScriptDir & "\Captured.bmp") ;save the captured bitmap to a file FileDelete(@ScriptDir & "\Captured.bmp") Global $hHBitmap = _WinAPI_MarkScreenRegionAndCapture() _WinAPI_SaveHBITMAPToFile(@ScriptDir & "\Captured.bmp", $hHBitmap) _WinAPI_DeleteObject($hHBitmap) If FileExists(@ScriptDir & "\Captured.bmp") Then ShellExecute(@ScriptDir & "\Captured.bmp") ;copy captured bitmap to clipboard Switch _WinAPI_MarkScreenRegionAndCapture(1, True) Case 1 MsgBox($MB_ICONINFORMATION, "Information", "Marked region was properly captured to clipboard!", 30) Case 0 MsgBox($MB_ICONERROR, "ERROR", "An error has occured!", 30) EndSwitch #EndRegion ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WinAPI_MarkScreenRegionAndCapture ; Description ...: Selected area on desktop will be captured and save to clipbord or GDI bitmap handle will be returned. ; Syntax ........: _WinAPI_MarkScreenRegionAndCapture([$iFillMode = 0[, $bClipboard = True]]) ; Parameters ....: $iFillMode - [optional] an integer value. Default is 0. ; 0: marked area filled with solid color ; 1: marked area filled with hatch pattern ($HS_DIAGCROSS) ; 2: marked area without any fill pattern / color - only red border ; $bClipboard - [optional] a boolean value. Default is False. If True then no GDI bitmap handle will be returned. ; If false then GDI bitmap handle will be returned. ; $bManual - [optional] a boolean value. Default is False. If True manual capturing is activated. ; $iX1 - [optional] an integer value. Default is 0. If $bManual is true enter the x1 screen pos. ; $iY1 - [optional] an integer value. Default is 0. If $bManual is true enter the Y1 screen pos. ; $iX2 - [optional] an integer value. Default is 0. If $bManual is true enter the x2 screen pos. ; $iY2 - [optional] an integer value. Default is 0. If $bManual is true enter the y2 screen pos. ; Return values .: 0 / 1 / -1 / GDI bitmap handle ; Author ........: UEZ ; Version .......: 0.92 build 2017-01-22 ; Modified ......: ; Remarks .......: Do not forget to dispose returned GDI bitmap handle for non clipboard mode using _WinAPI_DeleteObject! ; Related .......: ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _WinAPI_MarkScreenRegionAndCapture($iFillMode = 0, $bClipboard = False, $bManual = False, $iX1 = 0, $iY1 = 0, $iX2 = 0, $iY2 = 0) If @OSBuild > 6299 Then ;https://msdn.microsoft.com/en-us/library/windows/desktop/ms724832(v=vs.85).aspx DllCall("Shcore.dll", "long", "PROCESS_DPI_AWARENESS", 1) ;PROCESS_SYSTEM_DPI_AWARE = 1 (https://msdn.microsoft.com/en-us/library/windows/desktop/dn280512(v=vs.85).aspx) Else DllCall("User32.dll", "bool", "SetProcessDPIAware") EndIf Local $iOld = AutoItSetOption("MouseCoordMode", 1) If Not $bManual Then Local Const $hDesktop = WinGetHandle("[TITLE:Program Manager;CLASS:Progman]") Local Const $aFullScreen = WinGetPos($hDesktop) ;should work also on multi screens Local Const $iW = $aFullScreen[2], $iH = $aFullScreen[3] Local Const $hGUI_Screencapture = GUICreate("", $iW, $iH, $aFullScreen[0], $aFullScreen[1], $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_LAYERED)) GUISetState(@SW_SHOW, $hGUI_Screencapture) Local Const $hDC = _WinAPI_GetDC($hGUI_Screencapture) Local Const $hGfxDC = _WinAPI_CreateCompatibleDC($hDC) Local Const $hBitmapGDI = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH) Local $hObjOld = _WinAPI_SelectObject($hGfxDC, $hBitmapGDI) Local $tSize = DllStructCreate($tagSIZE) $tSize.x = $iW $tSize.y = $iH Local $tSource = DllStructCreate($tagPOINT) Local $tBlend = DllStructCreate($tagBLENDFUNCTION) $tBlend.Alpha = 0xFF $tBlend.Format = 1 Local $tDest = DllStructCreate($tagPOINT), $pPoint = DllStructGetPtr($tDest) $tDest.x = $aFullScreen[0] $tDest.y = $aFullScreen[1] Local Const $hPen = _WinAPI_CreatePen($PS_SOLID, 1, 0x0000FF) Local Const $hPen_Orig = _WinAPI_SelectObject($hGfxDC, $hPen) Local $hBrush, $iAlpha2, $iFlag $iFillMode = $iFillMode > 2 ? 2 : $iFillMode < 0 ? 0 : $iFillMode Switch $iFillMode Case 0 $hBrush = _WinAPI_CreateBrushIndirect($BS_SOLID, 0x808080) $iAlpha2 = 0xA0 $iFlag = $ULW_ALPHA Case 1 $hBrush = _WinAPI_CreateBrushIndirect($BS_HATCHED, 0x808000, $HS_DIAGCROSS) $iAlpha2 = 0x30 $iFlag = $ULW_ALPHA Case 2 $hBrush = _WinAPI_CreateBrushIndirect($BS_HOLLOW, 0x000000) $iAlpha2 = 0xFF ;not needed $iFlag = $ULW_COLORKEY EndSwitch Local $hBrush_Orig = _WinAPI_SelectObject($hGfxDC, $hBrush) Else If Not BitOr($iX1, $iX2, $iY1, $iY2) Then Return SetError(4, 0, 0) EndIf Local $aMPos[5], $aMPos_old[4], $tRECT = _WinAPI_CreateRect(0, 0, 0, 0) Do If $bManual Then $aMPos[2] = 1 Else GUISetCursor(16, 1, $hGUI_Screencapture) $aMPos = GUIGetCursorInfo($hGUI_Screencapture) $aMPos_old[0] = $aMPos[0] $aMPos_old[1] = $aMPos[1] $aMPos_old[2] = MouseGetPos(0) $aMPos_old[3] = MouseGetPos(1) EndIf Switch $aMPos[2] Case 0 ;display crosshair _WinAPI_BitBlt($hGfxDC, 0, 0, $iW, $iH, $hGfxDC, 0, 0, $CAPTUREBLT) _WinAPI_DrawLine($hGfxDC, $tDest.x, $aMPos[1], $iW, $aMPos[1]) _WinAPI_DrawLine($hGfxDC, $aMPos[0], $tDest.y, $aMPos[0], $iH) _WinAPI_UpdateLayeredWindow($hGUI_Screencapture, $hDC, $tDest, $tSize, $hGfxDC, $tSource, 0, $tBlend, $ULW_COLORKEY) Case 1 ;capture selected region If Not $bManual Then $tBlend.Alpha = $iAlpha2 While $aMPos[2] ;mark region GUISetCursor(14, 1, $hGUI_Screencapture) ;WinGetHandle(AutoItWinGetTitle())) $aMPos = GUIGetCursorInfo($hGUI_Screencapture) _WinAPI_BitBlt($hGfxDC, 0, 0, $iW, $iH, $hGfxDC, 0, 0, $CAPTUREBLT) ;clear bitmap ;draw rectangle $tRECT.Left = $aMPos_old[0] $tRECT.Top = $aMPos_old[1] $tRECT.Right = $aMPos[0] $tRECT.Bottom = $aMPos[1] _WinAPI_Rectangle($hGfxDC, $tRECT) If $iFillMode <> 2 Then _WinAPI_InvertRect($hGfxDC, $tRECT) _WinAPI_UpdateLayeredWindow($hGUI_Screencapture, $hDC, $tDest, $tSize, $hGfxDC, $tSource, 0, $tBlend, $iFlag) Sleep(10) WEnd _WinAPI_SelectObject($hGfxDC, $hObjOld) _WinAPI_ReleaseDC($hGUI_Screencapture, $hDC) _WinAPI_DeleteDC($hGfxDC) _WinAPI_DeleteObject($hBitmapGDI) _WinAPI_SelectObject($hGfxDC, $hPen_Orig) _WinAPI_DeleteObject($hPen) _WinAPI_SelectObject($hGfxDC, $hBrush_Orig) _WinAPI_DeleteObject($hBrush) GUIDelete($hGUI_Screencapture) ;capture region $aMPos[0] = MouseGetPos(0) $aMPos[1] = MouseGetPos(1) Else $aMPos_old[2] = $iX1 $aMPos_old[3] = $iY1 $aMPos[0] = $iX2 $aMPos[1] = $iY2 EndIf Local Const $hDC_Region = _WinAPI_GetDC(0) Local Const $hMemDC = _WinAPI_CreateCompatibleDC($hDC_Region) Local Const $iW_Region = Abs($aMPos[0] - $aMPos_old[2]) + 1, $iH_Region = Abs($aMPos[1] - $aMPos_old[3]) + 1 Local $hHBitmap_Captured = _WinAPI_CreateCompatibleBitmap($hDC_Region, $iW_Region, $iH_Region) $hObjOld = _WinAPI_SelectObject($hMemDC, $hHBitmap_Captured) _WinAPI_BitBlt($hMemDC, 0, 0, $iW_Region, $iH_Region, $hDC_Region, _ $aMPos[0] > $aMPos_old[2] ? $aMPos_old[2] : $aMPos[0], _ $aMPos[1] > $aMPos_old[3] ? $aMPos_old[3] : $aMPos[1], BitOR($SRCCOPY, $CAPTUREBLT)) Local $hHBitmap_Clipboard = _WinAPI_CopyImage($hHBitmap_Captured, 0, 0, 0, BitOR($LR_COPYDELETEORG, $LR_COPYRETURNORG)) _WinAPI_SelectObject($hHBitmap_Captured, $hObjOld) _WinAPI_DeleteDC($hHBitmap_Captured) _WinAPI_ReleaseDC(0, $hDC_Region) AutoItSetOption("MouseCoordMode", $iOld) If $bClipboard Then ;put captured region to clipboard If Not _ClipBoard_Open(0) Then _WinAPI_DeleteObject($hHBitmap_Clipboard) Return SetError(1, 0, 0) EndIf If Not _ClipBoard_Empty() Then _WinAPI_DeleteObject($hHBitmap_Clipboard) Return SetError(2, 0, 0) EndIf Local Const $hCP = _ClipBoard_SetDataEx($hHBitmap_Clipboard, $CF_BITMAP) If Not $hCP Or @error Then _WinAPI_DeleteObject($hHBitmap_Clipboard) Return SetError(3, 0, 0) EndIf _ClipBoard_Close() _WinAPI_DeleteObject($hHBitmap_Clipboard) Return 1 Else Return $hHBitmap_Clipboard EndIf EndSwitch Switch GUIGetMsg() Case $GUI_EVENT_CLOSE _WinAPI_SelectObject($hGfxDC, $hObjOld) _WinAPI_ReleaseDC($hGUI_Screencapture, $hDC) _WinAPI_DeleteDC($hGfxDC) _WinAPI_DeleteObject($hBitmapGDI) _WinAPI_SelectObject($hGfxDC, $hPen_Orig) _WinAPI_DeleteObject($hPen) GUIDelete($hGUI_Screencapture) AutoItSetOption("MouseCoordMode", $iOld) Return -1 EndSwitch Until False EndFunc ;==>_WinAPI_MarkScreenRegionAndCapture Might be useful...
       
      Download:  _WinAPI_MarkScreenRegionAndCapture.au3  (same as above in the code box)
       
      Tested only on Win10 x64 but should work also on other Window versions. If not please reply.
       
    • RyukShini
      By RyukShini
      #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Icon=car.ico #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <GDIPlus.au3> #include <File.au3> #include <Array.au3> #include <ColorConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <ProgressConstants.au3> ; Declare array Dim $Images[1] ; Gets all JPG files in the current directory (@ScriptDir). Local $search = FileFindFirstFile("*.jpg") ; Check if the search was successful If $search = -1 Then MsgBox(0, "Error", "No JPG files could be found.") Exit EndIf ; Resize array While 1 If IsArray($Images) Then Local $Bound = UBound($Images) ReDim $Images[$Bound+1] EndIf $Images[$Bound] = FileFindNextFile($search) If @error Then ExitLoop WEnd ; Close the search handle FileClose($search) ; Create directory "resized" if not there yet $nymappe = InputBox("Mappe / Bil Navn", "Mappe / Bil Navn") If NOT FileExists(@ScriptDir & "\" & $nymappe & "\") Then DirCreate(@ScriptDir & "\" & $nymappe & "\") EndIf ; Loop for JPGs - gets dimension of JPG and calls resize function to resize to 50% width and 50% height For $i = 1 to Ubound($Images)-1 If $Images[$i] <> "" AND FileExists(@ScriptDir & "\" & $Images[$i]) Then Local $ImagePath = @ScriptDir & "\" & $Images[$i] _GDIPlus_Startup() Local $hImage = _GDIPlus_ImageLoadFromFile($ImagePath) Local $ImageWidth = _GDIPlus_ImageGetWidth($hImage) Local $ImageHeight = _GDIPlus_ImageGetHeight($hImage) _GDIPlus_ImageDispose($hImage) _GDIPlus_Shutdown() ;MsgBox(0,"DEBUG", $ImageWidth & " x " & $ImageHeight) Local $NewImageWidth = ($ImageWidth / 100) * 15 Local $NewImageHeight = ($ImageHeight / 100) * 15 ;MsgBox(0,"DEBUG: " & $i,$Images[$i]) _ImageResize(@ScriptDir & "\" & $Images[$i], @ScriptDir & "\" & $nymappe & "\" & $Images[$i], $NewImageWidth, $NewImageHeight) EndIf Next ; Resize function Func _ImageResize($sInImage, $sOutImage, $iW, $iH) Local $hWnd, $hDC, $hBMP, $hImage1, $hImage2, $hGraphic, $CLSID, $i = 0 ;OutFile path, to use later on. Local $sOP = StringLeft($sOutImage, StringInStr($sOutImage, "\", 0, -1)) ;OutFile name, to use later on. Local $sOF = StringMid($sOutImage, StringInStr($sOutImage, "\", 0, -1) + 1) ;OutFile extension , to use for the encoder later on. Local $Ext = StringUpper(StringMid($sOutImage, StringInStr($sOutImage, ".", 0, -1) + 1)) ; Win api to create blank bitmap at the width and height to put your resized image on. $hWnd = _WinAPI_GetDesktopWindow() $hDC = _WinAPI_GetDC($hWnd) $hBMP = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH) _WinAPI_ReleaseDC($hWnd, $hDC) ;Start GDIPlus _GDIPlus_Startup() ;Get the handle of blank bitmap you created above as an image $hImage1 = _GDIPlus_BitmapCreateFromHBITMAP ($hBMP) ;Load the image you want to resize. $hImage2 = _GDIPlus_ImageLoadFromFile($sInImage) ;Get the graphic context of the blank bitmap $hGraphic = _GDIPlus_ImageGetGraphicsContext ($hImage1) ;Draw the loaded image onto the blank bitmap at the size you want _GDIPLus_GraphicsDrawImageRect($hGraphic, $hImage2, 0, 0, $iW, $iH) ;Get the encoder of to save the resized image in the format you want. $CLSID = _GDIPlus_EncodersGetCLSID($Ext) ;Generate a number for out file that doesn't already exist, so you don't overwrite an existing image. Do $i += 1 Until (Not FileExists($sOP & $i & "_" & $sOF)) ;Prefix the number to the begining of the output filename $sOutImage = $sOP & $i & "_" & $sOF ;Save the new resized image. _GDIPlus_ImageSaveToFileEx($hImage1, $sOutImage, $CLSID) ;Clean up and shutdown GDIPlus. _GDIPlus_ImageDispose($hImage1) _GDIPlus_ImageDispose($hImage2) _GDIPlus_GraphicsDispose ($hGraphic) _WinAPI_DeleteObject($hBMP) _GDIPlus_Shutdown() EndFunc Quality gets quite bad compared to using Paint / Photoshop when resizing with GDIPlus
      Any idea how to make the quality better?
      Thanks in advance
    • RyukShini
      By RyukShini
      Hello AutoIT masters

      I am gonna start writing a fun little script to resize X amount of images with the Horizontal/Vertical aspects to 15/15 instead of the standard 100/100

      I need to be able to do this with X amount of images and after changing the dimensions I need to save all the images in a path.
      so to keep things simple.

      1: File open prompt
      2: Choose X amount of images
      3: Automatically choose 15/15 for all images
      4: Save in path chosen by user
      5: Might be more to come.
      6: the faster the better!
       
      I am gonna start this project tomorrow, any help/references is highly appreciated!
      Thanks in advance and Wish me luck
       
       
      #### I Hit a bump on the road ###
      I successfully manage to do what I want to do and I successfully manage to rewrite names but 3 of the image names won't rename?
      So lets say I have 10 images that all get resized, then 7 of them gets renamed but not the last three, confuses me quite a bit?
      Thanks in advance!
      Rename script:
       
      Func renameall() local $path = @ScriptDir & "\" & $nymappe & "\" local $ret Local $hSearch = FileFindFirstFile($path & "*.jpg") $i = 1 While 1 $sFileName = FileFindNextFile($hSearch) If @error Then ExitLoop if FileMove($path & $sFileName, $path & String("NewName" & +$i) & ".jpg", 0) = 1 then ConsoleWrite($path & $sFileName & ' renamed to ' & $path & String("NewName" & +$i) & ".jpg" & @LF) Else ConsoleWrite('File rename failed for file = ' & $path & $sFileName & @LF) endif $i += 1 WEnd FileClose($hSearch) EndFunc Full script:
      #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Icon=car.ico #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <GDIPlus.au3> #include <File.au3> #include <Array.au3> #include <ColorConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <ProgressConstants.au3> ; Declare array Dim $Images[1] ; Gets all JPG files in the current directory (@ScriptDir). Local $search = FileFindFirstFile("*.jpg") ; Check if the search was successful If $search = -1 Then MsgBox(0, "Error", "No JPG files could be found.") Exit EndIf ; Resize array While 1 If IsArray($Images) Then Local $Bound = UBound($Images) ReDim $Images[$Bound+1] EndIf $Images[$Bound] = FileFindNextFile($search) If @error Then ExitLoop WEnd ; Close the search handle FileClose($search) ; Create directory "resized" if not there yet $nymappe = InputBox("Mappe / Bil Navn", "Mappe / Bil Navn") If NOT FileExists(@ScriptDir & "\" & $nymappe & "\") Then DirCreate(@ScriptDir & "\" & $nymappe & "\") EndIf ; Loop for JPGs - gets dimension of JPG and calls resize function to resize to 50% width and 50% height For $i = 1 to Ubound($Images)-1 If $Images[$i] <> "" AND FileExists(@ScriptDir & "\" & $Images[$i]) Then Local $ImagePath = @ScriptDir & "\" & $Images[$i] _GDIPlus_Startup() Local $hImage = _GDIPlus_ImageLoadFromFile($ImagePath) Local $ImageWidth = _GDIPlus_ImageGetWidth($hImage) Local $ImageHeight = _GDIPlus_ImageGetHeight($hImage) _GDIPlus_ImageDispose($hImage) _GDIPlus_Shutdown() ;MsgBox(0,"DEBUG", $ImageWidth & " x " & $ImageHeight) Local $NewImageWidth = ($ImageWidth / 100) * 15 Local $NewImageHeight = ($ImageHeight / 100) * 15 ;MsgBox(0,"DEBUG: " & $i,$Images[$i]) _ImageResize(@ScriptDir & "\" & $Images[$i], @ScriptDir & "\" & $nymappe & "\" & $Images[$i], $NewImageWidth, $NewImageHeight) EndIf Next ; Resize function Func _ImageResize($sInImage, $sOutImage, $iW, $iH) Local $hWnd, $hDC, $hBMP, $hImage1, $hImage2, $hGraphic, $CLSID, $i = 0 ;OutFile path, to use later on. Local $sOP = StringLeft($sOutImage, StringInStr($sOutImage, "\", 0, -1)) ;OutFile name, to use later on. Local $sOF = StringMid($sOutImage, StringInStr($sOutImage, "\", 0, -1) + 1) ;OutFile extension , to use for the encoder later on. Local $Ext = StringUpper(StringMid($sOutImage, StringInStr($sOutImage, ".", 0, -1) + 1)) ; Win api to create blank bitmap at the width and height to put your resized image on. $hWnd = _WinAPI_GetDesktopWindow() $hDC = _WinAPI_GetDC($hWnd) $hBMP = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH) _WinAPI_ReleaseDC($hWnd, $hDC) ;Start GDIPlus _GDIPlus_Startup() ;Get the handle of blank bitmap you created above as an image $hImage1 = _GDIPlus_BitmapCreateFromHBITMAP ($hBMP) ;Load the image you want to resize. $hImage2 = _GDIPlus_ImageLoadFromFile($sInImage) ;Get the graphic context of the blank bitmap $hGraphic = _GDIPlus_ImageGetGraphicsContext ($hImage1) ;Draw the loaded image onto the blank bitmap at the size you want _GDIPLus_GraphicsDrawImageRect($hGraphic, $hImage2, 0, 0, $iW, $iH) ;Get the encoder of to save the resized image in the format you want. $CLSID = _GDIPlus_EncodersGetCLSID($Ext) ;Generate a number for out file that doesn't already exist, so you don't overwrite an existing image. Do $i += 1 Until (Not FileExists($sOP & $i & "_" & $sOF)) ;Prefix the number to the begining of the output filename $sOutImage = $sOP & $i & "_" & $sOF ;Save the new resized image. _GDIPlus_ImageSaveToFileEx($hImage1, $sOutImage, $CLSID) ;Clean up and shutdown GDIPlus. _GDIPlus_ImageDispose($hImage1) _GDIPlus_ImageDispose($hImage2) _GDIPlus_GraphicsDispose ($hGraphic) _WinAPI_DeleteObject($hBMP) _GDIPlus_Shutdown() Call("renameall") EndFunc Func renameall() local $path = @ScriptDir & "\" & $nymappe & "\" local $ret Local $hSearch = FileFindFirstFile($path & "*.jpg") $i = 1 While 1 $sFileName = FileFindNextFile($hSearch) If @error Then ExitLoop if FileMove($path & $sFileName, $path & String("NewName" & +$i) & ".jpg", 0) = 1 then ConsoleWrite($path & $sFileName & ' renamed to ' & $path & String("NewName" & +$i) & ".jpg" & @LF) Else ConsoleWrite('File rename failed for file = ' & $path & $sFileName & @LF) endif $i += 1 WEnd FileClose($hSearch) EndFunc  
    • DrAhmed
      By DrAhmed
      Hey
      I'm not really familliar with GDI Plus , I am looking for how tocConvert a bitmap image to JPG in memory without saving it to disk
      Because I want to send it later via TCP directly without using FileRead and other stuff ..
      The only function I found is below but it saves the image in disk
      Func SaveBmp2JPG($Bitmap, $sSave = "Converted.jpg", $iQuality = 20) ;coded by UEZ 2013 If Not IsPtr($Bitmap) Then $Bitmap = _GDIPlus_ImageLoadFromFile($sFile) If @error Then Return SetError(1, 0, 0) EndIf Local $sCLSID = _GDIPlus_EncodersGetCLSID("JPG") Local $tParams = _GDIPlus_ParamInit(1) Local $tData = DllStructCreate("int Quality") Local $pData = DllStructGetPtr($tData) Local $pParams = DllStructGetPtr($tParams) DllStructSetData($tData, "Quality", $iQuality) _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData) If Not _GDIPlus_ImageSaveToFileEx($Bitmap, $sSave, $sCLSID, $pParams) Then Return SetError(2, 0, 0) Return True EndFunc what my code now looks like :
      #include <ScreenCapture.au3> #include <guiconstantsex.au3> #include <gdiplus.au3> #include <memory.au3> #include <staticconstants.au3> Global $ghGDIPDLL = $__g_hGDIPDll Example() Func Example() _GDIPlus_Startup() Local $hHBmp = _ScreenCapture_Capture("") ;create a GDI bitmap by capturing my desktop Local $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBmp) ;convert GDI bitmap to GDI+ bitmap _WinAPI_DeleteObject($hHBmp) ;release GDI bitmap resource because not needed anymore Local $hBitmap_Scaled2 = _GDIPlus_ImageResize($hBitmap, @DesktopWidth / 1.5, @DesktopHeight / 1.5) ;resize image SaveBmp2JPG($hBitmap_Scaled2,'Test.jpg',99) ; ===> Saving to disk ?? _GDIPlus_Shutdown() EndFunc ;==>Example Func SaveBmp2JPG($Bitmap, $sSave , $iQuality) ;coded by UEZ 2013 If Not IsPtr($Bitmap) Then $Bitmap = _GDIPlus_ImageLoadFromFile($sFile) If @error Then Return SetError(1, 0, 0) EndIf Local $sCLSID = _GDIPlus_EncodersGetCLSID("JPG") Local $tParams = _GDIPlus_ParamInit(1) Local $tData = DllStructCreate("int Quality") Local $pData = DllStructGetPtr($tData) Local $pParams = DllStructGetPtr($tParams) DllStructSetData($tData, "Quality", $iQuality) _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData) If Not _GDIPlus_ImageSaveToFileEx($Bitmap, $sSave, $sCLSID, $pParams) Then Return SetError(2, 0, 0) Return True EndFunc