Rotate Images free -Module -All OS

Share your advanced PureBasic knowledge/code with the community.
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Rotate Images free -Module -All OS

Post by Saki »

Rotate Images free -Module -All OS- Module -All OS

This is a module to create free rotated images.
Any image with or without alpha channel can be used as a template.
The alpha blending can be adjusted freely.
There are no stairs in the rotated images, the edges are smoothed.

The module can be integrated into your own software to create such images on the fly.

You simply pass any image to this function and get it rotated back.
You can save these images and insert them as you like into any design or on any background, like sprites, but just as well for canvas, images, or again on PB sprites.
There are now images with invisible mask.

This is something many have been looking for.

Have fun with it

A other rotate & mirror tool look here :
viewtopic.php?f=12&t=77009

The GFX_Wizzard_BF you found here, with other modules and several hundred other graphic functions :
viewtopic.php?f=12&t=66927

There is no easier way to rotate images :wink:
Image

Image

Code: Select all

DeclareModule RotateAlphaImageCreator
  EnableExplicit
  ; This is a part of GFX_Wizzard_BF - By Saki
  ; RotateAlphaImageCreator - Free rotatable images - Free adjustable alpha channel
  ; This tool can create also rectangular images that can be easily rotated like this
  ; The image frame is interpolated with the used background color
  Declare RotateAlphaImageCreator_BF(degree, image_ID, alpha=255, background_color=0, create_square_image=0)
  
EndDeclareModule

