Color Thief PHP est une classe PHP qui vous permet d'extraire la couleur dominante ou une palette de couleurs à partir d'une image JPEG, GIF, ou PNG. Le projet est disponible sur GitHub, et sur Packagist. Vous pouvez également voir le code en fonctionnement sur cette page de démonstration.
La particularité de cette classe est qu'elle n'utilise pas une simple moyenne arithmétique pour déterminer la couleur dominante, contrairement à de nombreux scripts disponibles sur le web. En effet, cette méthode donne souvent des résultats plutôt aberrants, avec une couleur moche qui ne ressemble à rien de ce que l'on perçoit dans l'image. Ici, un algorithme avancé de quantification de couleurs est utilisé. Cet algorithme, nommé "Modified Mean Cut Quantizer", est comparable à celui utilisé par la compression JPEG. L'avantage est que les couleurs calculées sont le plus souvent visuellement très proches de celles présentes dans l'image d'origine, comme vous pouvez le voir sur l'exemple ci-dessous :
L'utilisation de la classe est très simple, surtout si vous utilisez Composer, mais peut être assez gourmande en ressources en fonction de la taille de l'image et de la qualité demandée. Je vous conseille donc de conserver le résultat en base de données plutôt que d’exécuter le script à chaque chargement de page. Pour plus d'informations, je vous invite à vous reporter à la documentation sur GitHub.
Les applications de cette classe ne sont limitées que par votre imagination : moteur de recherche par couleur, adaptation des couleurs de l'interface graphique en fonction de l'image affichée... Alex P. Gates a même développé un script PHP capable de modifier la couleur d'une lampe en fonction des couleurs d'une image, en utilisant Color Thief PHP et une lampe Philips Hue.
Enfin, si vous avez besoin de cet outil coté client en Javascript, sachez qu'il s'agit en fait d'un portage d'un script javascript. Vous pouvez donc utiliser le script Color Thief original réalisé par Lokesh Dhakar.
J'ai testé cette classe sur plusieurs séries d'images afin d'en extraire la couleur dominante et les resultats obtenus sont sensiblement différents de ceux renvoyés par les versions javascript et java. Les couleurs sont souvent plus sombres avec color-thief-php. Une idée de ce qui provoque ces differences?
Il existe en effet une différence de résultat plus ou moins importante sur certaines images. A priori je pense qu'elle est en partie ou totalement due à des erreurs de calcul propre au langage PHP (arrondis). Tant que la différence sur les premières couleurs de la palette n'est pas perceptible à l’œil, ce n'est pas grave à mon sens. Mais il est vrai que je ne me suis pas encore suffisamment penché sur le problème pour répondre avec certitude.
Je n'avais pas connaissance de la version Java, merci de me l'avoir appris. Du coup, il serait intéressant de voir s'il existe aussi une différence de résultat entre la version Java et Javascript.
J'ai ouvert une fiche sur GitHub à ce sujet. Si vous avez des liens vers des images où la différence est importante, pourriez-vous les poster sur cette fiche ?
EDIT : Si vous n'avez pas de compte GitHub, postez directement les liens ici en commentaire. Je les reporterai moi-même sur GitHub puis je les supprimerai ici. Merci
cette image par exemple retourne un vert sombre tandis que la version javascript retourne un jaune vif. D'après ce que j'ai pu observer en faisant plus de tests, les différences entre les versions découlent de légères variations dans la hiérarchisation de la palette.
Sur votre image j'obtiens le même résultat sur les deux versions : un vert sombre. Peut être avez vous testé avec l'original depuis votre PC ? Dans ce cas la compression faites par Facebook fausse le test.
Mais j'ai trouvé un exemple que j'ai mis sur la fiche Github.
Après une analyse plus poussée, comme indiqué sur la fiche Github, il s'avère qu'il n'y a en fait aucun bug. La version Javascript retourne simplement des résultats différents selon les dimensions d'affichage de l'image sur la page Web. En effet, les calculs y sont effectués à partir d'un Canvas de dimension définie par le CSS, et donc après un éventuel redimensionnement de l'image originale. Or ce redimensionnement implique une réduction du nombre de pixels affichés, et donc un mélange des couleurs adjacentes, ce qui change le résultat final.
La version PHP ne fait rien de tout cela, et calcule toujours les couleurs dominantes à partir de l'image initiale sans redimensionnement.
Bonjour,
Bravo pour cette classe.
J'ai deux questions :
- est ce que la classe peut renvoyer un chiffrage de dominance en proportion des couleurs de la palette ?
- est ce que l'installation de PHPunit est indispensable ?
Je te remercie beaucoup par avance pour ces réponses !
Bonjour,
En l'état, non il n'est pas possible d'obtenir ce chiffrage. Avec des modifications, peut-être, à voir, mais ce pourrait être difficile.
PHPUnit n'est pas du tout obligatoire pour utiliser ColorThiefPHP. Dans le fichier composer.json, c'est une dépendance de développement uniquement, pour tester la classe lors de son développement.
D'accord Kévin, merci pour cette réponse éclair ! Est ce que l'array renvoyé par la classe quand on demande une palette est ordonné en fonction de cette proportion, ou bien l'ordre est-il aléatoire ?
Je te remercie encore et te souhaite une bonne journée !
J'ai bien avancé sur la modification que j'évoquais, dès que j'ai un résultat viable je te le poste.
Et pour répondre à ma précédente question, oui, les couleurs sont bien ordonnées.
Réponse un peu moins éclair ce coup-ci (je ne suis pas très matinal ), mais oui c'est ordonné plus ou moins selon l'importance des couleurs dans l'image. L'algorithme est en réalité un peu plus complexe que ça, et ça reste un algorithme donc la perception humaine peut différer un peu du résultat évidemment.
Si tu fais la modification pour obtenir la quantification et que tu as un compte Github, tu peux faire une pull request, je la regarderai et je verrai si je la merge ou si je la laisse pour info pour d'autres utilisateurs