none
Je n'arrive pas à tout convertire avec API vb6 vers vbNet, aide svp ? RRS feed

  • Question

  • Bonjour,

    Mon but serait de faire tourner dans le sens trigonométrique et à partir du zéro de ce dernier une image, mais je n'ai pas trouvé grand chose sur vbNet (rotate... ?, avec constance et sens prédéfini ?)... si vous savez ? 

    Exemple, j'écris 10 et l'image tourne dans la piscureBox de 10° d'angle (peut être faudra-il passer en radians, pas grave) ?

    Alors j'ai trouvé une source infernale en vb6 que je tente de passer en vbNet, ça bute sur un seul et unique mot clef, ce qui ne veut pas dire que ça marchera ensuite, alors j'en reparle après le code, voici déjà le code infernal :

     

    '
    ' rotatif : http://www.vbfrance.com/code.aspx?ID=53176
    Option Explicit On
    Public Class Form1
    
      Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Int32, ByVal X As Int32, ByVal Y As Int32, ByVal nWidth As Int32, ByVal nHeight As Int32, ByVal hSrcDC As Int32, ByVal xSrc As Int32, ByVal ySrc As Int32, ByVal dwRop As Int32) As Int32
      Private Declare Function CombineTransform Lib "GDI32.dll" (ByRef lpXFormResult As XForm, ByRef lpXForm1 As XForm, ByRef lpXForm2 As XForm) As Int32
      Private Declare Function SetGraphicsMode Lib "GDI32.dll" (ByVal handle As Long, ByVal iMode As Long) As Int32
      Private Declare Function GetWorldTransform Lib "GDI32.dll" (ByVal handle As Int32, ByRef lpXform As XForm) As Int32
      Private Declare Function SetWorldTransform Lib "GDI32.dll" (ByVal handle As Int32, ByRef lpXform As XForm) As Int32
      Private OldMode As Int32
      Private OldXForm As XForm
      Const PI = 3.14159264
      Const DegToRad = PI / 180
      Const GM_ADVANCED As Int32 = 2
    
      Structure XForm
        Dim eM11 As Single
        Dim eM12 As Single
        Dim eM21 As Single
        Dim eM22 As Single
        Dim eDx As Single
        Dim eDy As Single
      End Structure
    
    
      Sub Form_Load()
        PictureBox2.Image = PictureBox1.Image
      End Sub
    
      Sub Rotation(ByVal Angle As Integer)
        PictureBox2.Image = Nothing
        ActiveNewWorld(PictureBox2, CSng(Angle) * DegToRad)
        Call BitBlt(PictureBox2.Handle, -PictureBox2.Width / 2, -PictureBox2.Height / 2, PictureBox1.Width, PictureBox1.Height, PictureBox1.Handle, 0, 0, VbStrConv) ' vbSrcPaint)
        CloseNewWorld(PictureBox2)
        PictureBox2.Image = PictureBox2.Image
      End Sub
    
      Sub HScrollBar1_Scroll(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ScrollEventArgs) Handles HScrollBar1.Scroll
        Rotation(HScrollBar1.Value)
      End Sub
    
      Sub ActiveNewWorld(ByVal Pic As PictureBox, ByVal A As Single)
        OldMode = SetGraphicsMode(Pic.Handle, GM_ADVANCED)
        Call GetWorldTransform(Pic.Handle, OldXForm)
        Dim NewXForm As XForm
        NewXForm.eM11 = Math.Cos(A)
        NewXForm.eM12 = Math.Sin(A)
        NewXForm.eM21 = Math.Sin(A)
        NewXForm.eM22 = Math.Cos(A)
        NewXForm.eDx = Pic.Width / 2
        NewXForm.eDy = Pic.Height / 2
        Call SetWorldTransform(Pic.Handle, NewXForm)
      End Sub
    
      Sub CloseNewWorld(ByVal Pic As PictureBox)
        Call SetWorldTransform(Pic.Handle, OldXForm)
        Call SetGraphicsMode(Pic.Handle, OldMode)
      End Sub
    
    End Class
    
    


    Ça bute uniquement sur ce mot " VbStrConv", de la ligne :

    Call BitBlt(PictureBox2.Handle, -PictureBox2.Width / 2, -PictureBox2.Height / 2, PictureBox1.Width, PictureBox1.Height, PictureBox1.Handle, 0, 0, VbStrConv) ' vbSrcPaint)
    

    Ainsi, ceci sortant de mes connaissances, si vous pouvez me trouver plus court, ou me faire marcher ce code, je vous en remercie par avance, cordialement.

     



    Joseph Attila PUSZTAY
    EhJoe       Logiciels       Romans       Ecrire
    vendredi 23 décembre 2011 13:16

