Ruotare una immagine sul proprio asse centrale

Da Gambas-it.org - Wikipedia.

Per ruotare un'immagine rigorosamente intorno al proprio asse centrale (isometria diretta), mantenendo in modo costante e coerente la sua distanza dal Controllo che contiene l'oggetto "Immagine", possiamo adottare alcune modalità.


Uso di una PictureBox e di un Contenitore HSplit

La prima modalità è la più semplice da realizzare, prevede l'uso di una PictureBox e di un Contenitore HSplit.

Mostriamo un semplice e pratico esempio:

Public Sub Form_Activate()
 
 Dim im As Image
 Dim hs As HSplit
 Dim pbx As PictureBox
 Dim s As Short
 
  im = Image.Load("/percorso/del/file/immagine")
 
  With hs = New HSplit(Me)
    .X = 20
    .Y = 20
    .W = im.W
    .H = im.H
  End With
 
  With pbx = New PictureBox(hs)
    .Alignment = 3
    .Expand = True
    .Picture = im.Picture
  End With
  
  Do
    For s = 0 To 360
      pbx.Picture = im.Rotate(Rad(s)).Picture
      Wait 0.004
    Next
  Loop
  
End

Per effettuare la rotazione al contrario la riga del ciclo "For" sarà impostata come segue:

For s = 0 To -360 Step -1


Uso di una DrawingArea e delle Classi Paint e PaintBrush

Un'altra modalità prevede l'uso di una DrawingArea e le risorse delle Classi Paint e PaintBrush |1| e poniamo sul Form una DrawingArea.

La rotazione dell'immagine viene esercitata dal metodo

Paint.Rotate(Rad(valore_in_gradi))

Se si intende ruotare l'immagine in senso orario, bisognerà porre valori negativi dei gradi: Paint.Rotate(Rad(-valore_in_gradi)).


Nel seguente esempio pratico, una immagine di dimensioni 150x150 pixel sarà ruotata di 45° in senso antiorario:

Private im As Image


Public Sub  Form_Open()

  im = Image.Load("/percorso/del/file/immagine")

' Rendiamo la "DrawingArea" delle medesime dimensioni dell'immagine caricata:
  With DrawingArea1
    .W = im.W
    .H = im.H
  End With

End


Public Sub DrawingArea1_Draw()

 Dim pb As PaintBrush
 
  With Paint
' Creiamo un oggetto "PaintBrush" mediante l'immagine caricata:
    pb = Paint.Image(im)          
    pb.Scale(DrawingArea1.W / im.W, DrawingArea1.H / im.H)

' I valori associati ai parametri di questo metodo devono
' essere sempre pari alla metà della dimensione dell'immagine caricata:
    .Translate(im.W / 2, im.H / 2)
' Ruotiamo l'immagine di 45° in senso antiorario:
    .Rotate(Rad(45))
    .Translate(-im.W / 2, -im.H / 2)
    .Brush = pb
    .Rectangle(0, 0, DrawingArea1.W, DrawingArea1.H)
    .Fill
    .End
  End With
 
End


In quest'altro esempio, simile al precedente, sarà possibile ruotare un'immagine di 270° mediante uno Slider o mediante la rotellina del mouse oppure mediante il puntatore del mouse tenendo premuto un tasto:

Private im As Image
Private c As Short


Public Sub Form_Open()

 Me.Show

 im = Image.Load("/percorso/del/file/immagine")

 With DrawingArea1
   .W = im.W
   .h = im.H
 End With
 
End


Public Sub DrawingArea1_Draw()

 Dim pb As PaintBrush

  With Paint
    pb = .Image(im)          
    pb.Scale(DrawingArea1.W / im.W, DrawingArea1.H / im.H)
    .Translate(im.W / 2, im.H / 2)
    .Rotate(Rad(-1 * c))
   .Translate(- im.W / 2, - im.H / 2)
   .Brush = pb
   .Rectangle(0, 0, DrawingArea1.W, DrawingArea1.H)
   .Fill
   .End
 End With

