Je travaille sur une interface utilisateur pour une application, et j'essaie d'utiliser des icônes en niveaux de gris et d'autoriser l'utilisateur à changer le thème en une couleur de son choix. Pour ce faire, j'essaie simplement d'appliquer un ColorFilter pour superposer une couleur au-dessus du dessinable. J'ai essayé d'utiliser PorterDuff.Mode.MULTIPLY, et cela fonctionne presque exactement comme j'ai besoin, sauf que les blancs se superposent également à la couleur. Ce que je recherche idéalement, c'est quelque chose comme le mode de fusion "Couleur" dans Photoshop, où le graphique conserve sa transparence et sa luminosité, et ne modifie que la couleur de l'image. Par exemple:
devient
Après quelques recherches, il semble que la classe ColorMatrixColorFilter puisse faire ce dont j'ai besoin, mais je n'arrive pas à trouver de ressources indiquant comment la matrice est utilisée. C'est une matrice 4x5, mais ce que j'ai besoin de savoir, c'est comment je conçois la matrice. Des idées?
EDIT: Alors d'accord, ce que j'ai trouvé jusqu'à présent à ce sujet est le suivant:
1 0 0 0 0 //red
0 1 0 0 0 //green
0 0 1 0 0 //blue
0 0 0 1 0 //alpha
Où cette matrice est la matrice d'identité (lorsqu'elle est appliquée, n'apporte aucun changement), et les nombres vont de 0 à 1 (flottants). Cette matrice sera multipliée avec chaque pixel pour la convertir à la nouvelle couleur. C'est donc là que ça commence à devenir flou pour moi. Je pense donc que chaque pixel serait un vecteur 1 x 4 contenant les valeurs argb (par exemple 0.2, 0.5, 0.8, 1
) qui seraient parsemées de la matrice de transformation. Donc, pour doubler l'intensité du rouge d'une image, vous utiliseriez une matrice telle que:
2 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
ce qui vous donnerait un vecteur (couleur) de 0.4, 0.5, 0.8, 1
. D'après des tests limités, cela semble être le cas et fonctionne correctement, mais je me retrouve toujours avec le même problème (c'est-à-dire que les blancs gagnent en coloration). Une lecture plus approfondie me dit que c'est parce qu'il effectue la conversion sur les valeurs RVB, tandis que pour le décalage de teinte, les valeurs doivent d'abord être converties en valeurs HSL. Je pourrais donc peut-être écrire une classe qui lirait l'image et convertirait les couleurs, et redessinerait l'image avec les nouvelles couleurs. Cela crée UN AUTRE problème avec StateListDrawables, car je ne suis pas sûr de la manière dont je ferais pour obtenir chacun de ces éléments dans le code et de les modifier tous, ni de la lenteur du processus. : /
Hmm, d'accord, alors je suppose qu'une autre question que j'aurais est de savoir si une matrice peut être utilisée pour convertir RVB en un autre espace colorimétrique avec des informations de luminosité, telles que L a b ou HSL? Si tel est le cas, je pourrais simplement multiplier la matrice pour cette conversion, puis effectuer l'ajustement de la teinte sur CETTE matrice, puis appliquer cette matrice en tant que ColorFilter.
la source
Réponses:
C'est ce que j'utilise pour mon jeu. Il s'agit de la compilation de diverses parties trouvées sur divers articles sur des sites Web. Les crédits vont à l'auteur original à partir des liens @see. Notez que beaucoup plus peut être fait avec les matrices de couleurs. Y compris l'inversion, etc ...
Pour compléter cela, je devrais ajouter un exemple:
la source
mat
de votre code comporte 5 lignes? Ne devrait-il pas y avoir 4 lignes seulement (une pour chaque RGBA)?ColorMatrix
, je le reprends. La dernière ligne demat
n'est jamais utilisée du tout. LeColorMatrix
constructeur ne prend que les 4 premières lignes (copie les 20 premiers flottants de la matrice source donnée).voici le code complet si vous souhaitez régler la luminosité, le contraste, la saturation et la teinte. Prendre plaisir! Merci beaucoup à @RichardLalancette
la source
adjustContrast
méthode: (1) l'expressionvalue<<0
semble redondante, car elle serait toujours égale à (juste)value
. (2) Toutvalue
comme un entier, ne serait-il pasvalue % 1
toujours égal à 0?Pour toute personne intéressée par l'utilisation du ColorMatrixColorFilter. L'échantillon que j'ai utilisé ici a converti chaque pixel en rouge lorsque je dessine le bitmap sur la toile.
Le commentaire dans la classe provient de: http://developer.android.com/reference/android/graphics/ColorMatrix.html cela vous donne des informations sur la façon dont cela fonctionne
la source
La classe ci-dessous est une amélioration par rapport aux réponses qui ont déjà été publiées. Cela facilite la lecture et la création d'un fichier à
ColorFilter
partir d'un fichierBitmap
.Exemple d'utilisation:
la source
Il n'y a pas de relation linéaire entre Hue et RGB. La teinte est définie par morceaux en morceaux de 60 ° ( http://en.wikipedia.org/wiki/HSL_color_space#General_approach ), et il n'y a donc pas une simple conversion matricielle entre HSV et RVB. Pour modifier la teinte d'une image, vous pouvez utiliser la méthode suivante:
la source
Je pense que cette méthode vous donnera ce que vous voulez:
http://android.okhelp.cz/hue-color-colored-filter-bitmap-image-android-example/
la source
Comme le reste des réponses, j'ai utilisé une matrice de couleurs pour implémenter ce comportement, mais vous pouvez passer une ressource de couleur Android classique. La matrice mappe la couleur dans une plage comprise entre la valeur de l'image et le blanc.
la source
J'ai fait un petit testeur ColorMatrixFilter, basé sur l'extrait suivant:
Vous pouvez le voir ici: https://play.google.com/store/apps/details?id=org.vaelostudio.colormatrixtester
la source
Même si de nombreux effets utiles peuvent être obtenus en utilisant le,
ColorMatrix
j'envisagerais personnellement d'utiliser unColorMap[]
avecImageAttributes
. En faisant cela, nous pouvons définir quelles couleurs doivent être remplacées par quelles couleurs.la source
ColorMap
? Je pense qu'il n'y a pas de classe de ce type disponible dans les bibliothèques standard java / android.La façon dont je l'ai résolu est de commencer par une image en échelle de gris.
original ---> grayImage
vous pouvez le faire facilement dans Photoshop, ou si vous devez le faire dans le code, vous pouvez utiliser la méthode suivante.
Une fois que vous avez votre image GrayScale, vous pouvez utiliser le mode PorterDuff OVERLAY pour ajouter la couleur souhaitée.
Le résultat ci-dessus est le suivant: randomColorGif
la source