[win] Convert Image to Icon & Change windows icon

Share your advanced PureBasic knowledge/code with the community.
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

[win] Convert Image to Icon & Change windows icon

Post by eddy »

New optimized version for PB 5.30 : http://www.purebasic.fr/english/viewtop ... 73#p451173

Updated for PB5.30 / PB5.20 LTS
- convert PB image to windows icon
- change windows titlebar icon

Code: Select all

ProcedureDLL ConvertToIconImage(image) ; Convert PB Image to PB Icon Image
   ;Check if image source is valid
   If Not IsImage(image) : ProcedureReturn : EndIf
   If ImageWidth(image)<>ImageHeight(image) : ProcedureReturn : EndIf
   Select ImageWidth(image)
      Case 16, 32, 48, 72, 128, 256
      Default : ProcedureReturn
   EndSelect
   
   ;Create 32-bits-color Icon
   CompilerIf #PB_Compiler_Version >= 530
     Protected empty=CreateImage(#PB_Any, ImageWidth(image), ImageWidth(image), 32,#PB_Image_Transparent)
   CompilerElse      
     Protected empty=CreateImage(#PB_Any, ImageWidth(image), ImageWidth(image), 1)
   CompilerEndIf  
   Protected ICONINFO.ICONINFO
   ICONINFO\fIcon=1
   ICONINFO\hbmMask=ImageID(empty)
   ICONINFO\hbmColor=ImageID(image)
   Protected icon=CreateIconIndirect_(@ICONINFO)
   FreeImage(empty)
   ;Update PB Image
   Protected *Bitmap.Long=IsImage(image) : DeleteObject_(*Bitmap\l)
   *Bitmap\l=icon
   
   
   
   
   ProcedureReturn image
EndProcedure
ProcedureDLL SetImageMaskColor(color) ; Set color to use as maskcolor
   Global ImageMaskColorForCreateAlphaImage
   ImageMaskColorForCreateAlphaImage=color
EndProcedure
ProcedureDLL CreateAlphaImage(image, alphachannel=0) ; Create alpha image or masked image (32 bits)
   ;Create 32-bits-color image
   Protected w=ImageWidth(image)
   Protected h=ImageHeight(image)
   Protected paint=CreateImage(#PB_Any, w, h, 32)
   StartDrawing(ImageOutput(paint))
      DrawImage(ImageID(image), 0, 0)
   StopDrawing()
   
   ;Extract 32-bits-color bitmap
   Protected i, j
   Protected *rgba.RGBQUAD
   Protected bmp.BITMAP
   GetObject_(ImageID(paint), SizeOf(BITMAP), bmp)
   
   ;Apply Mask or Alpha layer
   If Not IsImage(alphachannel)
      Global ImageMaskColorForCreateAlphaImage
      Protected maskR.b=Red(ImageMaskColorForCreateAlphaImage)
      Protected maskG.b=Green(ImageMaskColorForCreateAlphaImage)
      Protected maskB.b=Blue(ImageMaskColorForCreateAlphaImage)
      
      For i=0 To bmp\bmHeight-1
         For j=0 To bmp\bmWidthBytes-1 Step 4
            *rgba=bmp\bmBits+bmp\bmWidthBytes*i+j
            *rgba\rgbReserved=$FF
            CompilerIf #PB_Compiler_Version >= 530
              *rgba\rgbReserved*Bool(#True XOr (*rgba\rgbBlue=maskB And *rgba\rgbGreen=maskG And *rgba\rgbRed=maskR))
            CompilerElse              
              *rgba\rgbReserved*(#True XOr (*rgba\rgbBlue=maskB And *rgba\rgbGreen=maskG And *rgba\rgbRed=maskR))
            CompilerEndIf            
         Next
      Next
   Else
      StartDrawing(ImageOutput(alphachannel))
         For i=0 To bmp\bmHeight-1
            For j=0 To bmp\bmWidthBytes-1 Step 4
               *rgba=bmp\bmBits+bmp\bmWidthBytes*i+j
               *rgba\rgbReserved=Point(j/4, i) & $FF
            Next
         Next
      StopDrawing()
   EndIf
   
   ;Redraw image
   CompilerIf 1
      FreeImage(image)
      CopyImage(paint, image)
   CompilerElse
      CreateImage(image, w, h, 32)
      StartDrawing(ImageOutput(image))
         DrawAlphaImage(ImageID(paint), 0, 0)
      StopDrawing()
   CompilerEndIf
   FreeImage(paint)
   
   ProcedureReturn image
EndProcedure

;********************
;EXAMPLE
;********************
For ico=1 To 32
   ;COLORS ( + MASKED COLOR )
   CreateImage(ico, 32, 32, 24)
   StartDrawing(ImageOutput(ico))
      FrontColor(#Black)
      Box(0, 0, 32, 32)
      
      FrontColor(#Red)
      For a=0 To 360 Step 20
         r=Random(14) : Box(16+r*Cos(a), 16+r*Sin(a), 3, 3)
      Next
   StopDrawing()
   ;//// CREATE MASKED ICON
   SetImageMaskColor(#Black)
   CreateAlphaImage(ico)
   ConvertToIconImage(ico)
   
   ;COLORS
   icoAlpha=ico+32
   CreateImage(icoAlpha, 32, 32, 24)
   StartDrawing(ImageOutput(icoAlpha))
      FrontColor(#Blue)
      Box(0, 0, 32, 32)
   StopDrawing()
   ;ALPHACHANNEL
   CompilerIf #PB_Compiler_Version >= 530
     alphachannel=CreateImage(#PB_Any, 32, 32, 24)
   CompilerElse     
     alphachannel=CreateImage(#PB_Any, 32, 32, 8)
   CompilerEndIf   
   StartDrawing(ImageOutput(alphachannel))
      FrontColor(#Black)
      Box(0, 0, 32, 32)
      
      For a=0 To 360 Step 20
         r=Random(14)
         If r>5
            FrontColor(256-256*r/16)
         Else
            FrontColor(255)
         EndIf
         Box(16.0+r*Cos(a), 16.0+r*Sin(a), 5, 5)
      Next
   StopDrawing()
   ;//// CREATE ALPHACHANNEL ICON
   CreateAlphaImage(icoAlpha, alphachannel)
   ConvertToIconImage(icoAlpha)
   FreeImage(alphachannel)
Next

win=OpenWindow(1, 0, 0, 300, 300, "Animated Transparent Icon by eddy")
CompilerIf #PB_Compiler_Version < 530
  CreateGadgetList(win)
CompilerEndIf
ButtonImageGadget(11, 5, 5, 100, 100, ImageID(1))
ButtonImageGadget(12, 110, 5, 100, 100, ImageID(1))
AddSysTrayIcon(111, win, ImageID(1))

Repeat
   event=WaitWindowEvent(200)
   
   If EventGadget()=11
      ShowIconMode=0
   ElseIf EventGadget()=12
      ShowIconMode=1
   EndIf
   
   If Not event
      anim=(anim+1)%32
      
      iconMasked=ImageID(anim+1)
      SetGadgetAttribute(11, #PB_Button_Image, iconMasked)
      
      iconAlpha=ImageID(anim+33)
      SetGadgetAttribute(12, #PB_Button_Image, iconAlpha)
      
      If ShowIconMode
         SendMessage_(win, #WM_SETICON, 0, iconAlpha)
         ChangeSysTrayIcon(111, iconAlpha)
      Else
         SendMessage_(win, #WM_SETICON, 0, iconMasked)
         ChangeSysTrayIcon(111, iconMasked)
      EndIf
   EndIf 
Until event=#PB_Event_CloseWindow
Last edited by eddy on Sat Aug 16, 2014 1:43 pm, edited 4 times in total.
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Re: [win] Convert Image to Icon & Change windows icon

Post by eddy »

updated
PB 5.30 supported: ConvertToIconImage(image)
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
AAT
Enthusiast
Enthusiast
Posts: 259
Joined: Sun Jun 15, 2008 3:13 am
Location: Russia

Re: [win] Convert Image to Icon & Change windows icon

Post by AAT »

Hi, eddy!

Excellent work! Thanks for sharing.

Good luck!
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Re: [win] Convert Image to Icon & Change windows icon

Post by eddy »

Here is a optimized version for PB5.30.
I removed some obsolete codes.

Code: Select all

Procedure.i ConvertToIconImage(Image, maskColor=0)   
  If Not (IsImage(Image) And ImageWidth(Image)=ImageHeight(Image)) : ProcedureReturn : EndIf
  Select ImageWidth(Image)
    Case 16, 32, 48, 72, 128, 256
    Default : ProcedureReturn
  EndSelect
  
  If ImageDepth(Image)<32
    ;Extract 32-bits-color bitmap
    Protected paint=CreateImage(#PB_Any, ImageWidth(Image), ImageHeight(Image), 32)
    StartDrawing(ImageOutput(paint))
    DrawImage(ImageID(Image), 0, 0)
    StopDrawing()
    Protected i, j
    Protected *rgba.RGBQUAD
    Protected bmp.BITMAP
    GetObject_(ImageID(paint), SizeOf(BITMAP), bmp)   
    ;Apply Mask layer
    Protected maskR.b=Red(maskColor)
    Protected maskG.b=Green(maskColor)
    Protected maskB.b=Blue(maskColor)      
    For i=0 To bmp\bmHeight-1
      For j=0 To bmp\bmWidthBytes-1 Step 4
        *rgba=bmp\bmBits+bmp\bmWidthBytes*i+j
        *rgba\rgbReserved=$FF*Bool(#True XOr (*rgba\rgbBlue=maskB And *rgba\rgbGreen=maskG And *rgba\rgbRed=maskR))
      Next
    Next
    ;Redraw Image
    FreeImage(Image)
    CopyImage(paint, Image)
    FreeImage(paint)
  EndIf 
  
  ;Create 32-bits-color Icon
  Protected empty=CreateImage(#PB_Any, ImageWidth(Image), ImageWidth(Image), 32, #PB_Image_Transparent)
  Protected ICONINFO.ICONINFO
  ICONINFO\fIcon=1
  ICONINFO\hbmMask=ImageID(empty)
  ICONINFO\hbmColor=ImageID(Image)
  Protected icon=CreateIconIndirect_(@ICONINFO)
  FreeImage(empty)
  ;Update PB Image
  Protected *Bitmap.Long=IsImage(Image) : DeleteObject_(*Bitmap\l)
  *Bitmap\l=icon
  ProcedureReturn Image
EndProcedure

CompilerIf #PB_Compiler_IsMainFile  
  ;********************
  ;EXAMPLE
  ;********************
  
  For animationFrame=0 To 31
    ;ALPHACHANNEL IMAGE (32 bits)
    imageAlpha=animationFrame
    CreateImage(imageAlpha, 32, 32, 32,#PB_Image_Transparent)
    StartDrawing(ImageOutput(imageAlpha))  
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    For a=0 To 10
      transparentColor=RGBA(255,0,0,a*10)
      r=Random(14) : Circle(16+r*Cos(a), 16+r*Sin(a), 2, transparentColor)
    Next
    StopDrawing()
    ConvertToIconImage(imageAlpha)
    
    ;COLOR MASKED IMAGE (24 bits)
    imageMasked=animationFrame+32
    maskColor=RGB(255, 0, 255); custom mask color 
    CreateImage(imageMasked, 32, 32, 24, maskColor)
    StartDrawing(ImageOutput(imageMasked))  
    For a=0 To 10
      solidColor=RGB(0,0,255)    
      r=Random(14) : Circle(16+r*Cos(a), 16+r*Sin(a), 2, solidColor)
    Next
    StopDrawing()
    ConvertToIconImage(imageMasked, maskColor)
  Next
  
  Enumeration 
    #Win
    #SystrayIcon1
    #SystrayIcon2
    #ButtonIcon1
    #ButtonIcon2
    #IconAnimationTimer
  EndEnumeration
  OpenWindow(#Win, 0, 0, 300, 300, "Animated Transparent Icon by eddy")
  ButtonImageGadget(#ButtonIcon1, 5, 5, 100, 100, ImageID(0))
  ButtonImageGadget(#ButtonIcon2, 110, 5, 100, 100, ImageID(0))
  AddSysTrayIcon(#SystrayIcon1, WindowID(#Win), ImageID(0))
  AddSysTrayIcon(#SystrayIcon2, WindowID(#Win), ImageID(0))
  AddWindowTimer(#Win,#IconAnimationTimer,100)
  
  Repeat
    event=WaitWindowEvent()
    
    ;select titlebar icon to display
    If EventGadget()=#ButtonIcon1
      SelectedTitleBarIcon=0
    ElseIf EventGadget()=#ButtonIcon2
      SelectedTitleBarIcon=1
    EndIf
    
    If event=#PB_Event_Timer
      ;update animation frame (0 -> 31)
      animationFrame=(animationFrame+1)%32
      iconAlpha=ImageID(animationFrame)
      iconMasked=ImageID(animationFrame+32)
      ;button animations
      SetGadgetAttribute(#ButtonIcon1, #PB_Button_Image, iconAlpha)
      SetGadgetAttribute(#ButtonIcon2, #PB_Button_Image, iconMasked)    
      ;systray animations
      ChangeSysTrayIcon(#SystrayIcon1, iconAlpha)
      ChangeSysTrayIcon(#SystrayIcon2, iconMasked)   
      ;titlebar animation
      Select SelectedTitleBarIcon
        Case 0 : SendMessage_(WindowID(#Win), #WM_SETICON, 0, iconAlpha)
        Case 1 : SendMessage_(WindowID(#Win), #WM_SETICON, 0, iconMasked)
      EndSelect
    EndIf 
  Until event=#PB_Event_CloseWindow
CompilerEndIf 
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
Post Reply