End


Public Sub Slider1_Change()

 c = Slider1.Value

 DrawingArea1.Refresh()

End


Public Sub DrawingArea1_MouseWheel()

 c = c + (1 * Mouse.Delta)
 
 Slider1.Value = c

 DrawingArea1.Refresh()
 
End


Public Sub DrawingArea1_MouseMove()

 c = 270 - (Round(270 / im.H) * Mouse.Y)
  
 If c < 0 Then c = 0
 If c > 270 Then c = 270

 Slider1.Value = c

 DrawingArea1.Refresh()

End


Esempio con altro codice

In quest'altro esempio si effettuerà ancora una volta la rotazione con un'immagine quadrata. La rotazione avverrà con sedici spostamenti ciscuno da 22,5 gradi in senso antiorario, utilizzando valori per l'aggiustamento dell'immagine riscontrati empiricamente.
Si porranno sul Form una DrawingArea, uno Slider, un ValueBox ed una TextArea:

Private im As Image
Private c As Single
Private wa As Single


Public Sub Form_Open()

 Me.Show

 Slider1.Value = 100
 ValueBox1.Value = Slider1.Value / 100
 im = Image.Load("/percorso/del/file/con/immagine/quadrata")

 With DrawingArea1
   .W = im.W
   .H = im.H
 End With

 While True
   c += 22.5
   If c > 360 Then c = 22.5
   DrawingArea1.Refresh()
   Wait wa
 Wend

End


Public Sub DrawingArea1_Draw()

 With Paint
   .Begin(DrawingArea1)
   .Rotate(Rad(c))
   Select Case c
     Case 22.5
       .DrawImage(im, (-34 * im.W) / 150, (23 * im.W) / 150)
     Case 45
       .DrawImage(im, (-75 * im.W) / 150, (32 * im.W) / 150)
     Case 67.5
       .DrawImage(im, (-115 * im.W) / 150, (23 * im.W) / 150)
     Case 90
       .DrawImage(im, (-150 * im.W) / 150, 0)
     Case 112.5
       .DrawImage(im, (-173.5 * im.W) / 150, (-34 * im.W) / 150)
     Case 135
       .DrawImage(im, (-181.5 * im.W) / 150, (-75 * im.W) / 150)
     Case 157.5
       .DrawImage(im, (-173.5 * im.W) / 150, (-115 * im.W) / 150)
     Case 180
       .DrawImage(im, (-150 * im.W) / 150, (-150 * im.W) / 150)
     Case 202.5
       .DrawImage(im, (-115 * im.W) / 150, (-173.5 * im.W) / 150)
     Case 225
       .DrawImage(im, (-75 * im.W) / 150, (-181.5 * im.W) / 150)
     Case 247.5
       .DrawImage(im, (-34 * im.W) / 150, (-173.5 * im.W) / 150)
     Case 270
       .DrawImage(im, 0, (-150 * im.W) / 150)
     Case 292.5
       .DrawImage(im, (23 * im.W) / 150, (-115 * im.W) / 150)
     Case 315
       .DrawImage(im, (32 * im.W) / 150, (-75 * im.W) / 150)
     Case 337.5
       .DrawImage(im, (23 * im.W) / 150, (-34 * im.W) / 150)
     Case 360
       .DrawImage(im, 0, 0)
   End Select
   .end
 End With
 
 TextLabel1.Text = CStr(c)

End


Public Sub Slider1_Change()

 wa = Slider1.Value / 100
 ValueBox1.Value = Slider1.Value / 100
 
End



Note

[1] L'uso combinato delle Classi Paint e PaintBrush, come nell'esempio, evita che l'oggetto Image si sposti in senso verticale e/o orizzontale durante la sua rotazione, come avviene se si utilizza semplicemente il metodo .Rotate() della Classe Image .