Réponses

  • Bonjour et bon Noël,

    Cela me donnerait qq chose comme :

     Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        If PictureBox1.Image Is Nothing Then Exit Sub ' picturebox1 vide
        Dim angle As Single = Val(ComboBox1.Text) ' picturebox1 chargée + choix de l'angle (combobox1)
        '
            PictureBox1.Image = New Bitmap(PictureBox1.Width, PictureBox1.Height)
        Dim g As Graphics = Graphics.FromImage(PictureBox1.Image)
            'g.Clear(Color.Transparent)
            g.TranslateTransform(PictureBox1.Width \ 2, PictureBox1.Height \ 2)
            g.RotateTransform(angle)
            'DrawRectangle(Pens.Red, -PictureBox1.Width \ 4, -PictureBox1.Height \ 4, PictureBox1.Width \ 2, PictureBox1.Height \ 2)
            Dim src As Bitmap = CType(My.Resources.ResourceManager.GetObject(ListBox1.Items(ListBox1.SelectedIndex)), Bitmap)
            g.DrawImage(src, -PictureBox1.Width \ 2 - 1, -PictureBox1.Height \ 2 - 1, PictureBox1.Width, PictureBox1.Height)
            g.Dispose()
        PictureBox1.Refresh()
      End Sub
    
    

    J'ai supprimé le AutoSize sur le contrôle PictureBox. C'est cela qui semble faire grandir à chaque fois l'image. J'ai mis aussi actuellement -1 car il y a apparemment un problème de calage.

    Il semble y avoir donc un petit ajustement à faire (les images ne seraient peut-être pas de la même taille que le PictureBox ou le "AutoSize" ne fonctionne pas correctement de manière répétée ????) mais cela devrait déjà être assez proche de ce que l'on veut...

    Cordialement.

     


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".
    • Marqué comme réponse EhJoe dimanche 25 décembre 2011 11:28
    dimanche 25 décembre 2011 10:05
    Modérateur
  • Bonjour Patrice,

    A toi aussi en ce jour de naissance de nôtre Seigneur je te souhaite une joyeuses fêtes de Noël.

    Alors je crois que j'ai trouvé (le plu facile en somme), voici le code, commentaires ensuite :

    g.TranslateTransform(PictureBox1.Width / 2, PictureBox1.Height / 2)
    g.RotateTransform(angle * -1)
    g.DrawImage(src, -PictureBox1.Width \ 2, -PictureBox1.Height \ 2, PictureBox1.Width, PictureBox1.Height)
    


    - Déjà la pictureBox, quand on y met des bords (3d ou autres), ça semble de pas bien gérer (bug ?), par contre si je ne mets rien ça marche....

    - Ligne 1 : En divisant par un entier, bien que le côté du carré soit un integer, si on a une dimension impaire, ben en divisant en entier par 2 "\" on perd 0,5 à chaque opération, peut être que ceci joue aussi, j'ai fait une division classique qui semble être acceptée.

    - Ligne 2 : pour tourner dans le sens universel (et trigonométrique), j'ai multiplié par "-1", ce qui fonctionne, par contre si on tourne pendant un quart d'heure on va arriver à -123467, alors là, je ne sais pas si le programme saura faire le ratio afin de ramener dans une zone de 0 à 359 ou s'il faut que je teste et m'en occupe moi même, je verrais...

    - Ligne 3 : Par contre là, la division classique est refusée, j'ai l'aissé la division avec reste entier, mais ça marche bien néanmoins.

    En conclusion, je te remercie beaucoup, car en vb6 je n'utilisaias pas ces directives, alors c'est difficile de trouver une directive dont on ne sait pas qu'elle existe, puis de comprendres quels sont les paramètres, surtout si c'est écrit en anglais que je ne comprends guère. Je peste toujours devant la complexité de vbNet, car pour moi, si j'avais juste indiqué PictureBox1.rotation.left = x : ceci m'aurait suffit, mais non, il faut en écrire dix lignes avec ce maudit objet graphique que je narrive pas à assimiler corectement...

    Grand merci à toi, ça marche !

    Cordialement :o)

     



    Joseph Attila PUSZTAY
    EhJoe       Logiciels       Romans       Ecrire
    • Marqué comme réponse EhJoe dimanche 25 décembre 2011 11:28
    dimanche 25 décembre 2011 11:27

