ResizeIcon() procedure

Share your advanced PureBasic knowledge/code with the community.
Inf0Byt3
PureBasic Fanatic
PureBasic Fanatic
Posts: 2236
Joined: Fri Dec 09, 2005 12:15 pm
Location: Elbonia

ResizeIcon() procedure

Post by Inf0Byt3 »

Been working with some icon code lately and I needed a way to resize icons, so I made this little procedure. It will split the icon in 2 (color and mask), draw the data on PB images via DrawIconEx_() (resize on the fly) then recombine the images back into an icon. The output file can be either 24 or 32 bit (because CreateImage only supports these 2 depths now). It is possible to get lower depths provided that you quantize the color image (Netmaestro had some nice code that created 8-bit images).

The same method (split icon, manipulate color, recombine images) could be used to create greyscale icons for example.

Code: Select all

;//////////////////////////////////////////////////////////////////////////
;//
;// Author: Inf0Byt3
;//
;// Description:
;//  ICO_Resize takes an existing hIcon and returns a new, resized 24 or 32
;//  bit hIcon (Not a PB image object!)
;//
;// Parameters:
;//   hIcon:  Icon handle, returned by ExtractIcon_, LoadIcon_, etc.
;//   Width:  Height = Width and Height of the new icon
;//   Depth:  The depth of the new icon (can be either 24 or 32)
;//
;// OS: Tested on XP, 32 bit
;// Compiler: PureBasic 5.00 +
;// License:  free, unrestricted, no warranty
;// Last update: 18 Jan 2013
;//
;//////////////////////////////////////////////////////////////////////////

Procedure.i ResizeIcon(hIcon.i, Width.l, Height.l, Depth.l=32)
  Protected IInfo.ICONINFO, ColorImg.i, MaskImg.i, DC.i, RethIcon.i, ICONINFO.ICONINFO
  If hIcon <> 0
    ;Get icon data
    If GetIconInfo_(hIcon, @IInfo)
      Select Depth
        Case 24
          ColorImg = CreateImage(#PB_Any, Width, Height, 24)
        Default
          ColorImg = CreateImage(#PB_Any, Width, Height, 32)
      EndSelect
      If IsImage(ColorImg) <> 0
        ;Draw color image
        DC = StartDrawing(ImageOutput(ColorImg))
        If DC <> 0
          DrawIconEx_(DC,0,0,hIcon,Width,Height,0,0,#DI_IMAGE)
          StopDrawing()
        EndIf
      EndIf
      MaskImg = CreateImage(#PB_Any, Width, Height) ;Depth is 24 by default
      If IsImage(MaskImg) <> 0
        ;Draw mask
        DC = StartDrawing(ImageOutput(MaskImg))
        If DC <> 0
          DrawIconEx_(DC,0,0,hIcon,Width,Height,0,0,#DI_MASK)
          StopDrawing()
        EndIf
      EndIf
      ;Create new icon
      ICONINFO\fIcon = 1
      ICONINFO\hbmMask = ImageID(MaskImg)
      ICONINFO\hbmColor = ImageID(ColorImg)
      RethIcon = CreateIconIndirect_(@ICONINFO)
      ;And free the resources
      If IsImage(ColorImg)
        FreeImage(ColorImg)
      EndIf
      If IsImage(MaskImg)
        FreeImage(MaskImg)
      EndIf
      DeleteObject_(IInfo\hbmColor)
      DeleteObject_(IInfo\hbmMask)
    EndIf
  EndIf
  ProcedureReturn RethIcon
EndProcedure

;A quick example:

If OpenWindow(0, 100, 200, 280, 280, "Resize icon", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
 
  Original_hIcon = LoadIcon_(0, #IDI_INFORMATION)
  Resized_hIcon1 = ResizeIcon(Original_hIcon, 64, 64, 32)
  Resized_hIcon2 = ResizeIcon(Original_hIcon, 128, 128, 32)
  
  ImageGadget(0, 30, 30, 32, 32, Original_hIcon)
  ImageGadget(2, 60, 60, 64, 64, Resized_hIcon1)
  ImageGadget(1, 120, 120, 128, 128, Resized_hIcon2)
  
  Repeat
    Event = WaitWindowEvent()
    If Event = #PB_Event_CloseWindow  ; If the user has pressed on the close button
      Quit = 1
    EndIf
  Until Quit = 1
  
  DestroyIcon_(Original_hIcon)
  DestroyIcon_(Resized_hIcon1)
  DestroyIcon_(Resized_hIcon2)
  
EndIf
None are more hopelessly enslaved than those who falsely believe they are free. (Goethe)
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: ResizeIcon() procedure

Post by Dude »

Thanks for this, Inf0Byt3. I needed this tonight. :) Wish PureBasic could do it natively with ResizeImage(), though.
Post Reply