Differenze tra le versioni di "Ruotare una immagine sul proprio asse centrale"

Da Gambas-it.org - Wikipedia.
 
(24 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
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'<I>oggetto</i> "Immagine", possiamo adottare una modalità che prevede l'uso di una ''DrawingArea''.
+
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 "Image", possiamo adottare alcune modalità.
  
 +
==Uso del Metodo ".Rotate()" della Classe Image==
 +
Innanzitutto si potrà utilizzare  una "PictureBox" e il solo Metodo ".Rotate()" della Classe "Image".
 +
<BR>Va sottolineato che <SPAN Style="text-decoration:underline">la "PictureBox" deve avere la Proprietà ".Alignment" impostata ad "Align.Center"</span>.
 +
Public Sub Button1_Click()
 +
 
 +
  Dim r As Short
 +
 
 +
  While True
 +
    With PictureBox1
 +
      .Image = Image.Load("<FONT Color=darkgreen>''/percorso/del/file/immagine''</font>")
 +
      .<FONT Color=#B22222>Alignment = Align.Center</font>
 +
      .W = .Image.W
 +
      .H = .Image.H
 +
      .Image = .Image.<FONT Color=#B22222>Rotate(Rad(r))</font>
 +
    End With
 +
    Wait 0.01
 +
    Inc r
 +
    If r == 360 Then r = 0
 +
  Wend
 +
 
 +
End
  
Con questa modalità utilizziamo le risorse delle Classi ''Paint'' e ''PaintBrush'' |[[#Note|1]]| e poniamo sul ''Form'' una ''DrawingArea''.
 
  
La rotazione dell'immagine viene esercitata dal metodo
+
==Uso di una ''PictureBox'' e di un Contenitore ''HSplit''==
''Paint.Rotate(Rad(valore_in_gradi))''
+
Un'altra modalità prevede ancora l'uso di una ''PictureBox'' e del Contenitore ''HSplit''.
Se si intende ruotare l'immagine in senso orario, bisognerà porre valori ''negativi'' dei gradi: ''Paint.Rotate(Rad(-valore_in_gradi))''.
+
<BR>Anche in questo caso <SPAN Style="text-decoration:underline">la ''PictureBox'' deve avere la Proprietà ".Alignment" impostata ad "Align.Center"</span>.
  
 
+
Mostriamo un semplice e pratico esempio:
Nel seguente esempio pratico, una immagine di dimensioni 150x150 pixel sarà ruotata di 45° in senso antiorario:
+
  Public Sub Form_Activate()
  Private im As Image
+
 
+
  Dim im As Image
+
  Dim hs As HSplit
'''Public''' Sub Form_Open()
+
  Dim pbx As PictureBox
+
   Dim s As Short
  im = Image.Load("''/percorso/dell'immagine''")
 
 
<FONT color=gray>' ''Rendiamo la "DrawingArea" delle medesime dimensioni dell'immagine caricata:''</font>
 
  With DrawingArea1
 
    .W = im.W
 
    .H = im.H
 
  End With
 
 
'''End'''
 
 
 
'''Public''' Sub DrawingArea1_Draw()
 
 
   Dim pb As PaintBrush
 
 
    
 
    
  With Paint
+
  im = Image.Load("<FONT Color=darkgreen>''/percorso/del/file/immagine''</font>")
<FONT color=gray>' ''Creiamo un oggetto "PaintBrush" mediante l'immagine caricata:''</font>
 
    pb = Paint.Image(im)         
 
    pb.Scale(DrawingArea1.W / im.W, DrawingArea1.H / im.H)
 
 
<FONT color=gray>' ''I valori associati ai parametri di questo metodo devono''
 
' ''essere sempre pari alla metà della dimensione dell'immagine caricata:''</font>
 
    .Translate(im.W / 2, im.H / 2)
 
<FONT color=gray>' ''Ruotiamo l'immagine di 45° in senso antiorario:''</font>
 
    .Rotate(Rad(45))
 
    .Translate(-im.W / 2, -im.H / 2)
 
    .Brush = pb
 
    .Rectangle(0, 0, DrawingArea1.W, DrawingArea1.H)
 
    .Fill
 
    .End
 
  End With
 
 
    
 
    
'''End'''
+
  With hs = New HSplit(Me)
 
+
    .X = 20
 
+
    .Y = 20
 
 
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/dell'immagine''")
 
 
  With DrawingArea1
 
 
     .W = im.W
 
     .W = im.W
     .h = im.H
+
     .H = im.H
 
   End With
 
   End With
 
    
 
    
'''End'''
+
   With pbx = New PictureBox(hs)
+
     .<FONT Color=#B22222>Alignment = Align.Center</font>
+
     .Expand = True
'''Public''' Sub DrawingArea1_Draw()
+
     .Image = im
 
   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 With
 +
 
 +
  Do
 +
    For s = 0 To 360
 +
      pbx.Image = im.<FONT Color=#B22222>Rotate(Rad(s))</font>
 +
      Wait 0.01
 +
    Next
 +
  Loop
 
   
 
   
  '''End'''
+
  <FONT Color=gray>' ''Oppure con due cicli annidati:''
+
  '''Do'''
+
    '''Repeat'''
'''Public''' Sub Slider1_Change()
+
      '''pbx.Image = im.Rotate(Rad(s))'''
+
      '''Wait 0.01'''
  c = Slider1.Value
+
      '''Inc s'''         ''oppure: Dec s''
+
    '''Until s == 360'''   ''oppure: -360''
  DrawingArea1.Refresh()
+
    '''s = 0'''
+
  '''Loop'''</font>
'''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
+
End
  If c > 270 Then c = 270
+
Per effettuare la rotazione al contrario la riga del ciclo "For" sarà impostata come segue:
+
For s = 0 To -360 Step -1
  Slider1.Value = c
+
 
+
 
  DrawingArea1.Refresh()
+
==Uso di una ''DrawingArea'' e dei Metodi ".Rotate()" e ".Translate()" della Classe "Paint"==
+
Un'altra modalità prevede l'uso di una ''DrawingArea'' e dei Metodi ".Rotate()" e ".Translate()" della Classe "Paint". <SUP>&#091;[[#Note|<B>nota 1</b>]]&#093;</sup>
'''End'''
 
  
 +
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))''.
  
====Esempio con altro codice====
+
Nel seguente esempio pratico, una immagine di uguali dimensioni sarà ruotata verso destra o verso sinistra premendo i tasti della tastiera "freccia in su" e "freccia in giù":
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.
+
Private DrawingArea1 As DrawingArea
<BR>Si porranno sul ''Form'' una ''DrawingArea'', uno ''Slider'', un ''ValueBox'' ed una ''TextArea'':
 
 
  Private im As Image
 
  Private im As Image
  Private c As Single
+
  Private ang As Float
Private wa As Single
 
 
   
 
   
 
   
 
   
  '''Public''' Sub Form_Open()
+
  Public Sub Form_Open()
 
   
 
   
  Me.Show
+
   im = Image.Load("<FONT Color=darkgreen>''/percorso/del/file/immagine''</font>")
+
 
  Slider1.Value = 100
+
   With Me
  ValueBox1.Value = Slider1.Value / 100
+
     .W = im.W * 3
   im = Image.Load("''/percorso/dell'immagine/quadrata''")
+
     .H = im.H * 2
+
    .Center
   With DrawingArea1
+
    .Arrangement = Arrange.Fill
     .W = im.W
+
  End With
     .H = im.H
+
 
 +
  With DrawingArea1 = New DrawingArea(Me) As "DrawingArea1"
 +
    .x = 0
 +
    .Y = 0
 +
    .Background = Color.White
 
   End With
 
   End With
 
   
 
   
  While True
+
  End
    c += 22.5
+
 
    If c > 360 Then c = 22.5
 
    DrawingArea1.Refresh()
 
    Wait wa
 
  Wend
 
 
  '''End'''
 
 
 
'''Public''' Sub DrawingArea1_Draw()
 
 
   
 
   
 +
Public Sub DrawingArea1_Draw()
 +
 
 
   With Paint
 
   With Paint
    .Begin(DrawingArea1)
+
<FONT Color=gray>' ''Imposta il fulcro/punto della rotazione - ad esempio -al centro dell'area di disegno:''</font>
    .Rotate(Rad(c))
+
    <FONT Color=red>.Translate</font>(DrawingArea1.W / 2, DrawingArea1.H / 2)
    Select Case c
+
<FONT color=gray>' ''Ruota l'immagine:''</font>
      Case 22.5
+
    <FONT Color=red>.Rotate(Rad(ang))</font>
        .DrawImage(im, (-34 * im.W) / 150, (23 * im.W) / 150)
+
<FONT color=gray>' ''Siccome l'angolo ruota su se stesso, si dà alle coordinate dell'immagine mezza dimensione negativa di se stessa.''
      Case 45
+
' ''Non si devono modificare i valori né i segni degli ultimi quattro argomenti qui riportati.''</font>
        .DrawImage(im, (-75 * im.W) / 150, (32 * im.W) / 150)
+
    .DrawImage(im, -im.W / 2, -im.H / 2, -im.W, -im.H)
      Case 67.5
+
    .End
        .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
 
   End With
 
    
 
    
  TextLabel1.Text = CStr(c)
+
End
 
   
 
   
'''End'''
 
 
   
 
   
 +
Public Sub Form_KeyPress()
 +
 
 +
  Select Case Key.Code
 +
    Case Key.Up
 +
      ang += 1
 +
      If ang = 361 Then ang = 1
 +
    Case Key.Down
 +
      ang -= 1
 +
      If ang = -361 Then ang = -1
 +
  End Select
 +
 +
  DrawingArea1.Refresh
 +
 
 +
End
 
   
 
   
'''Public''' Sub Slider1_Change()
 
 
   
 
   
  wa = Slider1.Value / 100
+
Public Sub Form_Resize()  <FONT color=gray>' ''Con questo evento se cambia la dimensione del Form, il disegno non va perso''</font>
   ValueBox1.Value = Slider1.Value / 100
+
 
 +
   DrawingArea1.Refresh
 
    
 
    
  '''End'''
+
  End
 
 
  
  
  
 
=Note=
 
=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'' .
+
[1] Vedere anche queste pagine:
 +
* [[Ruotare un'immagine sul proprio asse centrale in una DrawingArea]]
 +
* [[Ruotare qualsiasi elemento da disegnare in una DrawingArea]]

Versione attuale delle 13:33, 3 lug 2024

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 "Image", possiamo adottare alcune modalità.

Uso del Metodo ".Rotate()" della Classe Image

Innanzitutto si potrà utilizzare una "PictureBox" e il solo Metodo ".Rotate()" della Classe "Image".
Va sottolineato che la "PictureBox" deve avere la Proprietà ".Alignment" impostata ad "Align.Center".

Public Sub Button1_Click()
 
 Dim r As Short
 
 While True
   With PictureBox1
     .Image = Image.Load("/percorso/del/file/immagine")
     .Alignment = Align.Center
     .W = .Image.W
     .H = .Image.H
     .Image = .Image.Rotate(Rad(r))
   End With
   Wait 0.01
   Inc r
   If r == 360 Then r = 0
 Wend
 
End


Uso di una PictureBox e di un Contenitore HSplit

Un'altra modalità prevede ancora l'uso di una PictureBox e del Contenitore HSplit.
Anche in questo caso la PictureBox deve avere la Proprietà ".Alignment" impostata ad "Align.Center".

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 = Align.Center
   .Expand = True
   .Image = im
 End With
  
 Do
   For s = 0 To 360
     pbx.Image = im.Rotate(Rad(s))
     Wait 0.01
   Next
 Loop

' Oppure con due cicli annidati:
 Do
   Repeat
     pbx.Image = im.Rotate(Rad(s))
     Wait 0.01
     Inc s          oppure: Dec s
   Until s == 360   oppure: -360
   s = 0
 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 dei Metodi ".Rotate()" e ".Translate()" della Classe "Paint"

Un'altra modalità prevede l'uso di una DrawingArea e dei Metodi ".Rotate()" e ".Translate()" della Classe "Paint". [nota 1]

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 uguali dimensioni sarà ruotata verso destra o verso sinistra premendo i tasti della tastiera "freccia in su" e "freccia in giù":

Private DrawingArea1 As DrawingArea
Private im As Image
Private ang As Float


Public Sub  Form_Open()

 im = Image.Load("/percorso/del/file/immagine")
 
 With Me
   .W = im.W * 3
   .H = im.H * 2
   .Center
   .Arrangement = Arrange.Fill
 End With 
 
 With DrawingArea1 = New DrawingArea(Me) As "DrawingArea1"
   .x = 0
   .Y = 0
   .Background = Color.White
 End With

End
 

Public Sub DrawingArea1_Draw()
 
 With Paint
' Imposta il fulcro/punto della rotazione - ad esempio -al centro dell'area di disegno:
   .Translate(DrawingArea1.W / 2, DrawingArea1.H / 2)
' Ruota l'immagine:
   .Rotate(Rad(ang))
' Siccome l'angolo ruota su se stesso, si dà alle coordinate dell'immagine mezza dimensione negativa di se stessa.
' Non si devono modificare i valori né i segni degli ultimi quattro argomenti qui riportati.
   .DrawImage(im, -im.W / 2, -im.H / 2, -im.W, -im.H)
   .End
 End With
 
End


Public Sub Form_KeyPress()
 
 Select Case Key.Code
   Case Key.Up
     ang += 1
     If ang = 361 Then ang = 1
   Case Key.Down
     ang -= 1
     If ang = -361 Then ang = -1
 End Select

 DrawingArea1.Refresh
 
End


Public Sub Form_Resize()  ' Con questo evento se cambia la dimensione del Form, il disegno non va perso
 
 DrawingArea1.Refresh
 
End


Note

[1] Vedere anche queste pagine: