PerfectVector
Par Irene Kim

Bords SVG : aperçu avec feConvolveMatrix

Crée un aperçu de bords SVG avec feConvolveMatrix, diagnostique les artefacts d’alpha et de bordure, compare un noyau de netteté et vérifie si la source contient de vrais chemins.

9 min de lecture
Sur cette page

La détection de bords SVG avec feConvolveMatrix change les pixels rendus autour des limites de couleur. Elle peut produire un aperçu des bords à partir d’un PNG dans un SVG, mais elle ne crée pas de contours de chemins modifiables. Garde cette distinction claire lorsque l’étape suivante consiste à modifier un logo, préparer un dessin au trait ou créer une illustration web.

Un premier test utile est une petite image en niveaux de gris avec une forme connue. Applique un noyau de détection symétrique, préserve son alpha et compare-la à la source inchangée. Examine ensuite les éléments SVG. Une limite qui paraît plus nette ne prouve pas que l’image est devenue une géométrie vectorielle.

Commence par un aperçu de bords contrôlé

La référence de feConvolveMatrix décrit la convolution comme un calcul impliquant un pixel d’entrée et ses voisins. Ce noyau de 3 × 3 soustrait les huit voisins à huit fois le centre :

-1 -1 -1
-1  8 -1
-1 -1 -1

La somme de ses coefficients est nulle. Dans une zone uniforme, la réponse est nulle ; à un changement de luminosité, elle peut être positive ou négative. Avec bias="0", les résultats négatifs sont écrêtés à la limite inférieure de couleur. L’aperçu ne montre donc pas les deux côtés de chaque limite de façon égale.

L’exemple utilise explicitement divisor="1". La référence de divisor documente la normalisation par cette valeur et la valeur par défaut de 1 pour un noyau de somme nulle. Il définit aussi color-interpolation-filters="sRGB" pour utiliser des valeurs de canal sRGB plutôt que le traitement linearRGB par défaut de la primitive.

Enregistre ce fichier complet et autonome sous edge-preview.svg, puis ouvre-le dans un navigateur. Son PNG intégré est un losange original de 48 × 48 en niveaux de gris, sur un papier blanc opaque. Le centre est blanc, pas transparent.