Module RotateAlphaImageCreator
  ; --- Calculate size rotated image and create a empty resized image ---
  Global resulted_rotated_width, resulted_rotated_height, alpha_sprite
  Procedure.f Max(f_first.f, f_second.f)
    If f_first>f_second
      ProcedureReturn f_first
    Else
      ProcedureReturn f_second
    EndIf
  EndProcedure
  
  Procedure.f Min(f_first.f, f_second.f)
    If f_first>f_second
      ProcedureReturn f_second
    Else
      ProcedureReturn f_first
    EndIf
  EndProcedure
  
  Macro calculate_rotated_rectangle
    Protected radians.f=(2*#PI*degree)/360
    Protected cos.f=Cos(radians)
    Protected sin.f=Sin(radians)
    
    Protected point_1_x.f=-height*sin
    Protected point_1_y.f=height*cos
    Protected point_2_x.f=width*cos-height*sin
    Protected point_2_y.f=height*cos+width*sin
    Protected point_3_x.f=width*cos
    Protected point_3_y.f=width*sin
    
    Protected min_x.f=min(0, min(point_1_x, min(point_2_x, point_3_x)))
    Protected min_y.f=min(0, min(point_1_y, min(point_2_y, point_3_y)))
    Protected max_x.f=max(0, max(point_1_x, max(point_2_x, point_3_x)))
    Protected max_y.f=max(0, max(point_1_y, max(point_2_y, point_3_y)))
    
    Protected resulted_width.f=Abs(max_x)-min_x
    Protected resulted_height.f=Abs(max_y)-min_y
  EndMacro
  
  Procedure Create_empty_rotated_image_BF(width, height, degree, color=0, alpha_image=0)
    calculate_rotated_rectangle
    resulted_rotated_width=resulted_width
    resulted_rotated_height=resulted_height
    If alpha_image
      Protected resulted_ID=CreateImage(#PB_Any, resulted_width, resulted_height, 32, #PB_Image_Transparent)
      StartDrawing(ImageOutput(resulted_ID)) ; Low priority, no furter check
      Box(0, 0, resulted_width, resulted_height, color)
      StopDrawing()
    Else
      resulted_ID=CreateImage(#PB_Any, resulted_width, resulted_height, 24, color)
    EndIf
    ProcedureReturn resulted_ID
  EndProcedure
  
  Procedure Calculate_empty_rotated_rectangle_BF(width, height, degree)
    calculate_rotated_rectangle
    resulted_rotated_width=resulted_width
    resulted_rotated_height=resulted_height
    ProcedureReturn 1
  EndProcedure
  
  Procedure Get_resulted_rotated_width()
    ProcedureReturn resulted_rotated_width
  EndProcedure
  
  Procedure Get_resulted_rotated_height()
    ProcedureReturn resulted_rotated_height
  EndProcedure
  
  Procedure RotateAlphaImageCreator_BF(degree, image_ID, alpha=255, background_color=0, create_square_image=0)
    
    If Not IsImage(image_ID) : ProcedureReturn -6 : EndIf
    
    If alpha>255 Or alpha<0 : alpha=255 : EndIf
    
    If Abs(degree)>360 : degree=0 : EndIf
    
    Protected image_width=ImageWidth(image_ID), image_height=ImageHeight(image_ID)
    
    Protected alpha_image=1 ; Activate alpha channel enhancement
    If image_width>image_height
      Protected new_image_ID=Create_empty_rotated_image_BF(image_width+6, image_width+8, degree, background_color, alpha_image)
      Protected temp_image_ID=Create_empty_rotated_image_BF(image_width+6, image_width+8, degree, background_color, alpha_image)
    Else
      new_image_ID=Create_empty_rotated_image_BF(image_height+6, image_height+6, degree, background_color, alpha_image)
      temp_image_ID=Create_empty_rotated_image_BF(image_height+6, image_height+6, degree, background_color, alpha_image)
    EndIf
    
    If Not new_image_ID : ProcedureReturn -6 : EndIf
    If Not temp_image_ID : FreeImage(temp_image_ID) : ProcedureReturn -6 : EndIf
    
    If Not StartDrawing(ImageOutput(new_image_ID))
      FreeImage(new_image_ID) : FreeImage(temp_image_ID)
      ProcedureReturn -4
    EndIf
    
    If alpha_image
      DrawingMode(#PB_2DDrawing_AllChannels)
      DrawAlphaImage(ImageID(image_ID),
                     ImageWidth(new_image_ID)/2-image_width/2,
                     ImageWidth(new_image_ID)/2-image_height/2, alpha)
    Else
      DrawImage(ImageID(image_ID),
                ImageWidth(new_image_ID)/2-image_width/2,
                ImageWidth(new_image_ID)/2-image_height/2)
    EndIf
    StopDrawing()
    
    If Not StartVectorDrawing(ImageVectorOutput(temp_image_ID))
      FreeImage(new_image_ID) : FreeImage(temp_image_ID)
      ProcedureReturn -4
    EndIf
    
    RotateCoordinates(VectorOutputWidth()/2, VectorOutputHeight()/2, degree)
    MovePathCursor(0, 0) 
    
    DrawVectorImage(ImageID(new_image_ID), alpha) 
    StopVectorDrawing()
    FreeImage(new_image_ID)
    
    Calculate_empty_rotated_rectangle_BF(image_width, image_height, degree)
    Get_resulted_rotated_width()      
    Protected rectangle_width=Get_resulted_rotated_width()
    Protected rectangle_height=Get_resulted_rotated_height()  
    
    If create_square_image : Protected offset=2 : Else : offset=3 : EndIf
    
    If create_square_image
      If rectangle_width>rectangle_height
        Protected  rectangle_width_1=ImageWidth(temp_image_ID)/2-rectangle_width/2-offset
        Protected rectangle_height_1=ImageHeight(temp_image_ID)/2-rectangle_width/2-offset
        If rectangle_width_1<1 : rectangle_width_1=1 : EndIf
        If rectangle_height_1<1 : rectangle_height_1=1 : EndIf
        new_image_ID=GrabImage(temp_image_ID, #PB_Any,
                               rectangle_width_1,
                               rectangle_height_1,
                               rectangle_width+offset*2,
                               rectangle_width+offset*2)
      Else
        rectangle_width_1=ImageWidth(temp_image_ID)/2-rectangle_height/2-offset
        rectangle_height_1=ImageHeight(temp_image_ID)/2-rectangle_height/2-offset
        If rectangle_width_1<1 : rectangle_width_1=1 : EndIf
        If rectangle_height_1<1 : rectangle_height_1=1 : EndIf
        new_image_ID=GrabImage(temp_image_ID, #PB_Any,
                               rectangle_width_1,
                               rectangle_height_1,
                               rectangle_height+offset*2,
                               rectangle_height+offset*2)  
      EndIf
    Else
      new_image_ID=GrabImage(temp_image_ID,
                             #PB_Any,
                             ImageWidth(temp_image_ID)/2-rectangle_width/2-offset,
                             ImageHeight(temp_image_ID)/2-rectangle_height/2-offset,
                             rectangle_width+offset*2,
                             rectangle_height+offset*2)
    EndIf
    
    FreeImage(temp_image_ID)
    
    If Not (new_image_ID) : ProcedureReturn -6 : EndIf
    
    ProcedureReturn new_image_ID
  EndProcedure
EndModule
UseModule RotateAlphaImageCreator

CompilerIf #PB_Compiler_IsMainFile
  
  ; ###### Get the result ######
  EnableExplicit
  
  UsePNGImageDecoder() : UseJPEGImageDecoder() : UseTIFFImageDecoder() : UseGIFImageDecoder() : UsePNGImageEncoder()
  
  Define window_ID=OpenWindow(#PB_Any, 0, 0, 1200, 800, "RotateAlphaImageCreator - This is a Part from GFX_Wizzard_BF - By Saki",
                              #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_MaximizeGadget)
  SetWindowColor(window_ID, #Green)
  Define canvas_ID=CanvasGadget(#PB_Any, 10, 50, WindowWidth(window_ID)-20, WindowHeight(window_ID)-60)
  SetGadgetColor(canvas_ID, #PB_Gadget_BackColor, $909090)
  Define box_width=260
  Define box_height=320
  Define image_ID=CreateImage(#PB_Any, box_width, box_height, 24, #White)
  StartDrawing(ImageOutput(image_ID))
  DrawingMode(#PB_2DDrawing_Outlined)
  BackColor(#White)
  DrawText(20, 20, " Top left ", #Black)
  Box(0, 0, box_width, box_height, #Red)
  StopDrawing()
  
  StringGadget(1, 10, 10, 60, 25, "0", #PB_String_Numeric)
  StringGadget(2, 150, 10, 60, 25, "255", #PB_String_Numeric)
  TextGadget(3, 80, 15, 60, 25, "Degree")
  SetGadgetColor(3, #PB_Gadget_BackColor, #Green)
  TextGadget(4, 220, 15, 60, 25, "Alpha")
  SetGadgetColor(4, #PB_Gadget_BackColor, #Green)
  ButtonGadget(5,300,10,170,25,"Create fitted image")
  ButtonGadget(6,480,10,170,25,"Create squared image")
  ButtonGadget(7,660,10,120,25, "Load image")
  ButtonGadget(8,790,10,130,25, "Save image")
  ButtonGadget(9,930,10,150,25, "Background color")
  ButtonGadget(10,1090,10,100,25, "Tool color")
  
  Macro Macro_draw_image
    ResizeGadget(canvas_ID, #PB_Ignore, #PB_Ignore, WindowWidth(window_ID)-20,  WindowHeight(window_ID)-60)
    If StartDrawing(CanvasOutput(canvas_ID))
      If IsImage(image_1_ID)
        Box(0, 0, WindowWidth(window_ID), WindowHeight(window_ID), tool_color)
        DrawAlphaImage(ImageID(image_1_ID),
                       GadgetWidth(canvas_ID)/2-ImageWidth(image_1_ID)/2,
                       GadgetHeight(canvas_ID)/2-ImageHeight(image_1_ID)/2)
        BackColor(#White)
        If create_square_image
          DrawText(10, 10, " Squared image ", #Black)
        Else
          DrawText(10, 10, " Fitted image ", #Black)
        EndIf
      EndIf
      
      DrawText(10, 35, " "+Str(ImageWidth(image_1_ID))+" x "+Str(ImageHeight(image_1_ID))+" ", #Black)
      Box(10, 60, 30, 30, #Black)
      Box(12, 62, 26, 26, #White)
      Box(14, 64, 22, 22, background_color)
      StopDrawing()
    EndIf
  EndMacro
  
  Define create_square_image=0
  
  Define degree, alpha=255, background_color, tool_color=$909090
  SetGadgetColor(canvas_ID, #PB_Gadget_BackColor, tool_color)
  Define image_1_ID=RotateAlphaImageCreator_BF(0, image_ID, 255, background_color, create_square_image)
  Macro_draw_image
  
  Repeat
    Define win_event=WaitWindowEvent()
    
    If win_event=#PB_Event_SizeWindow
      Macro_draw_image
    EndIf
    
    Select win_event 
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 5
            create_square_image=0
            Define degree=Val(GetGadgetText(1))
            Define alpha=Val(GetGadgetText(2))
            image_1_ID=RotateAlphaImageCreator_BF(degree, image_ID, alpha, background_color, create_square_image)
            Macro_draw_image
          Case 6
            create_square_image=1
            Define degree=Val(GetGadgetText(1))
            Define alpha=Val(GetGadgetText(2))
            image_1_ID=RotateAlphaImageCreator_BF(degree, image_ID, alpha, background_color, create_square_image)
            Macro_draw_image
          Case 7
            Define path$=OpenFileRequester("Load a Image", "", "", 0)
            If FileSize(path$)>0
              FreeImage(image_ID)
              FreeImage(image_1_ID)
              image_ID=LoadImage(#PB_Any, path$)
              Define degree=Val(GetGadgetText(1))
              Define alpha=Val(GetGadgetText(2))
              Define image_1_ID=RotateAlphaImageCreator_BF(degree, image_ID, alpha, background_color, create_square_image)
              Macro_draw_image
              StopDrawing()
            EndIf
          Case 8
            Define path$=SaveFileRequester("Save the Image", "", "", 0)
            If path$<>""
              SaveImage(image_1_ID, path$+".png", #PB_ImagePlugin_PNG)
            EndIf
          Case 9
            background_color=ColorRequester(background_color)
            image_1_ID=RotateAlphaImageCreator_BF(degree, image_ID, alpha, background_color, create_square_image)
            Macro_draw_image
          Case 10
            tool_color=ColorRequester(tool_color)
            image_1_ID=RotateAlphaImageCreator_BF(degree, image_ID, alpha, background_color, create_square_image)
            Macro_draw_image 
        EndSelect
        
    EndSelect
  Until win_event=#PB_Event_CloseWindow
  
CompilerEndIf
Last edited by Saki on Mon Apr 05, 2021 4:34 pm, edited 10 times in total.
地球上の平和