Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   AutoIt (http://forum.oszone.net/forumdisplay.php?f=103)
-   -   [решено] Как из формата PNG сделать формат ICO (http://forum.oszone.net/showthread.php?t=181380)

assch 24-07-2010 23:35 1460112

Как из формата PNG сделать формат ICO
 
Можно ли средствами Autoit из формата - PNG - сделать формат - ICO

Creat0R 25-07-2010 00:14 1460122

Можно.

Заголовок темы сперва нужно указать более расширено, чтобы отражал суть темы.

assch 25-07-2010 00:35 1460127

Это набор функций или есть специальная функция для конвертации подобного рода.
На сайте Русское сообщество в одной из тем вроде нашёл какую то зацепку (хотя могу и ошибатся).

$hIcon = DllCall($ghGDIPDll, 'int', 'GdipCreateHICONFromBitmap', 'ptr', $hImage, 'int*', 0)

Пытаюсь обыграть её, но увы пока не получается. Хотя как я уже говорил это может быть тупиковый вариант.
Конечно найти самому это не сравнимо интересней. Но время, время. Вот воистину не восполнимый ресурс.
Если можно пример как это делается.

Creat0R 26-07-2010 02:10 1460564

Продублирую на всякий случай решение и тут:

Код:

#include <GDIPlus.au3>

$sImageFile = FileOpenDialog('Select PNG File', '', 'Images (*.png;*.bmp;*.jpg;*.jepg;*.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


FlatX007 26-07-2010 08:34 1460613

Иконки получаются не многостраничные! я знаю что это уже наглость но всё же :)

assch 26-07-2010 13:46 1460815

Creat0R Большое спасибо за код.
Жалко что иконки получаются не полноценными . (Я имею ввиду формат PNG прозрачные пиксили сделать не удалось)
А может быть всё таки можно раскатать эту тему? Как вы думаете.
Присоединяюсь к FlatX007 это уже наглость, но всё же вопрос к знатокам.

Как говорили древнии "Хочешь быть ещё богаче - Поделись."

assch 26-07-2010 16:38 1460942

Иконки не прозрачные были от того наверное, что перед конвертацией стояла функция которая обрезала файл под классические размеры иконки,
в данном случае 32 на 32.Она и гасила прозрачные пиксилы. Я попробЫвал убрать этот участок кода подставив файл PNG уже обрезанный правда под размер 48 на 48
Эта иконка просто так лучше смотрится и вроде получилось. Можно файл и не обрезать оставить его как есть например 256 на 256
(У меня был именно такой размер файла PNG ) Система его всё равно сделает стандартно маленьким(Правда есть одно но если эту иконку стандартно поставить
например в кнопку она будет отображаться на все свои размеры )Короче я отвлёкся.
Нужен другой код в начале этой основной функции (Большое спасибо за неё Креатору ) Чтобы он обрезал под предложенные размеры и чтобы он не гасил прозрачные пиксилы.
Попробую покапать дальше но, и не откажусь от советов.


Код:

#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


assch 26-07-2010 19:44 1461031

Вот код который выставил на другом сайте Creat0R за что ему большое спасибо.
Файл 48.png можно взять чуть по выше.





Код:

#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, 48, 48)
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


FlatX007 26-07-2010 23:51 1461143

Вложений: 1
Всё же непонятно зачем нужна иконка с "одной страницей" :dont-know

Иконки делаются так :

assch 28-07-2010 18:10 1462357

FlatX007, Что за программа?

FlatX007 28-07-2010 19:20 1462412

Axialis IconWorkshop


Время: 16:55.

Время: 16:55.
© OSzone.net 2001-