<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48">
  <defs>
    <filter id="effect" filterUnits="userSpaceOnUse" x="0" y="0" width="48" height="48" color-interpolation-filters="sRGB">
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="-1 -1 -1 -1 8 -1 -1 -1 -1" divisor="1" bias="0" targetX="1" targetY="1" edgeMode="duplicate" preserveAlpha="true"/>
    </filter>
  </defs>
  <image width="48" height="48" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAABOklEQVR4nNWZQQ7EIAwDU7+seTlPo1ppTyvRhcQGxYeeGuNpEZT06r13KyxYccGKC1ZcsOKCFRfUA7h7XQD/hldCQGX8G1oFAYXpKKwCAmzDfyHZEGCazYZjQoBltBqKBQGGSTSMEyDSANkQnqxPAbCmgSd8wgDs1cSDflAP1lqT+IYBIuGVENj15FUQUJiOwiogwDSbCcmGAMNkNRwTApniaKjV+/0lB06Ej9T5IA9Ord+rdW2Q53UKKSFYbxiZ4mgo5vQEw0R1ImsT405vZAwIxcKAacckhGpVw/SdAfNIX6gtLslX9P+AokXSAvtJ+EAT3bzYfjgxKNMHJwdn1FPaKju+heSNLeXX6LbWouI8sL25yzyRHWuvM87Ex39wZLoSS+pi3fct9b8+FyssWHHBigtWXDgdIKsHsU1cbk4FPAgAAAAASUVORK5CYII=" filter="url(#effect)"/>
</svg>

La définition du filtre ne prend effet que parce que l’image la référence avec filter="url(#effect)". La référence des filtres SVG explique que la définition elle-même n’est pas dessinée. La région explicite couvre cette source de 48 × 48 ; un autre dessin nécessite sa propre vérification de région.

Ce qui a changé dans le test du navigateur

Nous avons examiné six exemples originaux dans Chrome à 48 et 192 pixels CSS. Cinq fichiers contiennent une image PNG intégrée et aucun chemin. Le sixième est un équivalent vectoriel dessiné à la main de manière indépendante. C’est un contrôle géométrique, pas le résultat de l’application du filtre ni d’une vectorisation du PNG.

ExempleApparence observéeLecture sur un échantillon uniforme
PNG original dans un SVGLosange gris avec centre et papier blancsGris uni : RGBA 64, 64, 64, 255
Noyau de détection, alpha préservéChamp noir avec réponse de bord ; contour faible au grand affichageCentre et coin : RGBA 0, 0, 0, 255
Noyau de détection, alpha également filtréRésultat transparent dans ce fichier de testCentre, coin et échantillon uni : RGBA 0, 0, 0, 0
Contrôle de nettetéLosange rempli conservé, avec des pixels de limite modifiésGris uni resté à RGBA 64, 64, 64, 255
Noyau de détection, bord à valeur nulleApparition d’un cadre extérieur lumineuxCoin : RGBA 255, 255, 255, 255
Contrôle par chemin dessiné à la mainLosange géométrique propre et ouverture intérieure sur papier blancUn élément chemin, aucun élément image

Les échantillons RGBA provenaient d’une lecture Canvas de 48 × 48 de chaque SVG rendu. Les exemples affichés ont été vérifiés séparément aux deux tailles. Ce sont des observations pour cette source et ce navigateur, pas une garantie de compatibilité ni de lisibilité. Agrandir l’aperçu matriciel n’a pas retrouvé un contour plus propre.

Réponse des pixels et géométrie modifiable
Illustration conceptuelle opposant un losange de réponse de bord en pixels gris à un anneau corail en losange dessiné indépendamment avec des nœuds de modification
Illustration : un aperçu de bords en pixels et un chemin modifiable ont des représentations différentes. Ce n’est ni une capture de navigateur ni un résultat de conversion.

Rétablis un résultat disparu sans effacer le papier

preserveAlpha vaut false par défaut. Avec ce réglage, le noyau traite aussi l’alpha. Notre entrée opaque a un alpha de 1 partout : le noyau de somme nulle annule donc son alpha uniforme en même temps que sa couleur uniforme. Le résultat a disparu dans le fichier de test examiné.

Définir preserveAlpha="true" conserve l’alpha source tout en traitant la couleur. La référence de preserveAlpha documente cette distinction. Dans ce test, cela rétablit un aperçu de bords opaque. Le papier opaque et le centre blanc restent aussi opaques, même si leur couleur filtrée devient noire. Préserver l’alpha ne supprime pas un arrière-plan et ne trouve pas les trous d’un logo.

Si l’aperçu est surtout noir, compare d’abord une zone uniforme connue à une limite connue. Le noir peut être une réponse nulle valide. Pour examiner des changements de luminosité signés autour d’un ton moyen, essaie bias="0.5" ; la référence de bias explique le décalage ajouté après division. Cela change la plage d’affichage, pas la géométrie du SVG.

Vérifie les bordures séparément du dessin

Garde edgeMode="duplicate" pour la première comparaison. Ce mode prolonge les valeurs des pixels du bord lorsque les échantillons voisins sortent de l’entrée. none utilise des échantillons RGBA de valeur nulle ; wrap prend des échantillons sur le bord opposé. Ce sont des règles distinctes dans la référence de edgeMode.

Sur notre carte blanche opaque, changer uniquement duplicate en none a produit un cadre lumineux à l’extérieur de la carte. Cette limite appartient au rectangle de l’image, pas au losange. Compare le fichier sans filtre avant de considérer un cadre comme un contour du dessin.

La spécification Filter Effects définit la cible du noyau et le comportement d’échantillonnage. Ici, targetX="1" et targetY="1" centrent le noyau de 3 × 3. Cette base laisse kernelUnitLength non défini. Ne suppose pas qu’un échantillon voisin couvre toujours une unité utilisateur SVG à toutes les tailles d’affichage ; examine le rendu livré.

Utilise la netteté comme contrôle, pas comme récupération du flou

Pour conserver le dessin rempli tout en accentuant les changements locaux, remplace uniquement kernelMatrix par :

0 -1  0
-1 5 -1
0 -1  0

La somme est de 1. Une valeur de canal uniforme c renvoie 5c - 4c = c avec un diviseur de 1 et un biais de 0. Dans notre fichier de test, l’échantillon gris uni est resté à 64 tandis que les pixels de limite changeaient. Garde preserveAlpha="true" et edgeMode="duplicate" pour cette comparaison.

L’accentuation peut souligner le bruit et les halos en même temps que les limites utiles. Elle ne retrouve pas les détails sources perdus avant l’arrivée de l’image dans le filtre. Si un aperçu agrandi est mauvais, reviens à l’image originale au lieu de considérer un noyau plus fort comme un remplacement de la résolution source.

Examine le fichier avant de parler de vectorisation

La base publiée contient un <image> dont le href commence par data:image/png. La référence de l’élément image décrit les ressources matricielles et SVG que cet élément peut afficher. Ici, le type de média identifie l’image matricielle intégrée ; le filtre de bords laisse cet élément en place.

Pour comparaison, le maître créé indépendamment utilise ce chemin composé sur un rectangle blanc :

<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48">
  <rect width="48" height="48" fill="white"/>
  <path d="M24 6 L42 24 L24 42 L6 24 Z M24 17 L31 24 L24 31 L17 24 Z"
        fill="#404040" fill-rule="evenodd"/>
</svg>

Ces coordonnées ont été écrites séparément. Elles ne sont pas récupérées depuis l’image filtrée, et le dessin en pixels et le contrôle géométrique ne doivent pas nécessairement correspondre à chaque échantillon de limite. Le guide d’inspection des images matricielles intégrées explique comment vérifier un SVG mixte sans se fier au seul zoom.

Pour une illustration web, garde le maître SVG sans filtre et utilise une copie d’affichage filtrée lorsque l’effet sert le dessin. Pour des chemins de modification ou de production, examine les véritables contours sources et l’ouverture intérieure. Le guide du dessin au trait en SVG traite de cette tâche géométrique.

PerfectVector convient lorsque ton dessin de départ est un PNG ou JPG plat et que tu as besoin de formes sources modifiables. Convertis l’image originale en SVG, examine le contour et l’ouverture intérieure, puis garde le résultat propre comme maître. Un aperçu de bords réussi ne remplace pas cette vérification. Le guide de vectorisation explique la différence entre reconstruire des chemins et appliquer un effet d’image.

Questions fréquentes

La détection de bords SVG avec feConvolveMatrix crée-t-elle des chemins vectoriels ? Non. Elle calcule un effet de pixels rendus. Le PNG intégré dans cet exemple reste un élément image ; des contours modifiables nécessitent une géométrie dessinée ou vectorisée séparément.

Pourquoi mon filtre de bords fait-il disparaître le dessin ? Vérifie preserveAlpha. Sa valeur par défaut false filtre aussi l’alpha. Dans ce fichier de test opaque, le noyau de somme nulle a rendu le résultat examiné transparent. Préserver l’alpha a rétabli un aperçu opaque.

preserveAlpha supprime-t-il le fond blanc ? Non. Il garde l’alpha source. Un fond blanc opaque reste opaque, même si sa couleur filtrée devient noire. La suppression du fond et la reconstruction des chemins sont des tâches distinctes.

Pourquoi un filtre de bords dessine-t-il un cadre autour de l’image ? Examine edgeMode et le rectangle d’entrée. Utiliser des échantillons à valeur nulle hors de notre carte blanche opaque a créé une bordure extérieure lumineuse. Le traitement duplicate a évité cette bordure dans ce fichier de test.

Sources

  1. MDN : feConvolveMatrix — Convolution avec les pixels voisins et traitement des couleurs par défaut.
  2. MDN : divisor — Normalisation et valeur par défaut pour une somme nulle.
  3. MDN : filter — Définition et application d’un effet de filtre.
  4. MDN : preserveAlpha — Traitement de la couleur seule ou incluant l’alpha.
  5. MDN : bias — Décalage de la réponse après division.
  6. MDN : edgeMode — Traitement des bords par duplication, retour au bord opposé et valeurs nulles.
  7. W3C : Filter Effects, feConvolveMatrix — Règles de cible et d’échantillonnage.
  8. MDN : image — Contenu d’image matricielle et SVG référencé.

Plus depuis le blog

PerfectVector

Repartez d’un SVG plus net
et plus facile à modifier

Sans carte bancaire