web-dev-qa-db-fra.com

Bordure CSS sur image PNG avec des parties transparentes

Im essayant d'ajouter une bordure sur une image PNG que j'ai (exemple inclus). Le fait est que lorsque j'ajoute la bordure actuellement, elle l'ajoute sur une forme de boîte autour de toute l'image et non sur le vecteur exact (ce qui signifie qu'il inclut les parties transparentes de l'image).

Existe-t-il un moyen possible de configurer la configuration de la bordure sans tenir compte de la zone transparente? (Même si ce n'est pas en CSS ... Peut-être HTML5/JS?)

Example image

enter image description here

28
nimi

À partir de maintenant ( 31 janvier 2015) il existe un moyen de le faire sans utiliser de canvas, avec du CSS pur, et avec seulement 2 lignes de code.

L'astuce consiste à utiliser les css filter et -webkit-filter propriétés pour dessiner deux ombres portées sans flou, une pour l'axe positif et une pour le négatif, qui entoureront l'image, ce qui fournira ( avec un peu de chance) l'effet désiré.

Remarque : les filtres CSS ne sont pas du tout pris en charge dans IE (espérons que Spartan fera mieux), voici un - ( table de compatibilité .

Ce premier extrait ( ( violon ) appliquera la bordure la plus simple possible .

img {
  -webkit-filter: drop-shadow(1px 1px 0 black)
                  drop-shadow(-1px -1px 0 black);
  filter: drop-shadow(1px 1px 0 black) 
          drop-shadow(-1px -1px 0 black);
}

body {
  background-color: lightcoral;
}
<img src="http://i.imgur.com/GZoXRjS.png" width="250">

Comme vous pouvez le voir, certaines images (comme ce rendu Baymax génial ) ont besoin d'un peu plus de réglages, vous pouvez voir à droite la bordure est un peu plus petite que la gauche.

Dans cet esprit, voici l'extrait de bordure perfectionné ( violon ) avec juste une très petite valeur Tweak.

img {
  -webkit-filter: drop-shadow(2px 1px 0 black)
                  drop-shadow(-1px -1px 0 black);
  filter: drop-shadow(2px 1px 0 black) 
          drop-shadow(-1px -1px 0 black);
}

body {
  background-color: Khaki;
}
<img src="http://i.imgur.com/GZoXRjS.png" width="250">

Cela devrait couvrir assez bien les bordures, mais nous pouvons toujours nous amuser davantage, regardez cet extrait de légèreté impressionnant ( violon ).

img{
    -webkit-filter: drop-shadow(1px 1px 0 black) 
                    drop-shadow(-1px -1px 0 white);
    filter:drop-shadow(1px 1px 0 black) 
           drop-shadow(-1px -1px 0 white);
}

body{
    background-color:lightblue;
}
<img src="http://i.imgur.com/GZoXRjS.png" width="250">

J'espère que cela aidera quiconque à s'interroger sur la possibilité d'une bordure enveloppante pour les images semi-transparentes!

48
undefined

J'ai étendu un peu la réponse du haut, ce qui est mieux pour mon usage.

-webkit-filter: drop-shadow(2px 2px 0 white)
                drop-shadow(-2px 2px 0 white)
                drop-shadow(2px -2px 0 white)
                drop-shadow(-2px -2px 0 white);

filter: drop-shadow(2px 2px 0 white)
        drop-shadow(-2px 2px 0 white)
        drop-shadow(2px -2px 0 white)
        drop-shadow(-2px -2px 0 white);

Si quelqu'un en a encore besoin.

15
COOLGAMETUBE

Trois ans sur la question est toujours valable. Comme je voulais (à l'origine) un trait plus épais, j'ai fini par utiliser 8 ombres portées (une pour chaque point de la boussole) pour le rendre juste.

Curieusement, l'utilisation de 8 ombres avec un décalage x et y de 1px donne un contour qui semble large d'environ 5px, mais l'introduction de transparence dans la couleur semble aider à revenir à un résultat légèrement doux mais assez attrayant:

img {
    --stroke-pos: 1px;
    --stroke-neg: -1px;
    --stroke-color: rgba(0, 255, 0, 0.2);
    filter: drop-shadow(var(--stroke-pos) 0 0 var(--stroke-color)) 
      drop-shadow(var(--stroke-neg) 0 var(--stroke-color))
      drop-shadow(0 var(--stroke-pos) 0 var(--stroke-color))
      drop-shadow(0 var(--stroke-neg) 0 var(--stroke-color))
      drop-shadow(var(--stroke-pos) var(--stroke-pos) 0 var(--stroke-color)) 
      drop-shadow(var(--stroke-pos) var(--stroke-neg) 0 var(--stroke-color))
      drop-shadow(var(--stroke-neg) var(--stroke-pos) 0 var(--stroke-color))
      drop-shadow(var(--stroke-neg) var(--stroke-neg) 0 var(--stroke-color));   
}

Comme vous pouvez le voir, les variables CSS sont utiles ici (ou Sass/Less).

0
MSC

Je suis tombé sur le besoin de le faire moi-même - j'ai trouvé ce hack. Une série d'images superposées derrière mon original qui étaient légèrement en décalage les unes avec les autres. Le contexte ctx3 est une copie de l'image originale et cela reproduirait plusieurs fois une silhouette blanche derrière l'original.

      ctx3.shadowColor = "rgba(255,255,255,1)";
      ctx3.globalCompositeOperation = 'source-over';
      ctx3.shadowOffsetX = 2;
      ctx3.shadowOffsetY = 2;
      ctx3.shadowBlur = 0;
      ctx3.drawImage(YourImageSource,0,0);
      ctx3.shadowOffsetX = -2;
      ctx3.shadowOffsetY = -2;
      ctx3.shadowBlur = 0;
      ctx3.drawImage(YourImageSource,0,0);
      ctx3.shadowOffsetX = -2;
      ctx3.shadowOffsetY = 2;
      ctx3.shadowBlur = 0;
      ctx3.drawImage(YourImageSource,0,0);
      ctx3.shadowOffsetX = 2;
      ctx3.shadowOffsetY = -2;
      ctx3.shadowBlur = 0;
      ctx3.drawImage(YourImageSource,0,0);
      ctx3.shadowOffsetX = 0;
      ctx3.shadowOffsetY = 2;
      ctx3.shadowBlur = 0;
      ctx3.drawImage(YourImageSource,0,0);
      ctx3.shadowOffsetX = 0;
      ctx3.shadowOffsetY = -2;
      ctx3.shadowBlur = 0;
      ctx3.drawImage(YourImageSource,0,0);
      ctx3.shadowOffsetX = 2;
      ctx3.shadowOffsetY = 0;
      ctx3.shadowBlur = 0;
      ctx3.drawImage(YourImageSource,0,0);
      ctx3.shadowOffsetX = -2;
      ctx3.shadowOffsetY = 0;
      ctx3.shadowBlur = 0;
      ctx3.drawImage(YourImageSource,0,0);
0
Darren