Toutes les réponses

  • Bonjour,

    Dans ce contexte vbStrConv est incomplet et ne semble pas avoir de sens (http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.vbstrconv.aspx). Ce n'était pas plutôt vbSrcPaint, le dernier paramètre indiquant effectivement le mode de copie de l'image ? vbScrPaint vaut normalement &hEE0086

    Ces fonctions étant maintenant dispo directement avec .NET je proposerais à titre de démo qq chose comme :

    Private a As Single
    
        Private Sub Draw(ByVal angle As Single)
            Dim g As Graphics = Graphics.FromImage(PictureBox1.Image)
            g.Clear(Color.Transparent)
            g.TranslateTransform(PictureBox1.Width \ 2, PictureBox1.Height \ 2)
            g.RotateTransform(angle)
            g.DrawRectangle(Pens.Red, -PictureBox1.Width \ 4, -PictureBox1.Height \ 4, PictureBox1.Width \ 2, PictureBox1.Height \ 2)
            g.Dispose()
            PictureBox1.Refresh()
        End Sub
        Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
            Timer1.Interval = 5
            Timer1.Start()
            PictureBox1.Image = New Bitmap(PictureBox1.Width, PictureBox1.Height)
        End Sub
        Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
            a += 5
            Draw(a)
        End Sub
    

    Le dessin est effacé, l'origine mise au centre, avec application d'une rotation variable puis on trace un rectangle. On recommence régulièrement en changeant l'angle ce qui fait tourner le rectangle sur lui-même. Idem avec une image  ou quoi que ce soit d'autre...

     


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".
    vendredi 23 décembre 2011 14:22
    Modérateur
  • Bonjour Patrice,

    Merci, ce n'est pas ça, mais on s'en approche, manque plus que la bonne directive dans doute, voici le code et ensuite la suite des commentaires

     

    Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        If PictureBox1.Image Is Nothing Then Exit Sub ' picturebox1 vide
        Dim angle As Single = Val(ComboBox1.Text) ' picturebox1 chargée + choix de l'angle (combobox1)
        '
        PictureBox1.Image = New Bitmap(PictureBox1.Width, PictureBox1.Height)
        Dim g As Graphics = Graphics.FromImage(PictureBox1.Image)
        g.Clear(Color.Transparent)
        g.TranslateTransform(PictureBox1.Width \ 2, PictureBox1.Height \ 2)
        g.RotateTransform(angle)
        g.DrawRectangle(Pens.Red, -PictureBox1.Width \ 4, -PictureBox1.Height \ 4, PictureBox1.Width \ 2, PictureBox1.Height \ 2)
        g.Dispose()
        PictureBox1.Refresh()
      End Sub
    
    

     

     

    Alors, en fait, la pictureBox est un carré, et dedans devrait troune un image ronde, que doit-on mettre comme code s'il te plaît, car là tu as dessiné un rectangle qui en plus grandi à chaque fois qu'il toune, je ne sais même pas s'il tourne, mais par contre il double de taille à chaque appel, et le but ce n'est pas de le changer de taille mais de le faire tourner... Sais-tu ?

    PS je t'ai envoyé un mail avec le code du fichier sur hotmail.

    Cordialement.

     



    Joseph Attila PUSZTAY
    EhJoe       Logiciels       Romans       Ecrire

    • Modifié EhJoe vendredi 23 décembre 2011 21:03 ajout PS
    vendredi 23 décembre 2011 20:57
  • Bonjour et bon Noël,

    Cela me donnerait qq chose comme :

     Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        If PictureBox1.Image Is Nothing Then Exit Sub ' picturebox1 vide
        Dim angle As Single = Val(ComboBox1.Text) ' picturebox1 chargée + choix de l'angle (combobox1)
        '
            PictureBox1.Image = New Bitmap(PictureBox1.Width, PictureBox1.Height)
        Dim g As Graphics = Graphics.FromImage(PictureBox1.Image)
            'g.Clear(Color.Transparent)
            g.TranslateTransform(PictureBox1.Width \ 2, PictureBox1.Height \ 2)
            g.RotateTransform(angle)
            'DrawRectangle(Pens.Red, -PictureBox1.Width \ 4, -PictureBox1.Height \ 4, PictureBox1.Width \ 2, PictureBox1.Height \ 2)
            Dim src As Bitmap = CType(My.Resources.ResourceManager.GetObject(ListBox1.Items(ListBox1.SelectedIndex)), Bitmap)
            g.DrawImage(src, -PictureBox1.Width \ 2 - 1, -PictureBox1.Height \ 2 - 1, PictureBox1.Width, PictureBox1.Height)
            g.Dispose()
        PictureBox1.Refresh()
      End Sub
    
    

    J'ai supprimé le AutoSize sur le contrôle PictureBox. C'est cela qui semble faire grandir à chaque fois l'image. J'ai mis aussi actuellement -1 car il y a apparemment un problème de calage.

    Il semble y avoir donc un petit ajustement à faire (les images ne seraient peut-être pas de la même taille que le PictureBox ou le "AutoSize" ne fonctionne pas correctement de manière répétée ????) mais cela devrait déjà être assez proche de ce que l'on veut...

    Cordialement.

     


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".
    • Marqué comme réponse EhJoe dimanche 25 décembre 2011 11:28
    dimanche 25 décembre 2011 10:05
    Modérateur
  • Bonjour Patrice,

    A toi aussi en ce jour de naissance de nôtre Seigneur je te souhaite une joyeuses fêtes de Noël.

    Alors je crois que j'ai trouvé (le plu facile en somme), voici le code, commentaires ensuite :

    g.TranslateTransform(PictureBox1.Width / 2, PictureBox1.Height / 2)
    g.RotateTransform(angle * -1)
    g.DrawImage(src, -PictureBox1.Width \ 2, -PictureBox1.Height \ 2, PictureBox1.Width, PictureBox1.Height)
    


    - Déjà la pictureBox, quand on y met des bords (3d ou autres), ça semble de pas bien gérer (bug ?), par contre si je ne mets rien ça marche....

    - Ligne 1 : En divisant par un entier, bien que le côté du carré soit un integer, si on a une dimension impaire, ben en divisant en entier par 2 "\" on perd 0,5 à chaque opération, peut être que ceci joue aussi, j'ai fait une division classique qui semble être acceptée.

    - Ligne 2 : pour tourner dans le sens universel (et trigonométrique), j'ai multiplié par "-1", ce qui fonctionne, par contre si on tourne pendant un quart d'heure on va arriver à -123467, alors là, je ne sais pas si le programme saura faire le ratio afin de ramener dans une zone de 0 à 359 ou s'il faut que je teste et m'en occupe moi même, je verrais...

    - Ligne 3 : Par contre là, la division classique est refusée, j'ai l'aissé la division avec reste entier, mais ça marche bien néanmoins.

    En conclusion, je te remercie beaucoup, car en vb6 je n'utilisaias pas ces directives, alors c'est difficile de trouver une directive dont on ne sait pas qu'elle existe, puis de comprendres quels sont les paramètres, surtout si c'est écrit en anglais que je ne comprends guère. Je peste toujours devant la complexité de vbNet, car pour moi, si j'avais juste indiqué PictureBox1.rotation.left = x : ceci m'aurait suffit, mais non, il faut en écrire dix lignes avec ce maudit objet graphique que je narrive pas à assimiler corectement...

    Grand merci à toi, ça marche !

    Cordialement :o)

     



    Joseph Attila PUSZTAY
    EhJoe       Logiciels       Romans       Ecrire
    • Marqué comme réponse EhJoe dimanche 25 décembre 2011 11:28
    dimanche 25 décembre 2011 11:27