пример как это делается
#include <GDIPlus.au3>
$sImageFile = FileOpenDialog('Select PNG File', '', 'Images (*.png;*.bmp;*.jpg;*.jpeg;*.gif)')
If @error Then Exit
$sIcoFile = @DesktopDir & "\" & StringRegExpReplace($sImageFile, '^.*\\|\.[^\.]*$', '') & '.ico'
_ImageConvertToIco($sImageFile, $sIcoFile, 32, 32)
Func _ImageConvertToIco($sImageFile, $sOutIconFile, $iWidth = -1, $iHeight = -1)
Local $hImage, $HICON, $sTmp
If $iWidth <> -1 And $iHeight <> -1 Then
$sTmp = @TempDir & '\~_ImageConvertToIco.' & StringRegExpReplace($sImageFile, '^.*\.', '')
__ImageResize($sImageFile, $sTmp, $iWidth, $iHeight)
$sImageFile = $sTmp
EndIf
; Start GDIPlus
_GDIPlus_Startup()
; Load image
$hImage = _GDIPlus_ImageLoadFromFile($sImageFile)
; create a HICON from the image
$HICON = __GDIPlus_BitmapCreateHICONFromBitmap($hImage)
;Clean up and shutdown GDIPlus
_GDIPlus_ImageDispose($hImage)
_GDIPlus_Shutdown()
; create an ico file from the image
__CreateIconFileFromHICON($HICON, $sOutIconFile)
; Destroy the HICON now I've finished with it.
_WinAPI_DestroyIcon($HICON)
; Remove temporary file
If $sTmp <> '' And FileExists($sTmp) Then
FileDelete($sTmp)
EndIf
EndFunc ;==>_ImageConvertToIco
Func __ImageResize($sFile, $sOutput, $iWidth, $iHeight)
Local $hBMP, $hImage1, $hImage2, $hGraphic
_GDIPlus_Startup()
$hBMP = _WinAPI_CreateBitmap($iWidth, $iHeight, 1, 32) ; Create a bitmap (handle)
$hImage1 = _GDIPlus_BitmapCreateFromHBITMAP($hBMP) ; Create a bitmap object from a bitmap handle.
$hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage1) ; Get the graphic context of the blank bitmap.
$hImage2 = _GDIPlus_ImageLoadFromFile($sFile) ; Load the image you want to resize.
_GDIPlus_GraphicsDrawImageRect($hGraphic, $hImage2, 0, 0, $iWidth, $iHeight) ;Draw the loaded image to the graphics of the blank bitmap at the size you want.
_GDIPlus_ImageSaveToFile($hImage1, $sOutput)
_GDIPlus_ImageDispose($hImage1)
_GDIPlus_ImageDispose($hImage2)
_GDIPlus_GraphicsDispose($hGraphic)
_WinAPI_DeleteObject($hBMP)
_GDIPlus_Shutdown()
EndFunc ;==>__ImageResize
Func __CreateIconFileFromHICON($HICON, $sOutIcon)
Local $aInfo, $sIco, $sBmp, $hCDC, $tBI, $tBits, $iSz, $sBD, $FO
; Start of single icon Header 3 x 2 bytes = 6 bytes: 0000 Reserved / 0100 icon / 0100 Numer of icons, total length will be 22 bytes for a single icon when finished
$sIco = "0x000001000100"
; Start of the Bitmap data header 1 x 4bytes: length of the header will be 40 bytes when finished. Will be appended to the end of the icon header when finished
$sBmp = "28000000"
; Get info about the HICON, this is mainly to get the pointers to the Color/Mask bitmaps data
$aInfo = _WinAPI_GetIconInfo($HICON)
; create a memory Compatable DC
$hCDC = _WinAPI_CreateCompatibleDC(0)
; create a BITMAPINFO Struct to store the Bitmap Info, it needs to be inilialized by setting the struct size.
$tBI = DllStructCreate($tagBITMAPINFO)
DllStructSetData($tBI, "Size", DllStructGetSize($tBI))
; Pass a bitmap data pointer to the BITMAPINFO struct so we can recieve the details of the color bitmap data, we use it to write the headers
_WinAPI_GetDIBits($hCDC, $aInfo[5], 0, 0, 0, DllStructGetPtr($tBI), 0)
; Now we have some the basic info to add to the icon & Bitmap header so we'll add that to the headers.
$sIco &= Hex(DllStructGetData($tBI, "Width"), 2) & Hex(DllStructGetData($tBI, "Height"), 2) & "00000100" & _
__StringReverseBytes(Hex(DllStructGetData($tBI, "BitCount"), 4))
$sBmp &= __StringReverseBytes(Hex(DllStructGetData($tBI, "Width"))) & __StringReverseBytes(Hex(DllStructGetData($tBI, "Height") * 2)) & "0100" & _
__StringReverseBytes(Hex(DllStructGetData($tBI, "BitCount"), 4)) & "00000000"
; Get the size of the Bitmap data from the BITMAPINFO Struct, we'll use this in the headers further on.
$iSz = DllStructGetData($tBI, "SizeImage")
; create a struct to store the Bitmap data Bits of the first bitmap, reset the BITMAPINFO struct
$tBits = DllStructCreate("byte[" & DllStructGetData($tBI, "SizeImage") & "]")
; Get the color bitmap dib bits into the $tBits struct.
DllCall('gdi32.dll', 'int', 'GetBitmapBits', 'ptr', $aInfo[5], 'int', $iSz, 'ptr', DllStructGetPtr($tBits))
; Get GetBitmapBits returns Bottom to Top dib, so I turn it to Top to Bottom dib ;)
; ATM I'm only assuming that GetBitmapBits returns a Bottom to Top dib, maybe the bitmap bits you use could be Top Down already?.
For $i = DllStructGetData($tBI, "SizeImage") + 1 To 0 Step -(DllStructGetData($tBI, "SizeImage") / DllStructGetData($tBI, "Height"))
$sBD &= StringTrimLeft(BinaryMid(DllStructGetData($tBits, 1), $i, (DllStructGetData($tBI, "SizeImage") / DllStructGetData($tBI, "Height"))), 2)
Next
;Clear the BITMAPINFO & $tBits Struct as we'll use the same variables again for the mask bitmap data
$tBits = 0
$tBI = 0
; create a BITMAPINFO Struct to store the Bitmap Info again, it needs to be inilialized by setting the struct size.
$tBI = DllStructCreate($tagBITMAPINFO)
DllStructSetData($tBI, "Size", DllStructGetSize($tBI))
; Pass a bitmap data pointer to the BITMAPINFO struct so we can recieve the details of the bitmask bitmap data
_WinAPI_GetDIBits($hCDC, $aInfo[4], 0, 0, 0, DllStructGetPtr($tBI), 0)
; We've finished with the Compatable DC, delete it.
_WinAPI_DeleteDC($hCDC)
; Add the size of the of the color + bitmask bitmap data as we need this for both the icon & Bitmap header
$iSz += DllStructGetData($tBI, "SizeImage")
; combine the bitmap data size with the bitmap header, I'm padding the rest of the 40 byte bitmap header with 0's., that's the Bitmap header done
$sBmp &= __StringReverseBytes(Hex($iSz)) & "00000000000000000000000000000000"
; Now add the size of the Bitmap data + bitmap header size and combine the icon header together with the bitmap header and color bitmap data
$sIco &= __StringReverseBytes(Hex($iSz + 40)) & __StringReverseBytes(Hex("22")) & $sBmp & $sBD
; create a struct to store the Bitmap dib Bits of the mask bitmap
$tBits = DllStructCreate("byte[" & DllStructGetData($tBI, "SizeImage") & "]")
; Get the mask bitmap dib bits into the $tBits struct.
DllCall('gdi32.dll', 'int', 'GetBitmapBits', 'ptr', $aInfo[4], 'int', DllStructGetData($tBI, "SizeImage"), 'ptr', DllStructGetPtr($tBits))
; Get GetBitmapBits returns Bottom to Top dib, so I turn it to a Top to Bottom dib and append the mask bitmap data to the icon
For $i = DllStructGetData($tBI, "SizeImage") + 1 To 0 Step -(DllStructGetData($tBI, "SizeImage") / DllStructGetData($tBI, "Height"))
$sIco &= StringTrimLeft(BinaryMid(DllStructGetData($tBits, 1), $i, (DllStructGetData($tBI, "SizeImage") / DllStructGetData($tBI, "Height"))), 2)
Next
; Write the icon to a file.
$FO = FileOpen($sOutIcon, 18)
FileWrite($sOutIcon, Binary($sIco))
FileClose($FO)
; Clear the structs
$tBits = 0
$tBI = 0
EndFunc ;==>_CreateIconFileFromHICON
; Reverse Byte String
Func __StringReverseBytes($sByte)
Local $aX = StringRegExp($sByte, "(.{2})", 3), $sX = ''
For $i = UBound($aX) - 1 To 0 Step -1
$sX &= $aX[$i]
Next
Return $sX
EndFunc ;==>__StringReverseBytes
Func __GDIPlus_BitmapCreateHICONFromBitmap($hBitmap)
Local $HICON
$HICON = DllCall($ghGDIPDll, "int", "GdipCreateHICONFromBitmap", "hwnd", $hBitmap, "int*", 0)
If @error Then Return SetError(@error, 0, -1)
Return SetError($HICON[0], 0, $HICON[2])
EndFunc ;==>_GDIPlus_BitmapCreateHICONFromBitmap
У Вас, кажется, опечатка, надо jpeg....$sImageFile = FileOpenDialog('Select PNG File', '', 'Images (*.png;*.bmp;*.jpg;*.jepg;*.gif)')...
Скорее всего что можно, у меня не получилось, но я если честно особо и не вдавался, поковырял код, поискал по оф. форуму, на первые попытки ничего толком не нашёл.Может быть можно что то сделать?
#include <GDIPlus.au3>
$sIcoFile = @DesktopDir & '\Test.ico'
_GDIPlus_Startup()
; Load image
$hImage = _GDIPlus_ImageLoadFromFile("48.png")
; create a HICON from the image
$HICON = __GDIPlus_BitmapCreateHICONFromBitmap($hImage)
;Clean up and shutdown GDIPlus
_GDIPlus_ImageDispose($hImage)
_GDIPlus_Shutdown()
; create an ico file from the image
__CreateIconFileFromHICON($HICON, $sIcoFile)
; Destroy the HICON now I've finished with it.
_WinAPI_DestroyIcon($HICON)
Func __CreateIconFileFromHICON($HICON, $sOutIcon)
Local $aInfo, $sIco, $sBmp, $hCDC, $tBI, $tBits, $iSz, $sBD, $FO
; Start of single icon Header 3 x 2 bytes = 6 bytes: 0000 Reserved / 0100 icon / 0100 Numer of icons, total length will be 22 bytes for a single icon when finished
$sIco = "0x000001000100"
; Start of the Bitmap data header 1 x 4bytes: length of the header will be 40 bytes when finished. Will be appended to the end of the icon header when finished
$sBmp = "28000000"
; Get info about the HICON, this is mainly to get the pointers to the Color/Mask bitmaps data
$aInfo = _WinAPI_GetIconInfo($HICON)
; create a memory Compatable DC
$hCDC = _WinAPI_CreateCompatibleDC(0)
; create a BITMAPINFO Struct to store the Bitmap Info, it needs to be inilialized by setting the struct size.
$tBI = DllStructCreate($tagBITMAPINFO)
DllStructSetData($tBI, "Size", DllStructGetSize($tBI))
; Pass a bitmap data pointer to the BITMAPINFO struct so we can recieve the details of the color bitmap data, we use it to write the headers
_WinAPI_GetDIBits($hCDC, $aInfo[5], 0, 0, 0, DllStructGetPtr($tBI), 0)
; Now we have some the basic info to add to the icon & Bitmap header so we'll add that to the headers.
$sIco &= Hex(DllStructGetData($tBI, "Width"), 2) & Hex(DllStructGetData($tBI, "Height"), 2) & "00000100" & _
__StringReverseBytes(Hex(DllStructGetData($tBI, "BitCount"), 4))
$sBmp &= __StringReverseBytes(Hex(DllStructGetData($tBI, "Width"))) & __StringReverseBytes(Hex(DllStructGetData($tBI, "Height") * 2)) & "0100" & _
__StringReverseBytes(Hex(DllStructGetData($tBI, "BitCount"), 4)) & "00000000"
; Get the size of the Bitmap data from the BITMAPINFO Struct, we'll use this in the headers further on.
$iSz = DllStructGetData($tBI, "SizeImage")
; create a struct to store the Bitmap data Bits of the first bitmap, reset the BITMAPINFO struct
$tBits = DllStructCreate("byte[" & DllStructGetData($tBI, "SizeImage") & "]")
; Get the color bitmap dib bits into the $tBits struct.
DllCall('gdi32.dll', 'int', 'GetBitmapBits', 'ptr', $aInfo[5], 'int', $iSz, 'ptr', DllStructGetPtr($tBits))
; Get GetBitmapBits returns Bottom to Top dib, so I turn it to Top to Bottom dib ;)
; ATM I'm only assuming that GetBitmapBits returns a Bottom to Top dib, maybe the bitmap bits you use could be Top Down already?.
For $i = DllStructGetData($tBI, "SizeImage") + 1 To 0 Step -(DllStructGetData($tBI, "SizeImage") / DllStructGetData($tBI, "Height"))
$sBD &= StringTrimLeft(BinaryMid(DllStructGetData($tBits, 1), $i, (DllStructGetData($tBI, "SizeImage") / DllStructGetData($tBI, "Height"))), 2)
Next
;Clear the BITMAPINFO & $tBits Struct as we'll use the same variables again for the mask bitmap data
$tBits = 0
$tBI = 0
; create a BITMAPINFO Struct to store the Bitmap Info again, it needs to be inilialized by setting the struct size.
$tBI = DllStructCreate($tagBITMAPINFO)
DllStructSetData($tBI, "Size", DllStructGetSize($tBI))
; Pass a bitmap data pointer to the BITMAPINFO struct so we can recieve the details of the bitmask bitmap data
_WinAPI_GetDIBits($hCDC, $aInfo[4], 0, 0, 0, DllStructGetPtr($tBI), 0)
; We've finished with the Compatable DC, delete it.
_WinAPI_DeleteDC($hCDC)
; Add the size of the of the color + bitmask bitmap data as we need this for both the icon & Bitmap header
$iSz += DllStructGetData($tBI, "SizeImage")
; combine the bitmap data size with the bitmap header, I'm padding the rest of the 40 byte bitmap header with 0's., that's the Bitmap header done
$sBmp &= __StringReverseBytes(Hex($iSz)) & "00000000000000000000000000000000"
; Now add the size of the Bitmap data + bitmap header size and combine the icon header together with the bitmap header and color bitmap data
$sIco &= __StringReverseBytes(Hex($iSz + 40)) & __StringReverseBytes(Hex("22")) & $sBmp & $sBD
; create a struct to store the Bitmap dib Bits of the mask bitmap
$tBits = DllStructCreate("byte[" & DllStructGetData($tBI, "SizeImage") & "]")
; Get the mask bitmap dib bits into the $tBits struct.
DllCall('gdi32.dll', 'int', 'GetBitmapBits', 'ptr', $aInfo[4], 'int', DllStructGetData($tBI, "SizeImage"), 'ptr', DllStructGetPtr($tBits))
; Get GetBitmapBits returns Bottom to Top dib, so I turn it to a Top to Bottom dib and append the mask bitmap data to the icon
For $i = DllStructGetData($tBI, "SizeImage") + 1 To 0 Step -(DllStructGetData($tBI, "SizeImage") / DllStructGetData($tBI, "Height"))
$sIco &= StringTrimLeft(BinaryMid(DllStructGetData($tBits, 1), $i, (DllStructGetData($tBI, "SizeImage") / DllStructGetData($tBI, "Height"))), 2)
Next
; Write the icon to a file.
$FO = FileOpen($sOutIcon, 18)
FileWrite($sOutIcon, Binary($sIco))
FileClose($FO)
; Clear the structs
$tBits = 0
$tBI = 0
EndFunc ;==>_CreateIconFileFromHICON
; Reverse Byte String
Func __StringReverseBytes($sByte)
Local $aX = StringRegExp($sByte, "(.{2})", 3), $sX = ''
For $i = UBound($aX) - 1 To 0 Step -1
$sX &= $aX[$i]
Next
Return $sX
EndFunc ;==>__StringReverseBytes
Func __GDIPlus_BitmapCreateHICONFromBitmap($hBitmap)
Local $HICON
$HICON = DllCall($ghGDIPDll, "int", "GdipCreateHICONFromBitmap", "hwnd", $hBitmap, "int*", 0)
If @error Then Return SetError(@error, 0, -1)
Return SetError($HICON[0], 0, $HICON[2])
EndFunc ;==>_GDIPlus_BitmapCreateHICONFromBitmap
#Include <FreeImage.au3>
_FreeImage_LoadDLL(@ScriptDir & '\FreeImage.dll')
_FreeImage_Initialise()
$hImage = _FreeImage_LoadU($FIF_PNG, @ScriptDir & '\48.png')
_FreeImage_SaveU($FIF_ICO, $hImage, @ScriptDir & '\48.ico')
_FreeImage_Unload($hImage)
_FreeImage_DeInitialise()
_FreeImage_UnLoadDLL()
assch сказал(а):И всё же вопрос на последок какой функцией лучше обрезать размеры изображения(Восновном нужен для Png)
Чтобы не гасились прозрачные пиксилы.
#Include <GDIPlus.au3>
_GDIPlus_Startup()
$hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & '\48.png')
$hThumb = _GDIPlus_ImageGetThumbnail($hImage, 32, 32) ; <= Это уменьшенное изображение (32x32)
_GDIPlus_ImageSaveToFile($hThumb, @ScriptDir & '\32.png')
_GDIPlus_ImageDispose($hThumb)
_GDIPlus_ImageDispose($hImage)
_GDIPlus_ShutDown()
Func _GDIPlus_ImageGetThumbnail($hImage, $iWidth, $iHeight)
Local $aResult = DllCall($ghGDIPDll, 'uint', 'GdipGetImageThumbnail', 'ptr', $hImage, 'uint', $iWidth, 'uint', $iHeight, 'ptr*', 0, 'ptr', 0, 'ptr', 0)
If @error Then
Return SetError(1, 0, 0)
Else
If $aResult[0] Then
Return SetError($aResult[0], 0, 0)
EndIf
EndIf
Return $aResult[4]
EndFunc ;==>_GDIPlus_ImageGetThumbnail
#include <GDIPlus.au3>
$sImageFile = FileOpenDialog('Select PNG File', '', 'Images (*.png;*.bmp;*.jpg;*.jpeg;*.gif)')
If @error Then Exit
$sIcoFile = @DesktopDir & "\" & StringRegExpReplace($sImageFile, '^.*\\|\.[^\.]*$', '') & '.ico'
_ImageConvertToIco($sImageFile, $sIcoFile, 24, 24)
ShellExecute($sIcoFile)
Func _ImageConvertToIco($sImageFile, $sOutIconFile, $iWidth = -1, $iHeight = -1)
Local $sTmp, $hImage, $hGC, $hBmp, $hBmpGC, $HICON
; Start GDIPlus
_GDIPlus_Startup()
If $iWidth <> -1 And $iHeight <> -1 Then
$sTmp = @TempDir & '\~_ImageConvertToIco.' & StringRegExpReplace($sImageFile, '^.*\.', '')
; Load Image
$hImage = _GDIPlus_ImageLoadFromFile($sImageFile)
;Create New image
$hGC = _GDIPlus_ImageGetGraphicsContext($hImage)
$hBmp = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGC)
$hBmpGC = _GDIPlus_ImageGetGraphicsContext($hBmp)
;Draw
_GDIPlus_GraphicsDrawImageRect($hBmpGC, $hImage, 0, 0, $iWidth, $iHeight)
_GDIPlus_ImageSaveToFile($hBmp, $sTmp)
;Clenaup
_GDIPlus_GraphicsDispose($hGC)
_GDIPlus_GraphicsDispose($hBmpGC)
_GDIPlus_BitmapDispose($hBmp)
_GDIPlus_ImageDispose($hImage)
$sImageFile = $sTmp
EndIf
; Load image
$hImage = _GDIPlus_ImageLoadFromFile($sImageFile)
; create a HICON from the image
$HICON = __GDIPlus_BitmapCreateHICONFromBitmap($hImage)
;Clean up and shutdown GDIPlus
_GDIPlus_ImageDispose($hImage)
_GDIPlus_Shutdown()
; create an ico file from the image
__CreateIconFileFromHICON($HICON, $sOutIconFile)
; Destroy the HICON now I've finished with it.
_WinAPI_DestroyIcon($HICON)
; Remove temporary file
If $sTmp <> '' And FileExists($sTmp) Then
FileDelete($sTmp)
EndIf
EndFunc ;==>_ImageConvertToIco
Func __CreateIconFileFromHICON($HICON, $sOutIcon)
Local $aInfo, $sIco, $sBmp, $hCDC, $tBI, $tBits, $iSz, $sBD, $FO
; Start of single icon Header 3 x 2 bytes = 6 bytes: 0000 Reserved / 0100 icon / 0100 Numer of icons, total length will be 22 bytes for a single icon when finished
$sIco = "0x000001000100"
; Start of the Bitmap data header 1 x 4bytes: length of the header will be 40 bytes when finished. Will be appended to the end of the icon header when finished
$sBmp = "28000000"
; Get info about the HICON, this is mainly to get the pointers to the Color/Mask bitmaps data
$aInfo = _WinAPI_GetIconInfo($HICON)
; create a memory Compatable DC
$hCDC = _WinAPI_CreateCompatibleDC(0)
; create a BITMAPINFO Struct to store the Bitmap Info, it needs to be inilialized by setting the struct size.
$tBI = DllStructCreate($tagBITMAPINFO)
DllStructSetData($tBI, "Size", DllStructGetSize($tBI))
; Pass a bitmap data pointer to the BITMAPINFO struct so we can recieve the details of the color bitmap data, we use it to write the headers
_WinAPI_GetDIBits($hCDC, $aInfo[5], 0, 0, 0, DllStructGetPtr($tBI), 0)
; Now we have some the basic info to add to the icon & Bitmap header so we'll add that to the headers.
$sIco &= Hex(DllStructGetData($tBI, "Width"), 2) & Hex(DllStructGetData($tBI, "Height"), 2) & "00000100" & _
__StringReverseBytes(Hex(DllStructGetData($tBI, "BitCount"), 4))
$sBmp &= __StringReverseBytes(Hex(DllStructGetData($tBI, "Width"))) & __StringReverseBytes(Hex(DllStructGetData($tBI, "Height") * 2)) & "0100" & _
__StringReverseBytes(Hex(DllStructGetData($tBI, "BitCount"), 4)) & "00000000"
; Get the size of the Bitmap data from the BITMAPINFO Struct, we'll use this in the headers further on.
$iSz = DllStructGetData($tBI, "SizeImage")
; create a struct to store the Bitmap data Bits of the first bitmap, reset the BITMAPINFO struct
$tBits = DllStructCreate("byte[" & DllStructGetData($tBI, "SizeImage") & "]")
; Get the color bitmap dib bits into the $tBits struct.
DllCall('gdi32.dll', 'int', 'GetBitmapBits', 'ptr', $aInfo[5], 'int', $iSz, 'ptr', DllStructGetPtr($tBits))
; Get GetBitmapBits returns Bottom to Top dib, so I turn it to Top to Bottom dib ;)
; ATM I'm only assuming that GetBitmapBits returns a Bottom to Top dib, maybe the bitmap bits you use could be Top Down already?.
For $i = DllStructGetData($tBI, "SizeImage") + 1 To 0 Step -(DllStructGetData($tBI, "SizeImage") / DllStructGetData($tBI, "Height"))
$sBD &= StringTrimLeft(BinaryMid(DllStructGetData($tBits, 1), $i, (DllStructGetData($tBI, "SizeImage") / DllStructGetData($tBI, "Height"))), 2)
Next
;Clear the BITMAPINFO & $tBits Struct as we'll use the same variables again for the mask bitmap data
$tBits = 0
$tBI = 0
; create a BITMAPINFO Struct to store the Bitmap Info again, it needs to be inilialized by setting the struct size.
$tBI = DllStructCreate($tagBITMAPINFO)
DllStructSetData($tBI, "Size", DllStructGetSize($tBI))
; Pass a bitmap data pointer to the BITMAPINFO struct so we can recieve the details of the bitmask bitmap data
_WinAPI_GetDIBits($hCDC, $aInfo[4], 0, 0, 0, DllStructGetPtr($tBI), 0)
; We've finished with the Compatable DC, delete it.
_WinAPI_DeleteDC($hCDC)
; Add the size of the of the color + bitmask bitmap data as we need this for both the icon & Bitmap header
$iSz += DllStructGetData($tBI, "SizeImage")
; combine the bitmap data size with the bitmap header, I'm padding the rest of the 40 byte bitmap header with 0's., that's the Bitmap header done
$sBmp &= __StringReverseBytes(Hex($iSz)) & "00000000000000000000000000000000"
; Now add the size of the Bitmap data + bitmap header size and combine the icon header together with the bitmap header and color bitmap data
$sIco &= __StringReverseBytes(Hex($iSz + 40)) & __StringReverseBytes(Hex("22")) & $sBmp & $sBD
; create a struct to store the Bitmap dib Bits of the mask bitmap
$tBits = DllStructCreate("byte[" & DllStructGetData($tBI, "SizeImage") & "]")
; Get the mask bitmap dib bits into the $tBits struct.
DllCall('gdi32.dll', 'int', 'GetBitmapBits', 'ptr', $aInfo[4], 'int', DllStructGetData($tBI, "SizeImage"), 'ptr', DllStructGetPtr($tBits))
; Get GetBitmapBits returns Bottom to Top dib, so I turn it to a Top to Bottom dib and append the mask bitmap data to the icon
For $i = DllStructGetData($tBI, "SizeImage") + 1 To 0 Step -(DllStructGetData($tBI, "SizeImage") / DllStructGetData($tBI, "Height"))
$sIco &= StringTrimLeft(BinaryMid(DllStructGetData($tBits, 1), $i, (DllStructGetData($tBI, "SizeImage") / DllStructGetData($tBI, "Height"))), 2)
Next
; Write the icon to a file.
$FO = FileOpen($sOutIcon, 18)
FileWrite($sOutIcon, Binary($sIco))
FileClose($FO)
; Clear the structs
$tBits = 0
$tBI = 0
EndFunc ;==>_CreateIconFileFromHICON
; Reverse Byte String
Func __StringReverseBytes($sByte)
Local $aX = StringRegExp($sByte, "(.{2})", 3), $sX = ''
For $i = UBound($aX) - 1 To 0 Step -1
$sX &= $aX[$i]
Next
Return $sX
EndFunc ;==>__StringReverseBytes
Func __GDIPlus_BitmapCreateHICONFromBitmap($hBitmap)
Local $HICON
$HICON = DllCall($ghGDIPDll, "int", "GdipCreateHICONFromBitmap", "hwnd", $hBitmap, "int*", 0)
If @error Then Return SetError(@error, 0, -1)
Return SetError($HICON[0], 0, $HICON[2])
EndFunc ;==>_GDIPlus_BitmapCreateHICONFromBitmap
_GDIPlus_ImageGetThumbnail
#include <GDIPlus.au3>
$sImageFile = FileOpenDialog('Select Image File', '', 'Images (*.png;*.bmp;*.jpg;*.jpeg;*.gif)')
If @error Then Exit
$sIcoFile = @DesktopDir & "\" & StringRegExpReplace($sImageFile, '^.*\\|\.[^\.]*$', '') & '.ico'
_ImageConvertToIco($sImageFile, $sIcoFile, 32, 32)
ShellExecute($sIcoFile)
Func _ImageConvertToIco($sImageFile, $sOutIconFile, $iWidth = -1, $iHeight = -1)
Local $hImage, $hThumb, $HICON
; Start GDIPlus
_GDIPlus_Startup()
; Load image
$hImage = _GDIPlus_ImageLoadFromFile($sImageFile)
If $iWidth = -1 Then
$iWidth = _GDIPlus_ImageGetWidth($hImage)
EndIf
If $iHeight = -1 Then
$iHeight = _GDIPlus_ImageGetHeight($hImage)
EndIf
; Get Thumbnail (resize the image)
$hThumb = __GDIPlus_ImageGetThumbnail($hImage, $iWidth, $iHeight)
; create a HICON from the image
$HICON = __GDIPlus_BitmapCreateHICONFromBitmap($hThumb)
;Clean up and shutdown GDIPlus
_GDIPlus_ImageDispose($hImage)
_GDIPlus_ImageDispose($hThumb)
_GDIPlus_Shutdown()
; create an ico file from the image
__CreateIconFileFromHICON($HICON, $sOutIconFile)
; Destroy the HICON now I've finished with it.
_WinAPI_DestroyIcon($HICON)
EndFunc ;==>_ImageConvertToIco
Func __GDIPlus_ImageGetThumbnail($hImage, $iWidth, $iHeight)
Local $aResult = DllCall($ghGDIPDll, 'uint', 'GdipGetImageThumbnail', 'ptr', $hImage, 'uint', $iWidth, 'uint', $iHeight, 'ptr*', 0, 'ptr', 0, 'ptr', 0)
If @error Then
Return SetError(1, 0, 0)
Else
If $aResult[0] Then
Return SetError($aResult[0], 0, 0)
EndIf
EndIf
Return $aResult[4]
EndFunc ;==>_GDIPlus_ImageGetThumbnail
Func __GDIPlus_BitmapCreateHICONFromBitmap($hBitmap)
Local $HICON = DllCall($ghGDIPDll, "int", "GdipCreateHICONFromBitmap", "hwnd", $hBitmap, "int*", 0)
If @error Then
Return SetError(@error, 0, -1)
EndIf
Return SetError($HICON[0], 0, $HICON[2])
EndFunc ;==>_GDIPlus_BitmapCreateHICONFromBitmap
Func __CreateIconFileFromHICON($HICON, $sOutIcon)
Local $aInfo, $sIco, $sBmp, $hCDC, $tBI, $tBits, $iSz, $sBD, $FO
; Start of single icon Header 3 x 2 bytes = 6 bytes: 0000 Reserved / 0100 icon / 0100 Numer of icons, total length will be 22 bytes for a single icon when finished
$sIco = "0x000001000100"
; Start of the Bitmap data header 1 x 4bytes: length of the header will be 40 bytes when finished. Will be appended to the end of the icon header when finished
$sBmp = "28000000"
; Get info about the HICON, this is mainly to get the pointers to the Color/Mask bitmaps data
$aInfo = _WinAPI_GetIconInfo($HICON)
; create a memory Compatable DC
$hCDC = _WinAPI_CreateCompatibleDC(0)
; create a BITMAPINFO Struct to store the Bitmap Info, it needs to be inilialized by setting the struct size.
$tBI = DllStructCreate($tagBITMAPINFO)
DllStructSetData($tBI, "Size", DllStructGetSize($tBI))
; Pass a bitmap data pointer to the BITMAPINFO struct so we can recieve the details of the color bitmap data, we use it to write the headers
_WinAPI_GetDIBits($hCDC, $aInfo[5], 0, 0, 0, DllStructGetPtr($tBI), 0)
; Now we have some the basic info to add to the icon & Bitmap header so we'll add that to the headers.
$sIco &= Hex(DllStructGetData($tBI, "Width"), 2) & Hex(DllStructGetData($tBI, "Height"), 2) & "00000100" & _
__StringReverseBytes(Hex(DllStructGetData($tBI, "BitCount"), 4))
$sBmp &= __StringReverseBytes(Hex(DllStructGetData($tBI, "Width"))) & __StringReverseBytes(Hex(DllStructGetData($tBI, "Height") * 2)) & "0100" & _
__StringReverseBytes(Hex(DllStructGetData($tBI, "BitCount"), 4)) & "00000000"
; Get the size of the Bitmap data from the BITMAPINFO Struct, we'll use this in the headers further on.
$iSz = DllStructGetData($tBI, "SizeImage")
; create a struct to store the Bitmap data Bits of the first bitmap, reset the BITMAPINFO struct
$tBits = DllStructCreate("byte[" & DllStructGetData($tBI, "SizeImage") & "]")
; Get the color bitmap dib bits into the $tBits struct.
DllCall('gdi32.dll', 'int', 'GetBitmapBits', 'ptr', $aInfo[5], 'int', $iSz, 'ptr', DllStructGetPtr($tBits))
; Get GetBitmapBits returns Bottom to Top dib, so I turn it to Top to Bottom dib ;)
; ATM I'm only assuming that GetBitmapBits returns a Bottom to Top dib, maybe the bitmap bits you use could be Top Down already?.
For $i = DllStructGetData($tBI, "SizeImage") + 1 To 0 Step -(DllStructGetData($tBI, "SizeImage") / DllStructGetData($tBI, "Height"))
$sBD &= StringTrimLeft(BinaryMid(DllStructGetData($tBits, 1), $i, (DllStructGetData($tBI, "SizeImage") / DllStructGetData($tBI, "Height"))), 2)
Next
;Clear the BITMAPINFO & $tBits Struct as we'll use the same variables again for the mask bitmap data
$tBits = 0
$tBI = 0
; create a BITMAPINFO Struct to store the Bitmap Info again, it needs to be inilialized by setting the struct size.
$tBI = DllStructCreate($tagBITMAPINFO)
DllStructSetData($tBI, "Size", DllStructGetSize($tBI))
; Pass a bitmap data pointer to the BITMAPINFO struct so we can recieve the details of the bitmask bitmap data
_WinAPI_GetDIBits($hCDC, $aInfo[4], 0, 0, 0, DllStructGetPtr($tBI), 0)
; We've finished with the Compatable DC, delete it.
_WinAPI_DeleteDC($hCDC)
; Add the size of the of the color + bitmask bitmap data as we need this for both the icon & Bitmap header
$iSz += DllStructGetData($tBI, "SizeImage")
; combine the bitmap data size with the bitmap header, I'm padding the rest of the 40 byte bitmap header with 0's., that's the Bitmap header done
$sBmp &= __StringReverseBytes(Hex($iSz)) & "00000000000000000000000000000000"
; Now add the size of the Bitmap data + bitmap header size and combine the icon header together with the bitmap header and color bitmap data
$sIco &= __StringReverseBytes(Hex($iSz + 40)) & __StringReverseBytes(Hex("22")) & $sBmp & $sBD
; create a struct to store the Bitmap dib Bits of the mask bitmap
$tBits = DllStructCreate("byte[" & DllStructGetData($tBI, "SizeImage") & "]")
; Get the mask bitmap dib bits into the $tBits struct.
DllCall('gdi32.dll', 'int', 'GetBitmapBits', 'ptr', $aInfo[4], 'int', DllStructGetData($tBI, "SizeImage"), 'ptr', DllStructGetPtr($tBits))
; Get GetBitmapBits returns Bottom to Top dib, so I turn it to a Top to Bottom dib and append the mask bitmap data to the icon
For $i = DllStructGetData($tBI, "SizeImage") + 1 To 0 Step -(DllStructGetData($tBI, "SizeImage") / DllStructGetData($tBI, "Height"))
$sIco &= StringTrimLeft(BinaryMid(DllStructGetData($tBits, 1), $i, (DllStructGetData($tBI, "SizeImage") / DllStructGetData($tBI, "Height"))), 2)
Next
; Write the icon to a file.
$FO = FileOpen($sOutIcon, 18)
FileWrite($sOutIcon, Binary($sIco))
FileClose($FO)
; Clear the structs
$tBits = 0
$tBI = 0
EndFunc ;==>_CreateIconFileFromHICON
; Reverse Byte String
Func __StringReverseBytes($sByte)
Local $aX = StringRegExp($sByte, "(.{2})", 3), $sX = ''
For $i = UBound($aX) - 1 To 0 Step -1
$sX &= $aX[$i]
Next
Return $sX
EndFunc ;==>__StringReverseBytes
Сама Dll'ка “тяжёлая”, если писать мелкую утилиту, то оно будет лишним.А я бы все равно использовал бы
Значит она установлена как редактор по умолчанию для файлов иконок. Это делает строчка с ShellExecute.сразу же всплывает моя программа ArtIcons Pro с этой же иконкой в ней