creating_20a_20png_20file_20from_20a_20windows_20icon

This is an old revision of the document!


Creating a PNG file from a Windows icon

by Richard Russell, February 2018

Both Windows icons and PNG (Portable Network Graphics) files support transparency - an alpha channel if you prefer - so it may be useful to convert the former to the latter. For example Android and Mac OS icons use PNG format, so if you want to convert a Windows icon to be suitable for those operating systems this is what you need. The PROCpngfromhicon() procedure listed below performs the required conversion; its parameters are the path and filename of the PNG file to be created, a handle to the icon and the width and height of the icon (the routine could have discovered the dimensions itself, but in the program for which it was written they were already known). If you need to resize the icon the CopyImage API will do that.

The procedure has a dependency on GDIPlus so you will need to include this code in the initialisation section of your program:

      INSTALL @lib$ + "GDIPLIB"
      PROC_gdipinit
      SYS "GetModuleHandle", "GDIPLUS.DLL" TO gdip%
      SYS "GetProcAddress", gdip%, "GdipCreateBitmapFromScan0" TO `GdipCreateBitmapFromScan0`
      SYS "GetProcAddress", gdip%, "GdipSaveImageToFile"       TO `GdipSaveImageToFile`


and this code should be executed on exit:

      PROC_gdipexit


Here is the procedure itself:

      DEF PROCpngfromhicon(png$, hicon%, w%, h%)
      LOCAL I%, bitmap%, wide%, ole32%, cfs%
      LOCAL pixel%(), alpha%(), bmi{}, ii{}, clsid{}
      DIM wide% LOCAL MAX_PATH * 2
      DIM bmi{Size%, Width%, Height%, Planes{l&,h&}, BitCount{l&,h&}, \
      \       Compression%, SizeImage%, XPelsPerMeter%, YPelsPerMeter%, \
      \       ClrUsed%, ClrImportant%}
      DIM ii{fIcon%, xHotspot%, yHotspot%, hbmMask%, hbmColor%}
      DIM clsid{a%, b%, c%, d%, e%, f%, g%, h%}
      SYS "LoadLibrary", "OLE32" TO ole32%
      SYS "GetProcAddress", ole32%, "CLSIDFromString" TO cfs%
      SYS "MultiByteToWideChar", 0, 0, "{557CF406-1A04-11D3-9A73-0000F81EF32E}", -1, wide%, MAX_PATH
      SYS cfs%, wide%, clsid{}
      SYS "GetIconInfo", hicon%, ii{}
      bmi.Size% = DIM(bmi{})
      bmi.Width% = w%
      bmi.Height% = -h%
      bmi.Planes.l& = 1
      bmi.BitCount.l& = 32
      bmi.Compression% = BI_RGB
      DIM pixel%(w% * h% - 1)
      SYS "GetDIBits", @memhdc%, ii.hbmColor%, 0, h%, ^pixel%(0), bmi{}, DIB_RGB_COLORS
      FOR I% = 0 TO h%*w% - 1
        IF pixel%(I%) AND &FF000000 EXIT FOR
      NEXT
      IF I% >= h%*w% THEN
        DIM alpha%(w% * h% - 1)
        SYS "GetDIBits", @memhdc%, ii.hbmMask%, 0, h%, ^alpha%(0), bmi{}, DIB_RGB_COLORS
        FOR I% = 0 TO h%*w% - 1
          IF alpha%(I%)=FALSE pixel%(I%) OR= &FF000000
        NEXT
      ENDIF
      SYS `GdipCreateBitmapFromScan0`, w%, h%, 4*w%, &26200A, ^pixel%(0), ^bitmap%
      SYS "MultiByteToWideChar", CP_ACP, 0, png$, -1, wide%, MAX_PATH
      SYS `GdipSaveImageToFile`, bitmap%, wide%, clsid{}, 0
      SYS !(!bitmap%+8), bitmap% : REM Bitmap::Release
      SYS "FreeLibrary", ole32%
      ENDPROC
This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
creating_20a_20png_20file_20from_20a_20windows_20icon.1522502352.txt.gz · Last modified: 2024/01/05 00:18 (external edit)