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

Da Gambas-it.org - Wikipedia.
 
(23 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 <SPAN Style="text-decoration:underline">quadrata</span>. 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 14: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: