Jump to content

Recommended Posts

Posted (edited)

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
Posted
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:

  • 1 year later...
Posted (edited)
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

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
×
×
  • Create New...