IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

Return CType((R<<16) Or (G<<8) Or B, Integer)


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Août 2008
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 15
    Par défaut Return CType((R<<16) Or (G<<8) Or B, Integer)
    Bonjour,

    J'ai une fonction qui me retourne en entier une couleur
    mais qui en fait a sa tête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Public Function ColorTranslation(xColor As System.Drawing.Color) As Integer
        Return CType((xColor.R<<16) Or (xColor.G<<8) Or xColor.B, Integer)
    End Function
    Exemple
    Si
    xColor.R = 192
    xColor.G = 192
    xColor.B = 192

    Si je fais cela dans la fenêtre d'exécution
    (192<<16 Or 192<8 Or 192) = 12583104
    Qui est la bonne valeur

    ColorTranslation me retourne 192 ?????

    Je fais comme ça maintenant (Style VB6)
    Return CType(xColor.B * 65536 + xColor.G * 256 + xColor.R, Integer) qui fonctionne

    Je veux comprendre ce qui cloche dans ma fonction ColorTranslation

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Les propriétés R, G et B sont de type Byte, et font donc 8bits, et le résultat de l'opérateur "<<" sur un byte est aussi un byte. Donc quand tu décales de 16 bits vers la gauche, ça "déborde" et ça revient par la droite.
    Donc, si x est un Byte :
    (x << 16) = (x << 8) = x

    Au final, ça te fait donc : 192 Or 192 Or 192 = 192

    Il faut donc traiter R, G et B comme des Integer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        Public Function ColorTranslation(xColor As Color) As Integer
            Dim r As Integer = xColor.R
            Dim g As Integer = xColor.G
            Dim b As Integer = xColor.B
            Return (r << 16) Or (g << 8) Or b
        End Function
    Par contre je sais pas comment tu trouves 12583104, chez moi ça fait 12632256...


    Sinon, inutile de réinventer la roue, ce que tu as fait existe déjà (enfin presque). Il y a la méthode Color.ToArgb qui sert à ça. La seule différence, c'est que ça prend aussi en compte la valeur Alpha de la couleur (transparence) :
    (A << 24) Or (R << 16) Or (G << 8) Or B

    pour une couleur opaque, A vaut 1, donc l'octet de poids fort vaut 256 (&HFF), ce qui fait que l'entier obtenu est négatif... Si tu ne veux pas en tenir compte, tu peux toujours forcer à 0 l'octet de poids fort du résultat de ToArgb :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Public Function ColorTranslation(xColor As Color) As Integer
        Return xColor.ToArgb() And &H00FFFFFF
    End Function

  3. #3
    Membre averti
    Inscrit en
    Août 2008
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 15
    Par défaut
    Merci tomlev

    R, G et B sont de type Byte
    J'ai compris cela, mais j'ai fait ensuite cela
    et ça a pas marcher
    Return CType(xColor.R<<16, Integer) Or CType(xColor.G<<8, Integer) Or CType(xColor.B, Integer)

    Donc, j'ai zappé

    Oui c'est bien 12632256

    j'aurai pas trouver pour enlever la valeur Alpha
    Return xColor.ToArgb() And &H00FFFFFF

    Merci

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par Tropic Voir le message
    J'ai compris cela, mais j'ai fait ensuite cela
    et ça a pas marcher
    Return CType(xColor.R<<16, Integer) Or CType(xColor.G<<8, Integer) Or CType(xColor.B, Integer)
    Arrête de "colorier" le code manuellement, il y a la balise CODE qui sert à ça
    C'est normal que ça ne marche pas : quand tu fais la conversion en Integer, c'est déjà trop tard : le résultat de (xColor.R<<16) est sur 8 bits, donc à ce stade le résultat est déjà tronqué. Il faut convertir xColor.R en Integer AVANT de faire le décalage de bits :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Return CType(xColor.R, Integer) << 16 Or CType(xColor.G, Integer)<<8 Or CType(xColor.B, Integer)
    Citation Envoyé par Tropic Voir le message
    j'aurai pas trouver pour enlever la valeur Alpha
    Return xColor.ToArgb() And &H00FFFFFF
    Ben c'est pas très compliqué en fait... en gros, les 32 bits du nombre sont constitués d'un octet par couleur (A,R,G,B) :
    Code binaire : Sélectionner tout - Visualiser dans une fenêtre à part
    AAAAAAAA RRRRRRRR GGGGGGGG BBBBBBBB

    Pour mettre les A à 0, il faut faire un ET avec un nombre qui a ces bits à 0 :
    Code binaire : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    AAAAAAAA RRRRRRRR GGGGGGGG BBBBBBBB
               ET
    00000000 11111111 11111111 11111111
               =
    00000000 RRRRRRRR GGGGGGGG BBBBBBBB

    et le nombre binaire en question, en héxadécimal, s'écrit 00FFFFFF

  5. #5
    Membre averti
    Inscrit en
    Août 2008
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 15
    Par défaut
    Compris
    Exemple si je veux enlever Alpha et composante Vert
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Return xColor.ToArgb() And &H00FF00FF
    Par contre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CType(xColor.R<<16, Integer)
    j'ai vraiment zapper
    J'aurai du comprendre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CType(xColor.R, Integer)<<16
    Merci pour le petit tuto

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [servlet][bean] return d'une variable
    Par LoLoSS dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 07/05/2004, 16h59
  2. [pl/pgSQL 7.2] Returns Opaque?
    Par Gruik dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 18/10/2003, 16h50
  3. return ();exit() ;
    Par Zazeglu dans le forum C
    Réponses: 12
    Dernier message: 10/10/2003, 20h56
  4. [C#] Changer le focus avec la touche return
    Par sblanc74 dans le forum Windows Forms
    Réponses: 6
    Dernier message: 01/10/2003, 18h38
  5. return
    Par drKzs dans le forum C
    Réponses: 3
    Dernier message: 18/09/2003, 22h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo