Jump to content

Convert PNG and JPG to CUR in autoit


Recommended Posts

I don't think AutoIT has image conversion capabilities but you may be able to call a third party command line utility to convert and just pass it parameters.

Windows Cursor (.cur) file is same as icon (.ico) files.

Rename the file extension to ".cur"?

Edited by Confuzzled
Link to post
Share on other sites
On 5/13/2021 at 4:26 PM, Confuzzled said:

I don't think AutoIT has image conversion capabilities...

There is one since Dec-3-2007, named UEZ :D
With his script, I just tried to convert a transparent png (i.e. with alpha channel) to a cur file, hoping the cur would be transparent too... and it was, yes !

So now it's easy to create a few transparent cur files and use them as cursors, when desired, in AutoIt scripts.
Well done UEZ :thumbsup:

Link to post
Share on other sites
  • 1 year later...
On 5/14/2021 at 4:25 PM, UEZ said:

Try this:

;Coded by UEZ build 2021-05-14 beta
#include <GDIPlus.au3>
#include <WinAPIFiles.au3>

Global $sImageFile = FileOpenDialog("Select an GDI+ supported image", "", "Images (*.jpg;*.bmp;*.png;*.gif;*.tif;*.tiff)")
If @error Then Exit

_GDIPlus_Startup()
Global $hImage = _GDIPlus_ImageLoadFromFile($sImageFile)
$sImageFile = StringMid($sImageFile, StringInStr($sImageFile, "\", 0, -1) + 1)
$sImageFile = @ScriptDir & "\" & StringMid($sImageFile, 1, StringLen($sImageFile) - 4) & ".cur"
_GDIPlus_CreateCursorFileFromImage($hImage, $sImageFile, 32, 32)
If @error Then
    MsgBox($MB_ICONERROR, "Error", "Something went wrong!", 10)
Else
    MsgBox($MB_ICONINFORMATION, "Information", "Cursor file has been created. Check out: " & $sImageFile, 10)
EndIf
_GDIPlus_ImageDispose($hImage)
_GDIPlus_Shutdown()




; #FUNCTION# ====================================================================================================================
; Name ..........: _GDIPlus_CreateCursorFileFromImage
; Version .......: v0.15 build 2021-05-14 beta
; Description ...: Converts a GDI+ support image to a windows cursor format and saves it to disk.
; Syntax ........: _GDIPlus_CreateCursorFileFromImage($hImage[, $sFilename = ""[, $iWidth = 32[, $iHeight = 32]]])
; Parameters ....: $hImage              - a handle value.
;                  $sFilename           - [optional] a string value. Default is "".
;                  $iWidth              - [optional] an integer value. Default is 32.
;                  $iHeight             - [optional] an integer value. Default is 32.
;                  $iSpotX              - [optional] an integer value. Default is 0.
;                  $iSpotY              - [optional] an integer value. Default is 0.
; Return values .: True if file has been created
; Author ........: UEZ
; Modified ......:
; Remarks .......: If $sFilename is empty then the handle of the cursor will be returned instead. No animated cursor possible yet!
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _GDIPlus_CreateCursorFileFromImage($hImage, $sFilename = "", $iWidth = 32, $iHeight = 32, $iSpotX = 0, $iSpotY = 0)
    If $hImage = 0 Then Return SetError(1, 0, 0)
    Local $aDim = _GDIPlus_ImageGetDimension($hImage)
    If @error Then Return SetError(2, 0, 0)

    ;create image with scaled size
    $iWidth = $iWidth > 255 ? 255 : $iWidth < 1 ? 1 : $iWidth
    $iHeight = $iHeight > 255 ? 255 : $iHeight < 1 ? 1 : $iHeight
    Local Const $hImage_scaled = _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $GDIP_PXF32ARGB)
    Local Const $hCanvas = _GDIPlus_ImageGetGraphicsContext($hImage_scaled)
    _GDIPlus_GraphicsSetInterpolationMode($hCanvas, $GDIP_INTERPOLATIONMODE_HIGHQUALITYBICUBIC)
    _GDIPlus_GraphicsDrawImageRect($hCanvas, $hImage, 0, 0, $iWidth, $iHeight)
    Local Const $hIcon = _GDIPlus_HICONCreateFromBitmap($hImage_scaled)
    _GDIPlus_GraphicsDispose($hCanvas)
    _GDIPlus_ImageDispose($hImage_scaled)
    If $hIcon = 0 Then Return SetError(3, 0, 0)

    Local $iErr = 0
    If $sFilename <> "" Then
        If _WinAPI_SaveHICONToFile($sFilename, $hIcon) = 0 Then $iErr += 1
        _WinAPI_DestroyIcon($hIcon)
        If $iErr Then Return SetError(4, $iErr, 0)
    Else
        Local $aIcon = _WinAPI_GetIconInfo($hIcon)
        Local $hCursor = _WinAPI_CreateIconIndirect($aIcon[5], $aIcon[4], $iSpotX, $iSpotY, False)
        If $hCursor = 0 Then $iErr += 1
        _WinAPI_DestroyIcon($hIcon)
        If $iErr Then Return SetError(5, $iErr, 0)
        Return $hCursor
    EndIf

    Local $tagCur = "align 1;word;word ImageType;word NumberOfImgs;", $tagImgHeader = "byte Width;byte Height;byte PaletteColors;byte;word Format1;word Format2;dword Size;dword OffsetImg;"
    Local $tHeader = DllStructCreate($tagCur & $tagImgHeader), $iSize = DllStructGetSize($tHeader)

    ;read the header to the struct
    Local $nBytes
    Local $hFile = _WinAPI_CreateFile($sFilename, 2, 2)
    _WinAPI_ReadFile($hFile, $tHeader, $iSize, $nBytes)
    _WinAPI_CloseHandle($hFile)
    If $nBytes <> $iSize Then Return SetError(6, 0, 0)

    ;generate the file
    $nBytes = 0
    $tHeader.ImageType = 2
    $tHeader.Format1 = $iSpotX
    $tHeader.Format2 = $iSpotY
    $hFile = _WinAPI_CreateFile($sFilename, 2, 4)
    _WinAPI_SetFilePointer($hFile, 0)
    _WinAPI_WriteFile($hFile, $tHeader, $iSize, $nBytes)
    _WinAPI_CloseHandle($hFile)
    If $nBytes <> $iSize Then Return SetError(7, 0, 0)

    Return 1
EndFunc   ;==>_GDIPlus_CreateCursorFileFromImage

 

Almost, you must change 1 entry within the header of the cursor struct to become a cursor file.

To whomever also arriving here after hours of Google Search and cursing at the lack of a single straightforward answers on the web for how to create icon files, the header entry is ImageType -- 1 for icon files, 2 for cursor files, any other values are invalid -- according to this link: https://docs.fileformat.com/image/ico/

 

Here is a tweaked version of the script that asks if you would like to produce an ico or cur file:

#include <GDIPlus.au3>
#include <WinAPIFiles.au3>

Global $sImageFile = FileOpenDialog("Select an GDI+ supported image", "", "Images (*.jpg;*.bmp;*.png;*.gif;*.tif;*.tiff)")
If @error Then Exit
Global $iImageType = Number(InputBox("Select Type", "Cursor or Icon? (1 for icon, 2 for cusor)", "2"))
If @error Then Exit
_GDIPlus_Startup()
Global $hImage = _GDIPlus_ImageLoadFromFile($sImageFile)
$sImageFile = StringMid($sImageFile, StringInStr($sImageFile, "\", 0, -1) + 1)
$sImageFile = @ScriptDir & "\" & StringMid($sImageFile, 1, StringLen($sImageFile) - 4) & ($iImageType = 2 ? ".cur" :".ico")
_GDIPlus_CreateCurIcoFileFromImage($hImage, $sImageFile, 32, 32)
If @error Then
    MsgBox($MB_ICONERROR, "Error", "Something went wrong!", 10)
Else
    MsgBox($MB_ICONINFORMATION, "Information", ($iImageType=2?"Cursor":"Icon") & " file has been created. Check out: " & $sImageFile, 10)
EndIf
_GDIPlus_ImageDispose($hImage)
_GDIPlus_Shutdown()



Func _GDIPlus_CreateCurIcoFileFromImage($hImage, $sFilename = "", $iWidth = 32, $iHeight = 32, $iSpotX = 0, $iSpotY = 0, $iType = 2)
    If $hImage = 0 Then Return SetError(1, 0, 0)
    Local $aDim = _GDIPlus_ImageGetDimension($hImage)
    If @error Then Return SetError(2, 0, 0)

    ;create image with scaled size
    $iWidth = $iWidth > 255 ? 255 : $iWidth < 1 ? 1 : $iWidth
    $iHeight = $iHeight > 255 ? 255 : $iHeight < 1 ? 1 : $iHeight
    Local Const $hImage_scaled = _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $GDIP_PXF32ARGB)
    Local Const $hCanvas = _GDIPlus_ImageGetGraphicsContext($hImage_scaled)
    _GDIPlus_GraphicsSetInterpolationMode($hCanvas, $GDIP_INTERPOLATIONMODE_HIGHQUALITYBICUBIC)
    _GDIPlus_GraphicsDrawImageRect($hCanvas, $hImage, 0, 0, $iWidth, $iHeight)
    Local Const $hIcon = _GDIPlus_HICONCreateFromBitmap($hImage_scaled)
    _GDIPlus_GraphicsDispose($hCanvas)
    _GDIPlus_ImageDispose($hImage_scaled)
    If $hIcon = 0 Then Return SetError(3, 0, 0)

    Local $iErr = 0
    If $sFilename <> "" Then
        If _WinAPI_SaveHICONToFile($sFilename, $hIcon) = 0 Then $iErr += 1
        _WinAPI_DestroyIcon($hIcon)
        If $iErr Then Return SetError(4, $iErr, 0)
    Else
        Local $aIcon = _WinAPI_GetIconInfo($hIcon)
        Local $hCursor = _WinAPI_CreateIconIndirect($aIcon[5], $aIcon[4], $iSpotX, $iSpotY, False)
        If $hCursor = 0 Then $iErr += 1
        _WinAPI_DestroyIcon($hIcon)
        If $iErr Then Return SetError(5, $iErr, 0)
        Return $hCursor
    EndIf

    Local $tagCur = "align 1;word;word ImageType;word NumberOfImgs;", $tagImgHeader = "byte Width;byte Height;byte PaletteColors;byte;word Format1;word Format2;dword Size;dword OffsetImg;"
    Local $tHeader = DllStructCreate($tagCur & $tagImgHeader), $iSize = DllStructGetSize($tHeader)

    ;read the header to the struct
    Local $nBytes
    Local $hFile = _WinAPI_CreateFile($sFilename, 2, 2)
    _WinAPI_ReadFile($hFile, $tHeader, $iSize, $nBytes)
    _WinAPI_CloseHandle($hFile)
    If $nBytes <> $iSize Then Return SetError(6, 0, 0)

    ;generate the file
    $nBytes = 0
    $tHeader.ImageType = $iType
    $tHeader.Format1 = $iSpotX
    $tHeader.Format2 = $iSpotY
    $hFile = _WinAPI_CreateFile($sFilename, 2, 4)
    _WinAPI_SetFilePointer($hFile, 0)
    _WinAPI_WriteFile($hFile, $tHeader, $iSize, $nBytes)
    _WinAPI_CloseHandle($hFile)
    If $nBytes <> $iSize Then Return SetError(7, 0, 0)

    Return 1
EndFunc   ;==>_GDIPlus_CreateCursorFileFromImage

 

 

Now, any ideas on how to expand the UDF to allow multiple images to be included in the cursor/icon file?

Edited by AutoXenon
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
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By nacerbaaziz
      hello autoit team
      please i've a question for you.
      am creating a audio player
      and in this audio player i want to show the current trac info
      such as the total time and the position ... etc
      i know i can show it as label
      but the screen reader for the blind read the text every change
      because it have a screen scan
      what i want is to show this informations but such image or icon
      i mean i need to create
      GUICtrlCreatepic or GUICtrlCreateicon ....
      or some thing as that
      and show this informations as image on it
      i think that i can do that with the 
      _GDIPlus functions
      but i couldn't find the currect way to do it
      i tried the _GDIPlus_GraphicsDrawString
      but i couldn't know how it work
      what i need is a small example that create a GUI
      and add a multy line text to it as graphic or image.
      so i need a simple way because it will changed every sec
      i hope any one can help me to do that
      global $GUI = GUICreate("text", 400, 400) global $label = GUICtrlCreateLabel(GetText(), 10, 10, 380, 380) GUISetState() do sleep(100) until GUIGetMSG() = -3 exit func GetText() return StringFormat("file name is test.mp3 \r\n total time is 00:30:00 \r\n position is 00:05:50") endFunc  
    • By DigiBox
      Hello everyone,
      I decided to rewrite/convert some autohotkey scripts to autoit. I know Ahk pretty well, but I'm obviously new at autoit.
      I've done my best with this one and the problem I'm getting now is the error message "Error: Unknown function name".
      Forgive me if it's something simple, but like I said, I'm completely new at this (been at it for one day, while ahk for years).
      Here is the autoit script:
       
      #RequireAdmin If WinExists(@ScriptName) Then Exit AutoItWinSetTitle(@ScriptName) $slowness = IniRead ("extra.ini", "slownesss", slowness, "0") $slowdelay = IniRead ("extra.ini", "slownesss", slowdelay, "0") Global $Paused HotKeySet("{PAUSE}", "TogglePause") HotKeySet("{DELETE}", "Terminate") $track = 0 while 1 global $pos2 = mousegetpos() Local $coord1 = PixelSearch (511, 388, 511, 424, 0xBD302E, 30) If Not @error Then exitloop EndIf wend For $redloop = 1 to 10 step 1 global $pos2 = mousegetpos() local $coord2 = PixelSearch (511, 388, 511, 424, 0xBD302E, 30) If Not @error Then $track = 1 EndIf If @error Then ExitLoop EndIf If $redloop > 0 Then $fade = $redloop / 100 EndIf $move = $slowness + fade if $track = 1 Then global $pos1 = mousegetpos() $newx1 = $pos1-$xpos2 $newx2 = $pos2-$xpos1 $movex = $newx2/move _MouseMovePlus($movex,0) global $pos2 = mousegetpos() $track = 0 EndIf Next while 1 sleep 1 local $coord3 = PixelSearch (511, 388, 511, 424, 0xBD302E, 30) If @error Then exitloop EndIf WEnd Func TogglePause() $Paused = NOT $Paused While $Paused sleep(100) WEnd EndFunc ; mousemove------------------------------------------ Func _MouseMovePlus($X, $Y,$absolute = 0) global $MOUSEEVENTF_MOVE = 1 Local $MOUSEEVENTF_ABSOLUTE = 32768 DllCall("user32.dll", "none", "mouse_event", _ "long", $MOUSEEVENTF_MOVE + ($absolute*$MOUSEEVENTF_ABSOLUTE), _ "long", $X, _ "long", $Y, _ "long", 0, _ "long", 0) EndFunc Func Terminate() Exit 0 EndFunc  
      And here is the original Ahk script which I wrote (and works perfectly) :
       
      #SingleInstance force CoordMode, pixel,screen CoordMode, mouse,screen SetBatchLines -1 IniRead, slowness, extra.ini, slownesss, slowness IniRead, slowdelay, extra.ini, slownesss, slowdelay mouseXY(x,y) { DllCall("mouse_event",uint,1,int,x,int,y,uint,0,int,0) } track = 0 loop { mousegetpos, xpos2, ypos2 PixelSearch, Px, Py, 511, 388, 511, 424, 0xBD302E, 30, fast RGB if errorlevel = 0 { sleep slowdelay gosub, red } } red: loop, 10 { mousegetpos, xpos2, ypos2 PixelSearch, Px, Py, 511, 388, 511, 424, 0xBD302E, 30, fast RGB if errorlevel = 0 track = 1 if errorlevel = 1 break if (a_index > 0) fade := (a_index / 100) move := (slowness + fade) if track = 1 { MouseGetPos, xpos1, ypos1 newx1 := (xpos1-xpos2) newx2 := (xpos2-xpos1) mousexy(newx2/move, 0) mousegetpos, xpos2, ypos2 track = 0 } } loop { sleep 1 PixelSearch, Px, Py, 511, 388, 511, 424, 0xBD302E, 30, fast RGB if errorlevel = 1 return } return  
      Any help about the error is greatly appreciated and perhaps something else you may spot.
      Thanks in advance
    • By nooneclose
      I need help turning this string "20180913221626" into a formatted time string.
      I need to go from this: 20180913221626
      to this: 09/13/2018 10:16 PM
      I do not always know what the date will be so I can not just use a variable I need to actually convert/format. 
      I did see an older post in the forms that was basically the same question only the other guy did not post the working code and I can not figure out how to use _AD_GetObjectProperties properly to get what I want. 
      As always any help would be appreciated. 
      Here is the code I use to find the date, but it always gives me the unformatted version. 
      ;retrieve the items object $oItem = $oOutlook.Session.GetItemFromID($aItems[1][0], Default) $oItem.GetInspector $eSentOn = $oItem.SentOn ; When was the email sent? MsgBox("", "Sent On of the email", $eSentOn) ;******************************************************************************* ; Formats the date and time from the email ;******************************************************************************* ;Local $fDatenTime = _DateTimeFormat($eSentOn, 1) ;MsgBox("", "Formatted email time", $fDatenTime) $aProperties = _AD_GetObjectProperties($eSentOn) _ArrayDisplay($aProperties, "Did the conversion work?")  
    • By jtpr
      Has anybody ever imported a VuGen recording into AutoIT?  I like the recording cabability of VuGen and thought it would be great to use and then pull it into AutoIT to compile into an EXE.
       
      Jim
    • By FrancescoDiMuro
      Good evening
      I was looking around the forum if I could find a function that allows to convert a string into a 2 dimensional array...
      The first column of the array is always the same, but the rows could change...
      I have a pattern like:

      Column A|Column B
      Static Text 1|Data 1
      Static Text 2|Data 2
      Static Text 3|Data 3
      Static Text 4|Data 4

      Where, Static Text (1...4) will be always the same, and I don't want to change them... But, Data 1...4 are dynamic fields... So, I could have the pattern above AND I coould have the pattern I'm going to show you right below

      Column A|Column B
      Static Text 1|Data 1
      Static Text 2|Data 2
      Static Text 3|Data 3
      Static Text 4|Data 4
      Static Text 1|Data 5
      Static Text 2|Data 6
      Static Text 3|Data 7
      Static Text 4|Data 8

      How can I do in this case?

      Thanks for everyone's help


       
×
×
  • Create New...