254 lines
13 KiB
Markdown
254 lines
13 KiB
Markdown
# Iso-couches par nuances de gris — extension Inkscape
|
|
|
|
<table>
|
|
<tr>
|
|
<td width="50%" valign="top">
|
|
<img src="docs/exemple.png" alt="Une image de relief flou, sa découpe en 16 niveaux de gris, et les mêmes 16 niveaux au trait seul" width="420">
|
|
</td>
|
|
<td valign="top">
|
|
|
|
Extension Inkscape 1.x qui transforme une image bitmap en planches à découper
|
|
et à empiler, un calque par nuance de gris. L'image est lissée, quantifiée en quelques
|
|
niveaux (16 par défaut), puis chaque aplat est bordé d'un contour fermé et
|
|
souple, à la manière des courbes de niveau d'une carte. Le résultat se découpe
|
|
en strates (une feuille par niveau) ou se réduit à un dessin au trait.
|
|
|
|
De gauche à droite : l'image de départ, ses 16 niveaux remplis chacun de son
|
|
gris (16 calques), et les mêmes 16 niveaux en remplissage blanc et trait noir.
|
|
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
Le lissage respecte les contours : sur un portrait, la peau et les cheveux sont
|
|
aplanis mais les yeux, la bouche et le bord du visage restent nets, et les
|
|
16 niveaux suffisent à reconstruire le visage.
|
|
|
|
|
|
## Sommaire
|
|
|
|
- [Fonctionnalités](#fonctionnalités)
|
|
- [Installation](#installation)
|
|
- [Utilisation](#utilisation)
|
|
- [Paramètres](#paramètres)
|
|
- [Structure du projet](#structure-du-projet)
|
|
- [Développement](#développement)
|
|
|
|
## Fonctionnalités
|
|
|
|
- Entrée : une ou plusieurs images bitmap sélectionnées (PNG, JPEG…),
|
|
incorporées ou liées, y compris dans un groupe sélectionné. Les couleurs sont
|
|
lues comme des gris, la transparence comme du blanc.
|
|
- Lissage qui respecte les contours (filtre guidé) : les textures sont
|
|
aplanies, les transitions marquées restent nettes, ce qui garde un visage
|
|
reconnaissable. Un flou gaussien simple reste disponible pour les reliefs
|
|
abstraits.
|
|
- Quantification à seuils réguliers, de 2 à 64 niveaux, après étirement de la
|
|
plage de gris de l'image.
|
|
- Contours tracés au sous-pixel sur l'image lissée (« marching squares »), puis
|
|
simplifiés et convertis en courbes de Bézier : pas d'escalier de pixels.
|
|
- Toutes les formes sont fermées : là où un niveau touche le bord de l'image,
|
|
son contour longe ce bord, en lignes droites.
|
|
- Un calque Inkscape par niveau, nommé « Planche n° 1 », « Planche n° 2 »…
|
|
du fond vers l'avant, créé au-dessus de l'image : autant de nouveaux calques
|
|
que de niveaux de gris. Plusieurs images sélectionnées partagent les mêmes
|
|
calques.
|
|
- Planches à empiler : la planche n° 1 couvre toute l'image et chaque planche
|
|
suivante, plus petite, se pose devant la précédente (la plus claire devant,
|
|
ou la plus sombre devant), pour construire un relief en strates.
|
|
- Repère d'assemblage : chaque planche porte, en plus de son trait de découpe
|
|
(rouge), le contour de la planche suivante (noir), au tracé exact de sa
|
|
découpe, pour savoir où la coller.
|
|
- Variante « Son gris seul » : chaque calque contient l'aplat de son gris,
|
|
bordé sur tous ses côtés ; les planches pavent l'image sans se recouvrir et
|
|
ne portent pas de repère. Les contours sont exactement les frontières de
|
|
l'image quantifiée.
|
|
- Formes écrites en coordonnées du document, sans transformation, même pour
|
|
une image tournée, étirée ou placée dans un calque transformé.
|
|
- Remplissage au choix (gris du niveau, couleur unique, aucun) et trait
|
|
facultatif.
|
|
- Interface traduite en français et en anglais, selon la langue d'Inkscape
|
|
(anglais pour toute autre langue).
|
|
- Script de déploiement Windows.
|
|
|
|
## Installation
|
|
|
|
Aucune dépendance à installer : l'extension utilise `inkex`, `numpy` et
|
|
`Pillow`, tous fournis avec Inkscape.
|
|
|
|
### Windows
|
|
|
|
```powershell
|
|
.\deploy.ps1 # copie dans %APPDATA%\inkscape\extensions\GrayIsoLayers
|
|
.\deploy.ps1 -Uninstall # retire l'extension
|
|
.\deploy.ps1 -Force # déploie même si Inkscape est ouvert
|
|
```
|
|
|
|
Inkscape doit être fermé pendant la copie, puis relancé.
|
|
|
|
### Manuelle
|
|
|
|
Copier dans un sous-dossier du répertoire des extensions utilisateur
|
|
(`%APPDATA%\inkscape\extensions` sous Windows, `~/.config/inkscape/extensions`
|
|
sous Linux, `~/Library/Application Support/org.inkscape.Inkscape/config/inkscape/extensions`
|
|
sous macOS) :
|
|
|
|
- `gray_iso_layers.inx`, `gray_iso_layers.py`, `gray_iso_layers_core.py` ;
|
|
- `images/parameters_en.png` ;
|
|
- le dossier `locale/`.
|
|
|
|
## Utilisation
|
|
|
|
1. Importer une image (**Fichier > Importer**) et la sélectionner.
|
|
2. Lancer **Extensions > AlexDesign > Iso-couches par nuances de gris…**
|
|
(*Gray Iso-Layers*).
|
|
3. Régler le nombre de niveaux et le lissage, puis **Appliquer**.
|
|
|
|
Le résultat est une série de calques « Planche n° 1 », « Planche n° 2 »…
|
|
ajoutés juste au-dessus du calque de l'image, un par niveau de gris. La
|
|
planche n° 1 est au fond, la dernière devant. Par défaut, les planches
|
|
s'empilent : la planche n° 1, la plus sombre, couvre toute l'image et les
|
|
suivantes se posent devant elle. Chaque calque contient deux chemins : la
|
|
« Découpe » de la planche (trait rouge) et le « Repère de la planche n° … »
|
|
suivante (trait noir, sans remplissage). Avec le contenu « Son gris seul »,
|
|
chaque planche est l'aplat de son gris et il n'y a pas de repère. Un niveau dont toutes
|
|
les formes sont plus petites que le plus petit îlot conservé garde son calque,
|
|
vide.
|
|
|
|
### Conseils
|
|
|
|
- **Découpe laser** : choisir « Aucun remplissage » ; il ne reste que les
|
|
traits de découpe (rouge) et de marquage (noir), à affecter chacun à son
|
|
réglage dans le logiciel de la machine. Découper un calque par feuille.
|
|
- **Dessin au trait, comme une carte topographique** : remplissage « Couleur
|
|
unique » blanche (ou « Aucun remplissage »), trait noir, repère décoché.
|
|
- **Contours trop chargés, petits îlots** : augmenter le lissage ou le plus
|
|
petit îlot conservé.
|
|
- **Contours anguleux** : augmenter le lissage ou la simplification.
|
|
- **Détails perdus, visage méconnaissable** : réduire le lissage (0,5 à 1 %),
|
|
laisser « Préserver les contours » coché, augmenter la résolution de calcul.
|
|
- **Portrait** : un fond uni donne le meilleur résultat ; un fond en dégradé
|
|
produit des anneaux, puisque chaque nuance du dégradé devient un aplat.
|
|
- **Image liée introuvable** : l'incorporer (clic droit > Incorporer l'image).
|
|
- Une image de bruit flou (nuages, relief) donne les motifs les plus proches
|
|
d'une carte de courbes de niveau.
|
|
|
|
## Paramètres
|
|
|
|

|
|
|
|
Onglet **Niveaux**
|
|
|
|
| Paramètre | Défaut | Rôle |
|
|
| --- | --- | --- |
|
|
| Nombre de niveaux de gris | 16 | Nombre d'aplats, donc de calques produits (2 à 64). |
|
|
| Contenu de chaque planche | Empilées, la plus claire devant | « Empilées, la plus claire devant » : planche n° 1 = la plus sombre, toute l'image. « Empilées, la plus sombre devant » : planche n° 1 = la plus claire, toute l'image. « Son gris seul » : planches côte à côte, sans recouvrement, planche n° 1 = le gris le plus sombre. |
|
|
| Reporter sur chaque planche le contour de la suivante | oui | Repère d'assemblage tracé dans la couleur de marquage (planches empilées uniquement). |
|
|
| Lissage (% du grand côté de l'image) | 1 | Lissage appliqué avant la découpe : plus il est fort, plus les contours sont ronds et simples. |
|
|
| Préserver les contours lors du lissage | oui | Aplanit la peau et les textures mais garde nettes les transitions marquées (portraits, photos). Décoché : flou gaussien simple, mieux adapté aux reliefs abstraits. |
|
|
| Résolution de calcul (points sur le grand côté) | 800 | Taille à laquelle l'image est rééchantillonnée pour le calcul. |
|
|
| Plus petit îlot ou trou conservé (% de la surface de l'image) | 0,02 | Les formes plus petites sont écartées. |
|
|
| Simplification (points de calcul) | 0,4 | Écart maximal toléré lors de la suppression de nœuds ; 0 les conserve tous. |
|
|
| Lisser les contours avec des courbes de Bézier | oui | Sinon, les contours sont des polygones. |
|
|
|
|
Onglet **Style**
|
|
|
|
| Paramètre | Défaut | Rôle |
|
|
| --- | --- | --- |
|
|
| Remplissage | Gris de chaque niveau | Gris du niveau, couleur unique ou aucun remplissage. |
|
|
| Couleur de remplissage | blanc | Utilisée par le mode « Couleur unique ». |
|
|
| Épaisseur du trait (0 = sans trait) | 0,2 | Dans l'unité choisie ; commune à la découpe et au marquage. |
|
|
| Unité | mm | Unité de l'épaisseur du trait. |
|
|
| Couleur du trait de découpe | rouge | Contour de la planche. |
|
|
| Couleur du trait de marquage | noir | Repère de la planche suivante. |
|
|
| Conserver l'image d'origine | oui | Sinon l'image est supprimée. |
|
|
|
|
## Structure du projet
|
|
|
|
```text
|
|
gray_iso_layers.inx Boîte de dialogue (textes source en anglais)
|
|
gray_iso_layers.py Couche inkex : lecture de l'image, écriture du SVG
|
|
gray_iso_layers_core.py Noyau de calcul, sans inkex (numpy seul)
|
|
i18n.py Extraction / mise à jour / compilation des traductions
|
|
po/ Catalogues grayisolayers.pot, en.po, fr.po
|
|
locale/ Catalogues compilés (.mo), déployés
|
|
images/parameters_en.png Schéma de l'onglet « Help »
|
|
docs/schema_parametres.py Générateur du schéma (fr pour le README, en pour le dialogue)
|
|
docs/parametres.png Schéma du README
|
|
docs/exemple.png Illustrations du README (relief, portrait)
|
|
docs/exemple-portrait.png
|
|
doc/patern.jpg Motif qui a servi de modèle
|
|
doc/personne.jpg Portrait d'essai
|
|
test_gray_iso_layers.py Tests pytest
|
|
deploy.ps1 Déploiement / désinstallation Windows
|
|
```
|
|
|
|
API du noyau (`gray_iso_layers_core.py`). Un champ est un tableau numpy 2D de
|
|
gris (0 noir, 1 blanc) ; un anneau est un tableau `(n, 2)` de points, en
|
|
échantillons du champ.
|
|
|
|
| Fonction | Rôle |
|
|
| --- | --- |
|
|
| `gaussian_blur(field, sigma)` | Flou gaussien séparable, bords prolongés. |
|
|
| `box_blur(field, radius)` | Moyenne sur une fenêtre carrée. |
|
|
| `edge_preserving_blur(field, radius, contrast)` | Lissage qui respecte les contours (filtre guidé). |
|
|
| `smooth(field, blur, preserve_edges)` | Lissage avant découpe, puis étirement sur 0..1. |
|
|
| `normalize(field)` | Étire le champ sur 0..1. |
|
|
| `thresholds(levels)` | Seuils réguliers séparant les niveaux. |
|
|
| `contour_rings(field, threshold, above=True)` | Contours fermés de la région au-dessus (ou au-dessous) du seuil. |
|
|
| `ring_area(ring)` | Aire d'un anneau. |
|
|
| `simplify_ring(ring, tolerance)` / `simplify_chain(chain, tolerance)` | Simplification de Douglas-Peucker d'un anneau fermé, d'une ligne ouverte. |
|
|
| `contour_lines(field, threshold, tolerance, min_area)` | Ligne de niveau d'un seuil : boucles fermées et lignes ouvertes aboutissant au bord. |
|
|
| `region_rings(field, lines, inside)` | Contour fermé d'une région bornée par des lignes de niveau, refermé le long du bord de l'image. |
|
|
| `iso_boards(field, levels, blur, min_area, tolerance, shapes, preserve_edges)` | Une planche par niveau : liste de `(niveau, gris, anneaux, repère)`, le repère étant la ligne de niveau qui borde la planche suivante. |
|
|
| `iso_layers(…)` | Comme `iso_boards`, sans les repères. |
|
|
| `image_ring(width, height)` | Rectangle de l'image. |
|
|
| `scale_rings(rings, scale_x, scale_y, offset_x, offset_y)` | Passage au repère de destination. |
|
|
| `lines_to_d(lines, smooth, box, precision, matrix)` / `scale_lines(…)` | Écriture et mise à l'échelle d'une ligne de niveau (boucles fermées et lignes ouvertes). |
|
|
| `rings_to_d(rings, smooth, box, precision, matrix)` | Données `d` d'un chemin SVG, bords de l'image gardés droits, transformation affine facultative. |
|
|
| `parse_color(value)` / `gray_to_hex(gray)` | Couleurs. |
|
|
|
|
## Développement
|
|
|
|
```powershell
|
|
pip install pytest numpy pillow
|
|
python -m pytest -q
|
|
```
|
|
|
|
Sans `inkex` : 41 tests passent, 13 sont ignorés. Avec `inkex` :
|
|
|
|
```powershell
|
|
pip install lxml tinycss2 cssselect2 cssselect
|
|
$env:PYTHONPATH = 'C:\Program Files\Inkscape\share\inkscape\extensions'
|
|
python -m pytest -q # 54 tests passent
|
|
```
|
|
|
|
Les tests couvrent le noyau (lissage qui respecte les contours, contours d'un cône et d'une rampe, fermeture le
|
|
long des bords, cas selle, simplification, aplats conformes à l'image
|
|
quantifiée, frontières communes aux aplats voisins, feuilles à empiler, îlots
|
|
écartés, écriture des chemins), l'extension de bout en bout (un calque par niveau, repères d'assemblage, image incorporée, liée ou
|
|
tournée, groupe sélectionné, styles, messages d'erreur) et la cohérence des traductions et du
|
|
`.inx`.
|
|
|
|
### Traductions
|
|
|
|
Les textes source sont en anglais, dans le `.inx` et dans les `_("...")` du
|
|
`.py`. Après toute modification :
|
|
|
|
```powershell
|
|
python i18n.py # extrait, met à jour po/*.po, compile locale/
|
|
```
|
|
|
|
Compléter les `msgstr` vides de `po/fr.po`, puis relancer la commande. Pour
|
|
ajouter une langue, l'ajouter à `LANGUAGES` dans `i18n.py`.
|
|
|
|
### Schéma des paramètres
|
|
|
|
```powershell
|
|
python docs/schema_parametres.py
|
|
```
|
|
|
|
Produit `docs/parametres.png` (français, README) et `images/parameters_en.png`
|
|
(anglais, onglet « Help »), tracés avec les fonctions du noyau. L'export PNG
|
|
passe par `inkscape.com`.
|