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

JavaScript Discussion :

Changer la couleur d'un png uniquement en JS "pur"


Sujet :

JavaScript

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre extrêmement actif Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 532
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 532
    Par défaut Changer la couleur d'un png uniquement en JS "pur"
    Je ne connais rien à ce type de problème, mais en voici les données:

    j'ai un png, genre une étoile (ou un carré si vous voulez*) utilisant un fond invisible, il sera de couleur unie, et je veux pouvoir le "placer" juste une fois sur page html, mais en en changeant sa couleur suivant un contexte simple genre une valeur en 1 et 5 => rouge; (6,10) => orange, (10,15) => bleu; etc...

    J'ai vu qu'il y avait la possibilité d'appliquer un filtre en JS, mais je ne comprends rien aux tenants et aux aboutissants, je n'ai aucune culture graphique qui puisse m'aider à lire et à comprendre sur le sujet.

    1 : quelle couleur doit avoir l'image de base pour que le "filtrage" puisse s'appliquer directement, en noir ou en blanc?, ou autre chose ?
    2 : j'imagine et j’espère que le "filtrage" ne s'applique pas sur la partie transparente ?
    3 : comment procéder le plus simplement possible - [ est-ce qu'un bout de code d'une dizaine de lignes max peut résoudre ce problème ] ?


    * en réalité c'est une forme de tache (ne me demandez pas pourquoi)

  2. #2
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant perpétuel
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Billets dans le blog
    125
    Par défaut


    Je sais que la libpng existe, mais je ne l'ai jamais utilisée : https://libpng.sourceforge.io/index.html

    Blog

    Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
    (Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)

  3. #3
    Membre extrêmement actif Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 532
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 532
    Par défaut
    ah, merci je vais regarder, mais je crois "connaître" cette librairie, de mémoire c'est une librairie en C, servant à "faire" du png, si on réalise un logiciel de dessin...?

  4. #4
    Membre émérite
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 340
    Par défaut
    Bonjour,
    Citation Envoyé par psychadelic Voir le message
    1 : quelle couleur doit avoir l'image de base pour que le "filtrage" puisse s'appliquer directement, en noir ou en blanc?, ou autre chose ?
    En noir ou blanc, ça risque de rester en niveaux de gris, à moins de pouvoir réaliser une vraie transformation de la couleur, ce ne serait plus un simple filtre (Edit : en fait, je veux dire que pour passer du noir/blanc à une vraie couleur, il faudrait soit faire un remplacement de couleur soit ajouter comme un calque coloré translucide, concrètement ou par le biais d'une opération qui s'y apparente).
    Je partirais plutôt sur une couleur pleinement saturée.

    Citation Envoyé par psychadelic Voir le message
    2 : j'imagine et j’espère que le "filtrage" ne s'applique pas sur la partie transparente ?
    Ce qui est transparent devrait le rester.

    Citation Envoyé par psychadelic Voir le message
    3 : comment procéder le plus simplement possible - [ est-ce qu'un bout de code d'une dizaine de lignes max peut résoudre ce problème ] ?
    "uniquement en JS "pur" " : sous-entendu "pas de PHP" ou "pas de CSS" également ?
    Parce qu'en CSS, hue-rotate(...deg) semble bien convenir.
    Après essai avec une image rouge, je vois qu'il faudrait ajuster également la saturation et/ou la luminosité, car je constate beaucoup de perte en saturation/luminosité (j'ai fait une petite recherche et apparemment, il y aurait effectivement un souci à ce niveau).
    Une solution serait donc de préparer des classes CSS pour les différentes couleurs en tâtonnant pour ajuster la saturation/luminosité, et d'appliquer la classe souhaitée à l'utilisation.
    Idéalement, il faudrait trouver un code qui permet de trouver les réglages exacts à faire depuis une couleur de base vers une couleur d'arrivée...

    Sinon de rouge vers jaune par exemple, la rotation est de 60°.
    Il faut considérer un nuancier classique : de gauche à droite on va de rouge à rouge en passant par orange, jaune, vert, bleu, violet, rose...

  5. #5
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Citation Envoyé par Loralina Voir le message
    ...en CSS, hue-rotate(...deg) semble bien convenir...
    CSS - hue-rotate()

  6. #6
    Membre extrêmement actif Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 532
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 532
    Par défaut
    bon, j'ai pas trop regardé du coté CSS, mais j'ai fini par trouver un script js "pur" qui devrait le faire..

    je l'ai un peu adapté pour mon idée ( j'ai laissé les commentaires en anglais)

    je me suis fait rapidos une image png de Largeur=300px, Hauteur=200px en noir sur du transparent. ( j'ai pas testé pour l'opacité)

    Le truc c'est que ça produit une nouvelle image sur canvas, donc on double, ou triple, ou quadruple, x fois la mémoire (pour l'image), si on veut plusieurs images de couleurs différentes.

    et mon image de base fait dans les 100k et surtout 16000x380 ( je sais j'ai pas dit au départ, et c'est une image qui sert de fond défilant [encore une autre histoire] )

    et comme vous allez le voir ce code exécute une boucle sur chaque pixel pour en changer la couleur, donc pas glop.
    Code HTML : 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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    <!DOCTYPE html>
    <html lang="fr">
     
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Changer les couleurs d'un PNG (Noir + transparent) </title>
      <style>
        * {
          margin  : 0;
          padding : 0;
          border  : 0;
          box-sizing: border-box;
        }
        body {
          background-color : #c5ba23;  /* mo edi à un color picker, et je l'utilise        */
          color            : #a80c14;  /* pour choisir une couleur moche de remplacement   */
        }
        #origImg {
          display : block;
          width   : 300px;
          height  : 200px;
          margin  : 20px;
        }
        #myCanvas {
          margin : 20px;
          width  : 600px;  /* pour tester un effet de déformation */
          height : 200px;
        }
      </style>
    </head>
    <body>
     
      <!--
         <img id="origImg" src="test_1.png">  image en L=300px, H=200px
      -->
     
      <canvas id="myCanvas" ></canvas> 
     
      <script>
     
        var imageObj = new Image();
     
        imageObj.onload = function()
        {
          alterImage(this, '#a80c14', 300, 200)
        }
     
     
        imageObj.src = "test_1.png";  // url relative
        // imageObj.src = document.getElementById( "origImg" ).src;
     
     
        function alterImage(imageObj, newColor, wImg, hImg)
        {
          let
            RGB    = hex2rgb(newColor),
            canvas = document.getElementById("myCanvas"),
            ctx    = canvas.getContext("2d");
     
          //  console.log("a", canvas.width, canvas.height )
          //  console.log("b", canvas.scrollWidth, canvas.scrollHeight )
     
          canvas.setAttribute('width', wImg);
          canvas.setAttribute('height', hImg);
     
          ctx.drawImage(imageObj, 0, 0);
     
          //let id = ctx.getImageData(0, 0, canvas.width, canvas.height);
          let id = ctx.getImageData(0, 0, wImg, hImg);
     
          // Iterate over data.  Data is RGBA matrix so go by +=4 to get to next pixel data.
          for (let i=0, iMax=id.data.length ; i < iMax; i +=4)
          {
              // Check if RGB == 0 (black)
            if ( id.data[i] + id.data[i+1] + id.data[i+2] == 0 )
            {
              id.data[i]   = RGB.r;      
              id.data[i+1] = RGB.g;
              id.data[i+2] = RGB.b;
              // id.data[i+3]  reste inchangé, correspond au canal aplha ( opacité ) ?? ( à vérifier)
            }
          }
     
          // redraw your altered data on the canvas.
          ctx.putImageData(id, 0, 0);
        }
     
        function hex2rgb(hexStr)
        {
          // note: hexStr should be #rrggbb
          let
            hex = parseInt(hexStr.substring(1), 16),
            r   = (hex & 0xff0000) >> 16,
            g   = (hex & 0x00ff00) >> 8,
            b   =  hex & 0x0000ff;
          return {r, g, b};
        }
     
      </script>
    </body>
    </html>

    bref je sais pas trop si c'est le plus mieux génial, j'ai un gros doute

  7. #7
    Membre extrêmement actif Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 532
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 532
    Par défaut
    je viens d'essayer le hue-rotate, avec mon image en Noir, puis en blanc
    Code css : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        #origImg {
          display : block;
          width   : 300px;
          height  : 200px;
          margin  : 20px;
     
          filter: hue-rotate(60deg);
        }

    mais ça fait rien du tout.
    faut partir d'une couleur unie pour ce truc puisse fonctionner, c'est un peu compliqué, et effectivement va valoir tâtonner, (j'aime pas du tout du tout tâtonner, ça me rends malade quand les trucs ne sont pas rationnels)

  8. #8
    Membre émérite
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 340
    Par défaut
    Pour canvas, juste ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ctx.fillStyle=newColor;
    ctx.fillRect(0,0,canvas.width,canvas.height);
    ctx.globalCompositeOperation="destination-in";
    ctx.drawImage(imageObj,0,0);
    Après on peut envoyer ça sur une balise image avec toDataURL et supprimer le canvas.

    Pour hue-rotate, oui c'est ce que je dis, il faut partir d'une couleur, rouge étant à 0°, mais il faut gérer ensuite le problème de saturation/luminosité.

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

Discussions similaires

  1. Changer la couleur de certains caractères uniquement
    Par guillaume_31400 dans le forum Excel
    Réponses: 5
    Dernier message: 14/11/2017, 18h35
  2. [GD] Changer la couleur d'un fichier PNG
    Par The Transporter dans le forum Bibliothèques et frameworks
    Réponses: 3
    Dernier message: 09/01/2009, 14h43
  3. Réponses: 0
    Dernier message: 11/10/2008, 14h31
  4. Changer la couleur d'un PNG
    Par utwor dans le forum Windows Forms
    Réponses: 6
    Dernier message: 08/02/2008, 17h01
  5. Changer les couleurs de la palette avec du RGB
    Par le mage tophinus dans le forum x86 16-bits
    Réponses: 11
    Dernier message: 13/01/2003, 08h55

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