HILFE GESUCHT: Bild in Format X in Icon-Datei (*.ico) umwandeln/konvertieren/abspeichern

  • Du musst die Hex() Funktion anpassen, da in den älteren AutoIt Versionen die Hex() Länge Standard 8 ist.

    Beispiel:

    Spoiler anzeigen
    [autoit]


    #include <GDIPlus.au3>
    #include <WinAPI.au3>
    $file = FileOpenDialog("Ein Bild auswählen", "", "Bilder (*.jpg;*.bmp;*.png)")
    If @error Then Exit

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup ()
    $bild = Resize($file)
    $hIcon = _GDIPlus_BitmapCreateHICONFromBitmap($bild)
    _CreateIconFileFromHICON($hIcon, @ScriptDir & "\Test.ico")
    _WinAPI_DestroyIcon($hIcon)
    _GDIPlus_BitmapDispose($bild)
    Exit

    [/autoit] [autoit][/autoit] [autoit]

    Func Resize($sFilename, $width = 64, $height = 64) ; code by UEZ 2011
    Local $hBitmap = _GDIPlus_BitmapCreateFromFile($sFilename)
    Local $iH = _GDIPlus_ImageGetHeight($hBitmap)
    Local $iW = _GDIPlus_ImageGetWidth($hBitmap)
    Local $hImage = _GDIPlus_BitmapCreateFromScan0($width, $height)
    Local $hContext = _GDIPlus_ImageGetGraphicsContext($hImage)
    If $iW < $width And $iH < $height Then
    $w = $width / 2 - $iW / 2
    $h = $height / 2 - $iH / 2
    _GDIPlus_GraphicsDrawImageRect($hContext, $hBitmap, $width / 2 - $iW / 2, $height / 2 - $iH / 2, $iW, $iH)
    Else
    If $iW > $iH Then
    $f = $iW / $width
    Else
    $f = $iH / $height
    EndIf
    $w = $iW / $f
    $h = $iH / $f
    _GDIPlus_GraphicsDrawImageRect($hContext, $hBitmap, $width / 2 - $w / 2, $height / 2 - $h / 2, $w, $h)
    EndIf
    _GDIPlus_GraphicsDispose($hContext)
    _GDIPlus_BitmapDispose($hBitmap)
    Return $hImage
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _CreateIconFileFromHICON($hIcon, $sOutIcon) ;code by smashly
    Local $aInfo, $sIco, $sBmp, $hCDC, $tBI, $tBits, $iSz, $sBD, $FO

    [/autoit] [autoit][/autoit] [autoit]

    ; 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"

    [/autoit] [autoit][/autoit] [autoit]

    ; 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"

    [/autoit] [autoit][/autoit] [autoit]

    ; Get info about the HICON, this is mainly to get the pointers to the Color/Mask bitmaps data
    $aInfo = _WinAPI_GetIconInfo($hIcon)

    [/autoit] [autoit][/autoit] [autoit]

    ; Create a memory Compatable DC
    $hCDC = _WinAPI_CreateCompatibleDC(0)

    [/autoit] [autoit][/autoit] [autoit]

    ; 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))

    [/autoit] [autoit][/autoit] [autoit]

    ; 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)

    [/autoit] [autoit][/autoit] [autoit]

    ; 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" & _RB(Hex(DllStructGetData($tBI, "BitCount"), 4))
    $sBmp &= _RB(Hex(DllStructGetData($tBI, "Width"), 8)) & _RB(Hex(DllStructGetData($tBI, "Height") * 2, 8)) & "0100" & _RB(Hex(DllStructGetData($tBI, "BitCount"), 4)) & "00000000"

    [/autoit] [autoit][/autoit] [autoit]

    ; Get the size of the Bitmap data from the BITMAPINFO Struct, we'll use this in the headers further on.
    $iSz = DllStructGetData($tBI, "SizeImage")

    [/autoit] [autoit][/autoit] [autoit]

    ; Create a struct to store the Bitmap data Bits of the first bitmap, reset the BITMAPINFO struct
    $tBits = DllStructCreate("byte[" & DllStructGetData($tBI, "SizeImage") & "]")

    [/autoit] [autoit][/autoit] [autoit]

    ; Get the color bitmap dib bits into the $tBits struct.
    DllCall('gdi32.dll', 'int', 'GetBitmapBits', 'ptr', $aInfo[5], 'int', $iSz, 'ptr', DllStructGetPtr($tBits))

    [/autoit] [autoit][/autoit] [autoit]

    ; 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

    [/autoit] [autoit][/autoit] [autoit]

    ;Clear the BITMAPINFO & $tBits Struct as we'll use the same variables again for the mask bitmap data
    $tBits = 0
    $tBI = 0

    [/autoit] [autoit][/autoit] [autoit]

    ; 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))

    [/autoit] [autoit][/autoit] [autoit]

    ; 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)

    [/autoit] [autoit][/autoit] [autoit]

    ; We've finished with the Compatable DC, delete it.
    _WinAPI_DeleteDC($hCDC)

    [/autoit] [autoit][/autoit] [autoit]

    ; 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")

    [/autoit] [autoit][/autoit] [autoit]

    ; 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 &= _RB(Hex($iSz, 8)) & "00000000000000000000000000000000"

    [/autoit] [autoit][/autoit] [autoit]

    ; 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 &= _RB(Hex($iSz + 40, 8)) & _RB(Hex("22", 8)) & $sBmp & $sBD

    [/autoit] [autoit][/autoit] [autoit]

    ; Create a struct to store the Bitmap dib Bits of the mask bitmap
    $tBits = DllStructCreate("byte[" & DllStructGetData($tBI, "SizeImage") & "]")

    [/autoit] [autoit][/autoit] [autoit]

    ; 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))

    [/autoit] [autoit][/autoit] [autoit]

    ; 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

    [/autoit] [autoit][/autoit] [autoit]

    ; Write the icon to a file.
    $FO = FileOpen($sOutIcon, 18)
    FileWrite($sOutIcon, Binary($sIco))
    FileClose($FO)

    [/autoit] [autoit][/autoit] [autoit]

    ; Clear the structs
    $tBits = 0
    $tBI = 0
    EndFunc ;==>_CreateIconFileFromHICON

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    ; Reverse Byte String
    Func _RB($sByte)
    Local $aX = StringRegExp($sByte, "(.{2})", 3), $sX = ''
    For $i = UBound($aX) - 1 To 0 Step -1
    $sX &= $aX[$i]
    Next
    Return $sX
    EndFunc ;==>_RB

    [/autoit]

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • @Cyrox auf ner gleichen Bitmap zeichnen und dann erst abspeichern ?
    (Steht auch so im Link, so ähnlich)

    Es gibt sehr viele Leute, die glauben. Aber aus Aberglauben.
    - Blaise Pascal