Augmenter la luminosité d'une image

Résolu
Bonjour,

Alors voilà, désormais je cherche à augmenter la luminosité d'une image en pour-cent.
Ma première idée est de travailler en ARGB et augmenter la luminance mais je ne sais pas si c'est comme ça que l'on doit faire.

Cordialement.

10 réponses

Résumé de la discussion

La question porte sur comment augmenter la luminosité d'une image en pourcentage et sur la meilleure approche entre modification des valeurs ARGB et ajustement direct de la luminance via des modèles colorimétriques. Des échanges suggèrent d'utiliser le format HSV/HSB plutôt que RGB pour agir sur la luminosité, en modifiant la valeur et éventuellement la saturation, avec des conversions via Color.RGBtoHSB et Color.HSBtoRGB. En pratique, il faut appliquer l’opération à tous les pixels, respecter les limites (valeurs entre 0 et 1) et tenir compte de l’alpha, afin d’éviter une recoloration non désirée tout en préservant la teinte.

Bobot (l’IA à votre service)
  1. Modérateur
    Au lieu de travailler en RGB, tu devrais utiliser le format HSB (hue, saturation, brightness)

    int rgb = img.getRGB(x, y);
    Color clr = new Color(rgb);
    float[] hsb = Color.RGBtoHSB(clr.getRed(), clr.getGreen(), clr.getBlue(), null);
    
    //TODO : modification de hsb pour traitement
    
    int rgb2 = Color.HSBtoRGB(hsb[0],hsb[1],hsb[2]);
    img.setRGB(x, y, rgb2);
    1. Question : après je devrai sûrement programmer quelque chose pour augmenter ou diminuer la saturation, je travaillerai aussi en HSB et je changerai juste le S ou c'est plus compliqué que ça??
      1. Modérateur
        Normalement modifier la saturation devrait suffire. Après peut-être que ça ne fera pas exactement ce que tu veux et qu'il faudra aussi jouer sur le contraste, mais dans tout les cas tu ne touchera pas à la teinte.

        La seule vraie complication que tu pourrais avoir c'est avec la transparence, car je ne sais pas trop comment ça se comporte lors du passage de RGB à HSB, puisque l'alpha n'est pas passé en paramètre de la conversion... Mais au pire il suffira de le récupérer avant, de faire la conversion, puis de le remettre après.
      2. Modérateur
        En tenant compte de la transparence :

        int rgb = img.getRGB(x, y);
        Color clr = new Color(rgb,true);
        int alpha = clr.getAlpha();
        float[] hsb = Color.RGBtoHSB(clr.getRed(), clr.getGreen(), clr.getBlue(), null);
        
        //TODO : modification de hsb pour traitement
        
        rgb = Color.HSBtoRGB(hsb[0],hsb[1],hsb[2]);
        clr = new Color(rgb);
        clr = new Color(clr.getRed(), clr.getGreen(), clr.getBlue(), alpha);
        img.setRGB(x, y, clr.getRGB());
      3. C'est au brightness qu'on touche ?
      4. Modérateur
        Oui, je crois, il faudrait tester pour s'en assurer...
      5. On peut charger une image en HSB directement ?
    2. je cherche le méme probléme
      1. Modérateur
        Et bien lis, la réponse sera la même !
    3. hsb[0] c'est hue, hsb[1] c'est saturation et hsb[2] c'est Brightness c'est ça ?
      Et votre code je dois tout mettre dans deux boucles imbriquées c'est ça ?
      1. Modérateur
        Oui c'est ça, mais normalement la teinte (hue : qui est entre 0 et 360) tu n'as pas à y toucher.
    4. Une question : j'essaie de faire la fonction mais qui s'appelle lumisat, c'est-à-dire qu'avec une seule fonction elle va faire deux choses. Possible ? Style, selon le paramètre elle change soit la luminosité, soit la saturation.
      1. Modérateur
        Tu peux changer hsb[1] et hsb[2] en même temps (genre augmenter le premier et diminuer le deuxième) ça ne posera aucune problème !
    5. Mais hsb[0] je n'ai même pas besoin de lui attribuer quoi que ce soit non ?
      1. Modérateur
        Regarde mon code ! hsb est issu de la conversion RGBtoHSB à partir du pixel existant, donc hsb[0] a déjà une valeur qui correspond à un angle entre 0 et 360 degrés du cercle chromatique et correspondant aux valeurs RGB déjà présente initialement dans l'image. Si tu modifies hsb[0] tu vas changer la couleur alors que toi tu veux juste agir sur les deux autres.
    6. Avec la luminosité j'ai un problème, quand je tape une valeur inférieur à 100 l'image est noire.
      1. Peut être que j'ai compris, si je mets entier aussi...
      2. Modérateur
        d'autant que j'ai rappelé tout à l'heure que la valeur était entre 0 et 1 !!!
    7. Voilà ma fonction, il y a un soucis pour la luminosité inférieure à 100%
      Alors désolé pour les commentaires que vous m'avez fait souvent avec les paramètres mais je ne suis pas habitué à mettre énormément de paramètres.

      public static void lumisat(String choix, int pourcent)
      {
      // Cette fonction est chargée de changer soit la luminosité soit la saturation.
      int pix=0,h=0,w=0,x=0,y=0;
      double lumi=0,sat=0;
      if ((pourcent == 100) || (pourcent <=0)) {
      // Si la valeur est 100%, cela ne sert à rien d'appliquer la fonction.
      System.out.println("Erreur : le pourcentage est soit négatif soit egal a 0.");
      return;
      }
      else {
      lumi = 1;
      sat = 1;
      if(choix.equals("luminosite")) {
      lumi = pourcent/100;
      }
      else {
      if(choix.equals("saturation")) {
      sat = pourcent/100;
      }
      }
      }
      BufferedImage img=null;
      try {
      img = ImageIO.read(new File("./image.bmp"));
      }
      catch (Exception e) {}
      w = img.getWidth();
      h = img.getHeight();
      for(y=0;y<h;y++) {
      for(x=0;x<w;x++) {
      int rgb = img.getRGB(x, y);
      Color clr = new Color(rgb,true);
      int alpha = clr.getAlpha();
      float[] hsb = Color.RGBtoHSB(clr.getRed(), clr.getGreen(), clr.getBlue(), null);
      hsb[1] = (float) (hsb[1]*sat);
      hsb[2] = (float) (hsb[2]*lumi);
      rgb = Color.HSBtoRGB(hsb[0],hsb[1],hsb[2]);
      clr = new Color(rgb);
      clr = new Color(clr.getRed(), clr.getGreen(), clr.getBlue(), alpha);
      img.setRGB(x, y, clr.getRGB());
      }
      }
      try {
      ImageIO.write(img,"bmp",new File("lumisat.bmp"));
      }
      catch (Exception e) {};
      // Et on crée l'image.
      }
      1. Modérateur
        Si tu fais pourcent/100 alors que pourcent est un entier inférieur à 100 alors nécessairement ça fera 0 !
        HSB t'impose d'utiliser des float, alors pourquoi mettre des double en plein milieu ?
        De plus ton code ne te permet que d'augmenter les valeurs pas de les diminuer.

        Il faudrait plutôt utiliser au maximum les float en passant en paramètre 1 (=100% pas de changement), entre 0 et 1 (diminution), supérieur à 1 (augmentation), ça t'évitera la manipulation toute moche de String.

        public static void lumisat(float lumi, float sat) 
        // ...
        hsb[1] *= lumi;
        hsb[2] *= sat;
    8. Merci beaucoup, c'est résolu pour moi.
      Une fois encore vous m'avez sauvé la vie.
      1. Qu'est alpha s'il vous plaît ?
        1. Modérateur
          La transparence, c'est le A de ARGB