Convertir une image en échelle de gris en HTML/CSS
Existe-t-il un moyen simple d'afficher un bitmap couleur en échelle de gris avec juste HTML/CSS
?
il n'a pas besoin d'être Compatible IE (et j'imagine qu'il ne le sera pas) -- si ça marche en FF3 et/ou Sf3, c'est assez pour moi.
je sais que je peux le faire avec SVG
et la toile, mais cela semble beaucoup de travail en ce moment.
Est-il vraiment paresseux façon de le faire?
26 réponses
le Support des filtres CSS a atterri dans Webkit. donc nous avons maintenant une solution de navigation croisée.
img {
filter: gray; /* IE6-9 */
-webkit-filter: grayscale(1); /* Google Chrome, Safari 6+ & Opera 15+ */
filter: grayscale(1); /* Microsoft Edge and Firefox 35+ */
}
/* Disable grayscale on hover */
img:hover {
-webkit-filter: grayscale(0);
filter: none;
}
<img src="http://lorempixel.com/400/200/">
et Internet Explorer 10?
Vous pouvez utiliser un polyfill comme gris .
faisant suite à brillout.com'S réponse , et aussi Roman Nurik'S réponse , et en relaxant un peu l'exigence 'no SVG', vous pouvez Désaturer des images dans Firefox en utilisant seulement un seul fichier SVG et quelques CSS.
votre fichier SVG ressemblera à ceci:
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1"
baseProfile="full"
xmlns="http://www.w3.org/2000/svg">
<filter id="desaturate">
<feColorMatrix type="matrix" values="0.3333 0.3333 0.3333 0 0
0.3333 0.3333 0.3333 0 0
0.3333 0.3333 0.3333 0 0
0 0 0 1 0"/>
</filter>
</svg>
garde ça comme ressources.svg, il peut être réutilisé à partir de maintenant pour n'importe quelle image que vous voulez changer à l'échelle de gris.
dans votre CSS, vous faites référence au filtre en utilisant la propriété filter
spécifique à Firefox:
.target {
filter: url(resources.svg#desaturate);
}
Ajouter de la MS pour les propriétaires aussi, si vous en avez envie, appliquer cette classe à n'importe quelle image que vous souhaitez convertir en niveaux de gris (fonctionne dans Firefox - >3.5, IE8) .
modifier : Voici un joli blog qui décrit l'utilisation de la nouvelle CSS3 filter
propriété dans La réponse de SalmanPK en même temps que L'approche SVG décrite ici. En utilisant cette approche, vous finiriez avec quelque chose comme:
img.desaturate{
filter: gray; /* IE */
-webkit-filter: grayscale(1); /* Old WebKit */
-webkit-filter: grayscale(100%); /* New WebKit */
filter: url(resources.svg#desaturate); /* older Firefox */
filter: grayscale(100%); /* Current draft standard */
}
"1519280920 la" Poursuite de la prise en charge du navigateur info ici .
pour Firefox vous n'avez pas besoin de créer un filtre.fichier svg, vous pouvez utiliser données de schéma d'URI .
reprenant le code css de la première réponse donne:
filter: url("data:image/svg+xml;utf8,<svg%20xmlns='http://www.w3.org/2000/svg'><filter%20id='grayscale'><feColorMatrix%20type='matrix'%20values='0.3333%200.3333%200.3333%200%200%200.3333%200.3333%200.3333%200%200%200.3333%200.3333%200.3333%200%200%200%200%200%201%200'/></filter></svg>#grayscale"); /* Firefox 3.5+ */
filter: grayscale(100%); /* Current draft standard */
-webkit-filter: grayscale(100%); /* New WebKit */
-moz-filter: grayscale(100%);
-ms-filter: grayscale(100%);
-o-filter: grayscale(100%);
filter: gray; /* IE6+ */
prenez soin de remplacer la chaîne" utf-8 " par votre encodage de fichier.
cette méthode devrait être plus rapide que l'autre parce que le navigateur N'aura pas besoin de faire une deuxième requête HTTP.
mise à Jour: j'ai fait cela dans un dépôt GitHub, y compris JavaScript polyfill pour IE10 et IE11: https://github.com/karlhorky/gray
j'ai utilisé à l'origine la réponse de SalmanPK , mais j'ai ensuite créé la variation ci-dessous pour éliminer la requête HTTP supplémentaire requise pour le fichier SVG. La SVG en ligne fonctionne dans les versions 10 et plus de Firefox, et les versions inférieures à 10 ne représentent même plus 1% des le global marché du navigateur.
j'ai depuis tenu la solution à jour sur ce billet de blog , en ajoutant le support pour le retour à la couleur, C'est-à-dire le support 10/11 avec SVG, et une échelle de gris partielle dans la démo.
img.grayscale {
/* Firefox 10+, Firefox on Android */
filter: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='grayscale'><feColorMatrix type='matrix' values='0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0'/></filter></svg>#grayscale");
/* IE 6-9 */
filter: gray;
/* Chrome 19+, Safari 6+, Safari 6+ iOS */
-webkit-filter: grayscale(100%);
}
img.grayscale.disabled {
filter: none;
-webkit-filter: grayscale(0%);
}
si vous êtes en mesure d'utiliser JavaScript, alors ce script peut être ce que vous recherchez. Il fonctionne de la croix-navigateur et fonctionne bien pour moi jusqu'à présent. Vous ne pouvez pas l'utiliser avec des images chargées à partir d'un domaine différent.
a eu le même problème aujourd'hui. J'ai d'abord utilisé SalmanPK solution mais j'ai découvert que l'effet diffère entre FF et les autres navigateurs. C'est parce que la matrice de conversion fonctionne sur la légèreté seulement pas luminosité comme les filtres dans Chrome/IE . A ma grande surprise, J'ai découvert que la solution alternative et plus simple de SVG fonctionne aussi en FF4+ et produit de meilleurs résultats:
<svg xmlns="http://www.w3.org/2000/svg">
<filter id="desaturate">
<feColorMatrix type="saturate" values="0"/>
</filter>
</svg>
avec css:
img {
filter: url(filters.svg#desaturate); /* Firefox 3.5+ */
filter: gray; /* IE6-9 */
-webkit-filter: grayscale(1); /* Google Chrome & Safari 6+ */
}
One plus de mise en garde est que IE10 ne supporte pas "filtre: gris:" dans le mode conforme aux normes plus, a donc besoin de commutateur de mode de compatibilité dans les en-têtes pour travailler:
<meta http-equiv="X-UA-Compatible" content="IE=9" />
ne semble pas possible (encore), même avec les propriétés CSS3 ou propriétaire -webkit-
ou -moz-
CSS.
cependant, j'ai trouvé ce post de juin dernier qui a utilisé des filtres SVG sur HTML. Pas disponible dans n'importe quel navigateur courant (la démo laissait entendre une construction WebKit personnalisée), mais très impressionnant comme une preuve de concept.
pour les personnes qui posent des questions sur le soutien IE10 + ignoré dans d'autres réponses, consultez ce morceau de CSS:
img.grayscale:hover {
filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'1 0 0 0 0, 0 1 0 0 0, 0 0 1 0 0, 0 0 0 1 0\'/></filter></svg>#grayscale");
}
svg {
background:url(http://4.bp.blogspot.com/-IzPWLqY4gJ0/T01CPzNb1KI/AAAAAAAACgA/_8uyj68QhFE/s400/a2cf7051-5952-4b39-aca3-4481976cb242.jpg);
}
svg image:hover {
opacity: 0;
}
appliqué sur ce markup:
<!DOCTYPE HTML>
<html>
<head>
<title>Grayscaling in Internet Explorer 10+</title>
</head>
<body>
<p>IE10 with inline SVG</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svgroot" viewBox="0 0 400 377" width="400" height="377">
<defs>
<filter id="filtersPicture">
<feComposite result="inputTo_38" in="SourceGraphic" in2="SourceGraphic" operator="arithmetic" k1="0" k2="1" k3="0" k4="0" />
<feColorMatrix id="filter_38" type="saturate" values="0" data-filterid="38" />
</filter>
</defs>
<image filter="url("#filtersPicture")" x="0" y="0" width="400" height="377" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://4.bp.blogspot.com/-IzPWLqY4gJ0/T01CPzNb1KI/AAAAAAAACgA/_8uyj68QhFE/s1600/a2cf7051-5952-4b39-aca3-4481976cb242.jpg" />
</svg>
</body>
</html>
pour plus de démos, consultez la rubrique CSS3 Graphics section et ce vieux blog D'IE http://blogs.msdn.com/b/ie/archive/2011/10/14/svg-filter-effects-in-ie10.aspx
dans Internet Explorer utiliser la propriété filter.
dans webkit et Firefox il n'y a actuellement aucun moyen de desatuarte une image uniquement avec CSS. vous devrez donc utiliser canvas ou SVG pour une solution côté client.
mais je pense qu'utiliser SVG est plus élégant. consultez mon billet de blog pour la solution SVG qui fonctionne à la fois pour Firefox et webkit: http://webdev.brillout.com/2010/10/desaturate-image-without-javascript.html
et à proprement parler puisque SVG est HTML la solution est purement html+css: -)
la façon la plus simple de réaliser une échelle de gris avec CSS exclusivement est via la propriété filter
.
img {
-webkit-filter: grayscale(100%); /* Safari 6.0 - 9.0 */
filter: grayscale(100%);
}
la propriété n'est toujours pas entièrement supportée et nécessite toujours la propriété -webkit-filter
pour être supportée par tous les navigateurs.
une nouvelle façon de faire cela est disponible depuis un certain temps sur les navigateurs modernes.
background-blend-mode vous permet d'obtenir des effets intéressants, et l'un d'eux est la conversion en niveaux de gris
la valeur luminosité , fixée sur un fond blanc, le permet. (passez la souris pour le voir en gris)
.test {
width: 300px;
height: 200px;
background: url("http://placekitten.com/1000/750"), white;
background-size: cover;
}
.test:hover {
background-blend-mode: luminosity;
}
<div class="test"></div>
la luminosité est prise de l'image, la couleur est prise de l'arrière-plan. Depuis, il est toujours blanc, il n'y a pas de couleur.
, Mais il permet beaucoup plus.
vous pouvez animer le paramètre d'effet 3 couches. La première sera l'image, et le second sera un blanc-noir dégradé. Si vous appliquez un mode de mélange multiple sur ceci, vous obtiendrez un résultat blanc comme avant sur la partie blanche, mais l'image originale sur la partie noire (multiplier par blanc donne blanc, multiplier le noir n'a pas d'effet.)
sur la partie blanche du gradient, vous obtenez le même effet qu'avant. Sur la partie noire du gradient, vous mélangez l'image sur elle-même, et le résultat est l'image non modifiée.
maintenant, tout ce qui est nécessaire est de déplacer le gradient pour obtenir cet effet dynamique: (hover pour le voir en couleur)
div {
width: 600px;
height: 400px;
}
.test {
background: url("http://placekitten.com/1000/750"),
linear-gradient(0deg, white 33%, black 66%), url("http://placekitten.com/1000/750");
background-position: 0px 0px, 0px 0%, 0px 0px;
background-size: cover, 100% 300%, cover;
background-blend-mode: luminosity, multiply;
transition: all 2s;
}
.test:hover {
background-position: 0px 0px, 0px 66%, 0px 0px;
}
<div class="test"></div>
Peut-être que de cette façon, vous aider à
img {
-webkit-filter: grayscale(100%); /* Chrome, Safari, Opera */
filter: grayscale(100%);
}
il est en fait plus facile de le faire avec IE si je me souviens correctement en utilisant une propriété propriétaire CSS. Essayez ce FILTER: Gray
de http://www.ssi-developer.net/css/visual-filters.shtml
la méthode par Ax rend simplement l'image transparente et a un fond noir derrière elle. Je suis sûr que vous pourriez argumenter que c'est grayscale.
bien que vous ne vouliez pas utiliser Javascript, je pense que vous aurez à utiliser. Vous pouvez également utiliser un langage côté serveur pour le faire.
si vous êtes prêt à utiliser Javascript, alors vous pouvez utiliser une toile pour convertir l'image en niveaux de gris. Puisque Firefox et Safari prennent en charge <canvas>
, cela devrait fonctionner.
alors j'ai googlé "canvas grayscale", et le premier résultat a été http://www.permadi.com/tutorial/jsCanvasGrayscale/index.html qui semble fonctionner.
la prise en charge des filtres CSS natifs dans webkit a été ajoutée à partir de la version actuelle 19.0.1084.46
so-webkit-filter: grayscale (1) fonctionnera et ce qui est plus facile que L'approche SVG pour webkit...
voici un mixin pour moins qui vous permettra de choisir n'importe quelle opacité. Remplissez les variables vous-même pour CSS simple à différents pourcentages.
indice soigné ici , il utilise le type saturé pour la matrice de sorte que vous n'avez pas besoin de faire quelque chose de fantaisie pour changer le pourcentage.
.saturate(@value:0) {
@percent: percentage(@value);
filter: url("data:image/svg+xml;utf8,<svg%20xmlns='http://www.w3.org/2000/svg'><filter%20id='grayscale'><feColorMatrix%20type='saturate'%20values='@value'/></filter></svg>#grayscale"); /* Firefox 3.5+ */
filter: grayscale(@percent); /* Current draft standard */
-webkit-filter: grayscale(@percent); /* New WebKit */
-moz-filter: grayscale(@percent);
-ms-filter: grayscale(@percent);
-o-filter: grayscale(@percent);
}
puis l'utiliser:
img.desaturate {
transition: all 0.2s linear;
.saturate(0);
&:hover {
.saturate(1);
}
}
vous n'avez pas besoin d'utiliser autant de préfixes pour une utilisation complète, parce que si vous choisissez le préfixe pour l'ancien firefox, vous n'avez pas besoin d'utiliser le préfixe pour le nouveau firefox.
donc pour une utilisation complète, assez utiliser ce code:
img.grayscale {
filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#grayscale"); /* Firefox 10+, Firefox on Android */
filter: gray; /* IE6-9 */
-webkit-filter: grayscale(100%); /* Chrome 19+, Safari 6+, Safari 6+ iOS */
}
img.grayscale.disabled {
filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'1 0 0 0 0, 0 1 0 0 0, 0 0 1 0 0, 0 0 0 1 0\'/></filter></svg>#grayscale");
filter: none;
-webkit-filter: grayscale(0%);
}
img {
-webkit-filter: grayscale(100%); /* Safari 6.0 - 9.0 */
filter: grayscale(100%);
}
Basé sur robertc la réponse de :
pour obtenir bon conversion de l'image colorée à l'image en échelle de gris au lieu d'utiliser la matrice comme ceci:
0.3333 0.3333 0.3333 0 0
0.3333 0.3333 0.3333 0 0
0.3333 0.3333 0.3333 0 0
0 0 0 1 0
vous devez utiliser la matrice de conversion comme ceci:
0.299 0.299 0.299 0
0.587 0.587 0.587 0
0.112 0.112 0.112 0
0 0 0 1
cela devrait bien fonctionner pour tous les types d'images basées sur le modèle RGBA (rouge-vert-bleu-alpha).
pour plus d'informations si vous utilisez matrix I posté plus probable que la robertc d'un seul contrôle les liens suivants:
en complément des réponses des autres, il est possible de désaturer une image à mi-chemin sur FF sans matrix headaches:
<feColorMatrix type="saturate" values="$v" />
où $v
se situe entre 0
et 1
. C'est l'équivalent de filter:grayscale(50%);
.
Live exemple:
.desaturate {
filter: url("#desaturate");
-webkit-filter: grayscale(50%);
}
figcaption{
background: rgba(55, 55, 136, 1);
padding: 4px 98px 0 18px;
color: white;
display: inline-block;
border-top-left-radius: 8px;
border-top-right-radius: 100%;
font-family: "Helvetica";
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<filter id="desaturate">
<feColorMatrix type="saturate" values="0.4"/>
</filter>
</svg>
<figure>
<figcaption>Original</figcaption>
<img src="http://www.placecage.com/c/500/200"/>
</figure>
<figure>
<figcaption>Half grayed</figcaption>
<img class="desaturate" src="http://www.placecage.com/c/500/200"/>
</figure>
une solution terrible mais réalisable: rendre l'image à l'aide d'un objet Flash, qui vous donne alors toutes les transformations possibles en Flash.
si vos utilisateurs utilisent des navigateurs de bord de saignée et si Firefox 3.5 et Safari 4 le support (Je ne sais pas que l'un ou l'autre do/will), Vous pouvez ajuster le CSS profil de couleur attribut de l'image, le réglage à une échelle de gris profil ICC URL. Mais cela fait beaucoup de si!
be une alternative pour les navigateurs plus anciens pourrait être d'utiliser un masque produit par des pseudo-éléments ou des étiquettes en ligne.
Absolute positionning hover un img (ou une zone de texte qui ne nécessite pas de clic ni de sélection) peut imiter de près les effets d'échelle de couleur , via rgba () ou translucide png .
il ne donnera pas une seule échelle de couleur, mais va nuances de couleur hors de portée.
essai sur stylo de code avec 10 couleurs différentes via un pseudo-élément, le dernier est gris . http://codepen.io/gcyrillus/pen/nqpDd (recharger pour passer à une autre image)
vous pouvez utiliser une des fonctions de jFunc-utiliser la fonction " jfun_canvasfiltergrayscale" http://jfunc.com/jFunc-functions.aspx
essayez ce plugin jquery. Bien que ce ne soit pas une solution HTML et CSS pure, c'est un moyen paresseux d'atteindre ce que vous voulez. Vous pouvez personnaliser votre échelle de gris pour mieux répondre à votre usage. Utilisez-le comme suit:
$("#myImageID").tancolor();
il y a une démo interactive 151950920". Vous pouvez jouer avec elle.
consultez la documentation sur l'utilisation, c'est assez simple. docs
si vous, ou quelqu'un d'autre faisant face à un problème similaire dans le futur sont ouverts à PHP. (Je sais que vous avez dit HTML / CSS, mais peut-être que vous utilisez déjà PHP dans le backend) Voici une solution PHP:
Je l'ai obtenu de la bibliothèque PHP GD et j'ai ajouté une variable pour automatiser le processus...
<?php
$img = @imagecreatefromgif("php.gif");
if ($img) $img_height = imagesy($img);
if ($img) $img_width = imagesx($img);
// Create image instances
$dest = imagecreatefromgif('php.gif');
$src = imagecreatefromgif('php.gif');
// Copy and merge - Gray = 20%
imagecopymergegray($dest, $src, 0, 0, 0, 0, $img_width, $img_height, 20);
// Output and free from memory
header('Content-Type: image/gif');
imagegif($dest);
imagedestroy($dest);
imagedestroy($src);
?>
pour l'échelle de gris en pourcentage dans Firefox, utilisez filtre saturé à la place: (rechercher 'saturate')
filter: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='saturate'><feColorMatrix in='SourceGraphic' type='saturate' values='0.2' /></filter></svg>#saturate"