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

avec Java Discussion :

Créer un dégradé à plusieurs couleurs et récupérer une couleur à l'aide d'une valeur


Sujet :

avec Java

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Territoire de Belfort (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Août 2017
    Messages : 20
    Points : 18
    Points
    18
    Par défaut Créer un dégradé à plusieurs couleurs et récupérer une couleur à l'aide d'une valeur
    Bonjour à tous,

    Je souhaite réaliser une fonction qui permet de récupérer une couleur dans un dégradé de jaune à violet (en passant par vert et bleu) avec en paramètre une valeur comprise entre 0.0 et 10.0 (associé une valeur à une couleur unique, et que par exemple on obtient du bleu pour la valeur 8.0 et du bleu/violet pour 9.0 )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public Color getColor(double valeur);
    J'avais déjà réaliser un dégradé entre du vert et rouge pour symboliser une probabilité mais c'était une probabilité comprises entre 0 et 1 et une couleur comprise entre 2 valeurs du code RGB.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    double proba = 0.4;
    Color c = new Color((float) (1f-proba),(float) (1f-proba),(float)0.0);

    Je ne vois vraiment pas comment faire pour réaliser ce dégradé à plusieurs couleurs.
    Pouvez vous me donner des indices sur comment faire ? Un algo java ou un algo en pseudo-code pour le faire ? Une API vers laquelle me tourner ?


    Merci pour tous le temps que vous consacrez à lire et à répondre à ma requête.

    Bakamii.

  2. #2
    Membre expérimenté Avatar de herve91
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 282
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 282
    Points : 1 608
    Points
    1 608
    Par défaut
    Bonsoir,

    si je comprends bien, tu veux associer une couleur dans le spectre jaune - violet à une valeur décimale comprise entre 0.0 et 10.0
    En regardant sur le net, on trouve
    • jaune #FFFF00
    • magenta #FF00FF

    Il s'agit donc d'une application linéaire de [0.0, 10.0] vers [#FFFF00, #FF00FF] :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    y = ax + b avec a = (#FF00FF - #FFFF00) / 10.0 = (16711935 - 16776960) / 10.0 = -6502.5 et b = #FFFF00 = 16776960
    y = -6502.5x + 16776960
     
    public Color getColor(double valeur) {
       if (valeur < 0.0 || valeur > 10.0) {
          throw new IllegalArgumentException("La valeur [" + valeur + "] devrait être comprise entre 0.0 et 10.0");
       }
       return new Color((int) (-6502.5 * valeur + 16776960));
    }

  3. #3
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Mouai vu que là on bosse sur 3 dimensions (R, G et B) qui varient indépendamment l'une de l'autre ne ne suis pas vraiment sur qu'on obtienne toujours le résultat escompté...

    Le modèle HSB (hue saturation brightness : Teinte saturation lumière) peut être utilisé pour simplifier encore plus l’équation : le jaune est aux alentours de 60° et le magenta aux alentours de 300°.
    Passer du jaune au magenta en traversant le vert et le bleu consiste donc juste en une variation croissante de l'angle H, une seule dimension qui varie donc puisque S et B restent constants.



    Cela devient donc assez simple d'obtenir la couleur voulue.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    // En Java2D H, S et B sont compris entre 0 et 1.
    float h2 = Color.RGBtoHSB(Color.YELLOW.getRed(), Color.YELLOW.getGreen(), Color.YELLOW.getBlue(), null)[0];
    float h2 = Color.RGBtoHSB(Color.MAGENTA.getRed(), Color.MAGENTA.getGreen(), Color.MAGENTA.getBlue(), null)[0];
    float h3 = h1 +  facteur * (h2 - h1);
    float s3 = 1;
    float b3 = 1;
    Color c3 = Color.getHSBColor(h3, s3, b3);
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  4. #4
    Membre expérimenté Avatar de herve91
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 282
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 282
    Points : 1 608
    Points
    1 608
    Par défaut
    Effectivement, je ne connaissais pas le modèle HSB, qui permet de faire varier uniquement la teinte.
    Si on raisonne dans le modèle RGB, l'équation initiale doit être réécrite pour chacune des 3 dimensions.
    Dans ce cas, on obtient les spectres suivants, en haut selon la variation RGB, en bas selon la variation HSB :

    Nom : Capture.PNG
Affichages : 3834
Taille : 11,7 Ko

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Territoire de Belfort (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Août 2017
    Messages : 20
    Points : 18
    Points
    18
    Par défaut
    Bonjour à vous,

    D'abord merci à vous deux de m'avoir répondu et de m'avoir proposé une solution.

    J'ai testé les 2 méthodes proposées, celle de Bouye me convient mieux car elle passe bien par les couleurs vertes et bleues alors que celle de herve91 reste entre jaune et magenta.

    En inspectant le résultat obtenu de la méthode de Bouye, je m’aperçois que ça va me poser d'autres problèmes pour lesquelles je n'avais pas anticipé :

    La différence de couleur entre certaines valeurs (à 0.05 près) est pas assez flagrante pour l'utilisateur. Y a t il un moyen pour accentué les couleurs ?
    J'ai essayé d'étirer la plage de couleurs en rajoutant le rouge avant le jaune mais les couleurs à 0.05 près restent trop similaires.

    Autre approche : Existe t il un modèle comme le HSB qui comprends les couleurs qui n'apparaissent pas dans le spectre de la lumière ? ( marron(s) , beige, vert foncé , ...)

    Problème annexe moins important :
    Ces couleurs ont pour but de servir de background en fonction d'une valeur, et faut que le texte soit visible
    Est-il possible de pâlir une couleur après coup ? J'ai pu voir qu'il existait une méthode brighter() et darker() pour la classe Color, mais comme leur nom l'indique elles modifient plus la "lumière" de la couleur que sa "pâleur".
    Idées, Indices, API ?

    Merci pour vos réponses passés et potentiellement futures

    Bakamii.
    Images attachées Images attachées   

  6. #6
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    Le but c'est de finalement afficher un dégradé ? Pourquoi ne pas utiliser directement les classes faites pour ça ? Par exemple en Swing :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    public class ExempleGradient {
     
    	public static Color COLOR_1 = Color.YELLOW;
    	public static Color COLOR_2 = Color.MAGENTA;
     
    	public static void main(String[] args) {
     
     
    		JFrame frame = new JFrame("Démo");
     
     
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
     
    		JPanel panel = new JPanel() {
    			protected void paintComponent(java.awt.Graphics g) {
    				Graphics2D g2d = (Graphics2D) g;
    				int width = getWidth();
    				int height = getHeight();
    				g2d.setPaint(new GradientPaint(new Point(0,0), COLOR_1, new Point(width,0), COLOR_2));
    				g.fillRect(0, 0, width, height);
    			}
    		};
     
    		frame.add(panel);
     
    		frame.setSize(600, 400);
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true); 
     
    	}
     
    }
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    public class ExempleGradient2 {
     
    	public static Color[] COLORS = {Color.YELLOW,Color.MAGENTA,Color.CYAN};
    	public static float[] FRACTIONS = {0,.5f,1f};
     
    	public static void main(String[] args) {
     
     
    		JFrame frame = new JFrame("Démo");
     
     
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
     
    		JPanel panel = new JPanel() {
    			protected void paintComponent(java.awt.Graphics g) {
    				Graphics2D g2d = (Graphics2D) g;
    				int width = getWidth();
    				int height = getHeight();
    				g2d.setPaint(new LinearGradientPaint(new Point(0,0), new Point(width,0), FRACTIONS, COLORS));
    				g.fillRect(0, 0, width, height);
    			}
    		};
     
    		frame.add(panel);
     
    		frame.setSize(600, 400);
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true); 
     
    	}
     
    }
    (Il y en a d'autres)

    Citation Envoyé par Bakamii Voir le message
    Autre approche : Existe t il un modèle comme le HSB qui comprends les couleurs qui n'apparaissent pas dans le spectre de la lumière ? ( marron(s) , beige, vert foncé , ...)
    Il y a des modèles pour tout, avec des couleurs visibles ou invisibles, qui existent dans un modèle mais pas dans un autre, orientés pour la vision humaine, la représentation des couleurs sur un écran, sur du papier, etc. RGB, HSV, HSL, LAB, XYZ, LUV, NCS, CYMK, LMS, YIQ... Il existe même plusieurs modèles RVB par exemple qui n'ont pas les mêmes couleurs (le sRGB a un blanc moins blanc que le modèle RGB d'Adobe par exemple). Il y a des modèles avec lesquels il est impossible d'envisager de déterminer un gradient par calcul (je ne citerais pas la marque célèbre qui commence par P), et qui ne peuvent être transcrits d'ailleurs ni en RGB, ni en CYMK, ni dans aucun autre modèle sans "déformation".

    Citation Envoyé par Bakamii Voir le message
    Problème annexe moins important :
    Ces couleurs ont pour but de servir de background en fonction d'une valeur, et faut que le texte soit visible
    Est-il possible de pâlir une couleur après coup ? J'ai pu voir qu'il existait une méthode brighter() et darker() pour la classe Color, mais comme leur nom l'indique elles modifient plus la
    Je suis pas sûr de ce qu'est exactement la pâleur. Un ajout de blanc ? Dans un système additif à priori ? Du coup dans un système tel que le blanc soit une composante, ou soit décomposable. Pour avoir fait des trucs qui pourraient peut-être ressembler à ce que tu cherches à faire, par composition avec un alpha blanc (donc dessiner une couleur, une image, un gradient peut importe, et dessiner par dessus un aplat blanc avec un alpha par exemple à 0.3, ou même un gradient de blanc à blanc RGB avec alpha de 0f à 1f. Pâlir une couleur pourrait donc être la composer avec du blanc, par composition alpha.
    Sinon, il me semble avoir vu un modèle basé sur un cône (à la HSL), mais avec un axe de blanc et non de luminosité, mais je ne me souviens plus du nom.

    Pour l'affichage de texte sur un fond, dégradé ou pas, je chercherais plutôt un algorithme fondé sur la notion de contraste et/ou de luminance perçue (perceptive luminance).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  7. #7
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    En fait cela va vraiment dépendre de son usage. S'il cherche a afficher un truc forme ou autre rempli de maniere automatique oui bien sur GradientPain (ou des classes plus spécialisée mais plus lourde comme LinearGradientPain) c'est ce qu'il faut utiliser. Par contre s'il s'agit juste d'extraire une couleur donnée (par exemple pour générer une heatmap) pas forcement, l’équation en HSB est assez simple et légère (pas besoin de stocker des points ou des objets couleur). D'un autre coté si on génère une heat map par exemple et qu'on a une palette réduite (ex: 256 couleurs) c'est pas plus con de mettre les couleurs générées en cache de manière a faire un poids mouche.

    PS : si tu veux accentuer la différence entre les couleurs du dégradé le plus simple est encore de reduire le nombre de couleur que ton algo peut generer : ici c'est du truecolor, on calcule un nombre "infini" de couleurs entre les deux extrêmes donc on a une transition douce pour l’œil qui trouve cela bien plus joli mais qui ne fait plus trop la différence (a moins de fortement zoomer sur l'image). Si tu utilises une palette plus réduite (genre que 256 ou moins de couleurs), le seuillage sera plus accentue et donc l’œil verra bien mieux la différence entre les couleurs du dégradé.

    Pour le reste outre ce qu'a indiqué Joel, ici nous avons utilisé une équation unique simple pour générer des couleurs entre les deux extrêmes. Si tu veux générer d'autres couleurs tu peux utiliser plusieurs équations ; c'est juste le principe mathématique qui s'applique derrière les gradients qui contiennent de multiples stops et couleurs intermédiaires ([c1 -c2] [c3 -c4] [c5 -c6]) : chaque sous-segment du gradient est une équation différente donc la palette générée sur ce sous-segment est différente de celle des autres. De plus chaque sous-segment peut avoir une longueur différente de celle de autres. Et si on prend c2 == c3 et c4 == c5 on aura une transition uniforme de c1 a c6 en passant par plusieurs variations et en générant des couleurs qu'il serait plus complexe d'obtenir via une seule et unique équation.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

Discussions similaires

  1. [XL-MAC 2011] Remplir une table en fonction d'une condition à l'aide d'une itération
    Par chou2best dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 07/11/2015, 16h29
  2. Réponses: 1
    Dernier message: 03/11/2010, 11h41
  3. Récupérer un élément à l'aide d'une partie de son ID
    Par hassine dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 13/05/2010, 11h57
  4. Réponses: 1
    Dernier message: 06/11/2009, 13h52
  5. une liste déroulante pour choisir une couleur ?
    Par Ekimasu dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 26/02/2009, 12h44

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