Image Rotate And Crop Using Grabimage

Share your advanced PureBasic knowledge/code with the community.
collectordave
Addict
Addict
Posts: 1310
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

Image Rotate And Crop Using Grabimage

Post by collectordave »

Been looking to do this for a while and thought I would post.

The programme loads a .jpg image and allows the user to rotate the image either clockwise or anti clockwise and to crop the image at anytime, taking the whole image including background or just a portion of the image.

The user can also save the image to disk as a .jpg file.

It uses the DCTool toolbar from elsewhere on the forum and some images I have used, so to run the code you will need DCTool.pbi and the images. Anyone needing these I can zip them up and put on dropbox.

If anyone can improve the code in anyway I would be gratefull. As a start I think I may have missed some Freeimage bits so may have a memory leak etc.

here is the code

Code: Select all

UseJPEGImageDecoder()
UseJPEGImageEncoder()
UsePNGImageDecoder()



  
 IncludeFile "DCTool.pbi" 

Global dlgCropImage

Global cnvEditImage, tnSelectImage, btnRotateLeft, btnRotateRight, btnCrop, btnDone.i,btnSave.i,btnCancel.i,imgDone

Global ImgSelect,ImgCrop, ImgAntiClock, ImgClock, ImgSave, ImgOk,ImgCancel,ImgUndo,ImgHelp 

Global Drawing.i,GrabImage.i,EditTool.i

Global CanvasImage.i,ImgToEdit.i,ImgEdited.i,Top.i,Left.i,Angle.i

Procedure LoadSampleImage()
  
  Define imgFile.s,loadimg.i,ImgWidth.i,ImgHeight.i,imgAspect.d
  Define Ratio1.d,Ratio2.d,Aspect.d,x.i,y.i,adjustedheight.i,adjustedwidth.i
  
  Define TempImage.i
  
  Pattern.s = "JPG (*.jpg)|*.jpg;PNG (*.png)|*.png;"
 
  imgFile = OpenFileRequester("Please choose file to load", GetCurrentDirectory(), Pattern, 0)
  
  If imgFile

    ImgToEdit = LoadImage(#PB_Any,imgFile)
    ImgEdited = ImgToEdit
    
    ImgWidth =  ImageWidth(ImgToEdit)
    Left = (430 - ImgWidth)/2
    ImgHeight =  ImageHeight(ImgToEdit)
    Top = (430 - ImgHeight)/2 
    
    ;Get aspect ratio
    imgAspect = ImgWidth/ImgHeight

    ; Maintain aspect ratio     
    Ratio1 = 300/ImgWidth
    Ratio2 = 300/ImgHeight
 
    If Ratio1 < Ratio2
      Aspect = Ratio1
    Else
      Aspect = Ratio2
    EndIf     
      
    adjustedwidth = ImgWidth * Aspect
    adjustedheight = ImgHeight * Aspect 
    
    ResizeImage(ImgToEdit,adjustedwidth,adjustedheight)

    Left = (430 - adjustedwidth)/2

    Top = (430 - adjustedheight)/2 

    StartVectorDrawing(CanvasVectorOutput(cnvEditImage,#PB_Unit_Pixel ))

    MovePathCursor(Left, Top)
    DrawVectorImage(ImageID(ImgToEdit))
    StopVectorDrawing()
    
    TempImage = GetGadgetAttribute(cnvEditImage, #PB_Canvas_Image)

    CanvasImage =  CreateImage(#PB_Any, 430, 430)
    StartDrawing(ImageOutput(CanvasImage))
    DrawImage(TempImage,0,0)
    StopDrawing()

    DisableIconBarGadgetItem(EditTool, 2, #False) 
    DisableIconBarGadgetItem(EditTool, 3, #False)
    DisableIconBarGadgetItem(EditTool, 4, #False) 
    DisableIconBarGadgetItem(EditTool, 5, #False)
    DisableIconBarGadgetItem(EditTool, 6, #False) 
    DisableIconBarGadgetItem(EditTool, 7, #False)   
    ResizeIconBarGadget(EditTool, #PB_Ignore, #IconBar_Auto)
    
  EndIf
  
 EndProcedure
 
Procedure LoadEditedImage(EditedImage.i)
   
  ImgWidth =  ImageWidth(EditedImage)
  Left = (430 - ImgWidth)/2
  ImgHeight =  ImageHeight(EditedImage)
  Top = (430 - ImgHeight)/2 

  StartVectorDrawing(CanvasVectorOutput(cnvEditImage,#PB_Unit_Pixel ))
    
    ;Clear Canvas
    MovePathCursor(0, 0)
    VectorSourceColor(RGBA(255,255,255,255))
    AddPathBox(0,0,430,430)
    FillPath()  
 
    MovePathCursor(Left, Top)
    DrawVectorImage(ImageID(EditedImage))
    StopVectorDrawing()
    TempImage = GetGadgetAttribute(cnvEditImage, #PB_Canvas_Image) 
    CanvasImage =  CreateImage(#PB_Any, 430, 430)
    StartDrawing(ImageOutput(CanvasImage))
    DrawImage(TempImage,0,0)
  StopDrawing()
   
 EndProcedure
 
Procedure RotateImg(Angle.i)
   
  Define TempImage.i
   
  StartVectorDrawing(CanvasVectorOutput(cnvEditImage,#PB_Unit_Pixel ))
    SaveVectorState()

    ;Clear Canvas
    MovePathCursor(0, 0)
    VectorSourceColor(RGBA(255,255,255,255))
    AddPathBox(0,0,430,430)
    FillPath()
    
    ;Draw Rotated Image
    RotateCoordinates(215, 215, Angle) ; rotate by -20 degrees around the (50, 50) point
    MovePathCursor(Left,Top)
    DrawVectorImage(ImageID(ImgToEdit))
    RestoreVectorState()
    
  StopVectorDrawing()
  
  TempImage = GetGadgetAttribute(cnvEditImage, #PB_Canvas_Image)
    
  CanvasImage = CreateImage(#PB_Any, 430, 430)
  StartDrawing(ImageOutput(CanvasImage))
    DrawImage(TempImage,0,0)
  StopDrawing()
    
EndProcedure
 
Procedure GrabSelectedimage(x1.i,y1.i,x2.i,y2.i)
   
  Define TempImage.i
   
  If drawing = #False
    TempImage = CreateImage(#PB_Any, 430, 430)
    StartDrawing(ImageOutput(TempImage))
      DrawImage(ImageID(CanvasImage),0,0)
    StopDrawing()
  EndIf
  ImgEdited = GrabImage(TempImage, #PB_Any, x1,y1,x2-x1,y2-y1)
  LoadEditedImage(ImgEdited)
  FreeImage (TempImage)
 
EndProcedure

   

ImgSelect = CatchImage(#PB_Any,?ToolBarSelect)
ImgCancel = CatchImage(#PB_Any,?ToolBarCancel)
ImgSave  = CatchImage(#PB_Any,?ToolBarSave)
ImgClock = CatchImage(#PB_Any,?ToolBarRotateC)
ImgAntiClock = CatchImage(#PB_Any,?ToolBarRotatAC)
ImgCrop = CatchImage(#PB_Any,?ToolBarCrop)
ImgUndo = CatchImage(#PB_Any,?ToolBarUndo)
ImgHelp = CatchImage(#PB_Any,?ToolBarHelp)  

   
   Define Quit.i
   
dlgCropImage = OpenWindow(#PB_Any, 0, 00, 450, 490, "Select\Edit Image", #PB_Window_SystemMenu)
EditTool = IconBarGadget(0, 0, WindowWidth(dlgCropImage),20,#IconBar_Default,dlgCropImage)
  AddIconBarGadgetItem(EditTool, "Select Image",  ImgSelect)
  AddIconBarGadgetItem(EditTool, "Cancel", ImgCancel)
  AddIconBarGadgetItem(EditTool, "Save As File", ImgSave)
  IconBarGadgetDivider(EditTool)  
  AddIconBarGadgetItem(EditTool, "Rotate Clockwise", ImgClock)
  AddIconBarGadgetItem(EditTool, "Rotate Anticlockwise", ImgAntiClock)
  AddIconBarGadgetItem(EditTool, "Crop", ImgCrop)
  AddIconBarGadgetItem(EditTool, "Back To Original Image", ImgUndo)
  IconBarGadgetSpacer(EditTool) 
  AddIconBarGadgetItem(EditTool, "Help", ImgHelp)  
  ResizeIconBarGadget(EditTool, #PB_Ignore, #IconBar_Auto)
  
  DisableIconBarGadgetItem(EditTool, 2, #True) 
  DisableIconBarGadgetItem(EditTool, 3, #True)
  DisableIconBarGadgetItem(EditTool, 4, #True) 
  DisableIconBarGadgetItem(EditTool, 5, #True)
  DisableIconBarGadgetItem(EditTool, 6, #True) 
  DisableIconBarGadgetItem(EditTool, 7, #True)  
   
   
   
cnvEditImage = CanvasGadget(#PB_Any, 10, 50, 430, 430)

Angle = 0
Drawing = #False
GrabImage = #False
Quit = #False


Repeat
    
  Event = WaitWindowEvent()
  
  Select Event
      
    Case #PB_Event_CloseWindow
      Quit = #True
      CloseWindow(dlgCropImage)

    Case #PB_Event_Gadget
      
      Select EventGadget()
        Case EditTool ;Toolbar event
          Select EventData() ;For each button on toolbar
                
            Case 0 ;Load Image To edit
              LoadSampleImage()
                
            Case 1 ;Close
                
              Quit = #True
              CloseWindow(dlgCropImage)
              
            Case 2 ;Save Image
              Pattern.s = "JPG (*.jpg)|*.jpg;"
              imgFile.s = SaveFileRequester("Please choose file to Save", "C:\", Pattern, 0)
    
              ;Change To All jpg Images
              SaveImage(ImgEdited, imgFile + ".jpg",#PB_ImagePlugin_JPEG)
                
            Case 3
              Angle = Angle + 1
              RotateImg(Angle) 
    
           Case 4   
             Angle = Angle - 1
             RotateImg(Angle)
               
           Case 5 ;Alow User To grab All Or Part Of Image
               
             GrabImage = #True

           Case 6 ;Back To Original Image

             ImgEdited = ImgToEdit
             LoadEditedImage(ImgEdited)
             
           Case 7
               
             Debug "Help"
               
        EndSelect         
          
          
      Case cnvEditImage
         
        If GrabImage = #True
            
          Select EventType()
               
                
            Case #PB_EventType_LeftButtonDown 

              x1 = GetGadgetAttribute(cnvEditImage, #PB_Canvas_MouseX)  
              y1 = GetGadgetAttribute(cnvEditImage, #PB_Canvas_MouseY)
              Drawing = #True
              
            Case #PB_EventType_LeftButtonUp
                  
              x2 = GetGadgetAttribute(cnvEditImage, #PB_Canvas_MouseX)             
              y2 = GetGadgetAttribute(cnvEditImage, #PB_Canvas_MouseY) 
              Drawing = #False
              GrabImage = #False
              GrabSelectedimage(x1,y1,x2,y2)
                  
                  
            Case #PB_EventType_MouseMove
                  
              x2 = GetGadgetAttribute(cnvEditImage, #PB_Canvas_MouseX)             
              y2 = GetGadgetAttribute(cnvEditImage, #PB_Canvas_MouseY)                
              If Drawing = #True
                StartVectorDrawing(CanvasVectorOutput(cnvEditImage,#PB_Unit_Pixel ))
                MovePathCursor(0,0)
                DrawVectorImage(ImageID(CanvasImage))
                VectorSourceColor(RGBA(255,0,0,255))
                AddPathBox(x1,y1,x2-x1,y2-y1)
                DashPath(2,1)
                StopVectorDrawing()
              EndIf                 
                  
          EndSelect
          
        EndIf
         
      EndSelect
      
  EndSelect
  
Until Quit = #True

DataSection

      ToolBarSelect:
        IncludeBinary "Resources\image_edit.png"
      ToolBarCancel:
        IncludeBinary "Resources\Exit.png"  
      ToolBarSave:
        IncludeBinary "Resources\Save.png"
      ToolBarRotateC:
        IncludeBinary "Resources\arrow_rotate_clockwise.png"  
      ToolBarRotatAC:
        IncludeBinary "Resources\arrow_rotate_anticlockwise.png"    
      ToolBarCrop:
        IncludeBinary "Resources\cut_red.png"     
      ToolBarUndo:
      IncludeBinary "Resources\arrow_undo.png"   
      ToolBarHelp:
        IncludeBinary "Resources\help.png"    
  EndDataSection
Hope it helps someone

CD
Any intelligent fool can make things bigger and more complex. It takes a touch of genius — and a lot of courage to move in the opposite direction.