Outils pour utilisateurs

Outils du site


issue112:inkscape

Table des matières

1

Last time, we looked at Flood Fill and Turbulence – a pair of primitives that can be used to fill the filter area with, respectively, a flat color or a pseudo-random cloud of colors. But there's a universe of other fills you might like to use, from stripes to polka dots, flowers to butterflies. To cater for such infinite possibilities, the SVG standard provides a way to pull another image into your filter chain, using the Image primitive. This allows you to not only use bitmap images, but can even reference other parts of your SVG file to let you pull your own creations into the filter chain. There's just one little problem: the Inkscape implementation is well and truly broken. Let's start with the bit that does work, at least to some degree: importing an external bitmap image into your filter chain. As usual, we'll begin with a bit of text as the object to which we'll apply the filter. You can, of course, use any type of object, but I find that text gives me a quick and easy way to see how a filter will look when applied to a complex shape, rather than using just a simple rectangle or circle.

La dernière fois, nous avons regardé Remplissage et Turbulence, deux primitives qui peuvent être utilisées pour remplir les zones de filtrage avec, respectivement, une couleur unie ou un nuage de couleurs pseudo-aléatoires. Mais il y a une foule d'autres remplissages que vous pourriez vouloir utiliser, des bandes jusqu'aux pois, des fleurs aux papillons. Pour répondre à ces possibilités infinies, la norme SVG fournit une méthode pour insérer une autre image dans votre chaîne de filtrage, en utilisant la primitive Image. Ceci vous permet, non seulement d'utiliser des images bitmap, mais peut aussi faire référence à d'autre parties de votre fichier SVG pour vous permettre d'insérer vos propres créations dans la chaîne de filtrage. Il n'y a qu'un petit problème : l'implémentation dans Inkscape est belle et bien inutilisable.

Commençons avec le peu qui fonctionne, au moins jusqu'à un certain point : l'importation d'une image bitmap externe dans votre chaîne de filtres. Comme d'habitude, nous commencerons avec un peu de texte comme objet auquel appliquer le filtre. Vous pouvez, bien sûr, utiliser n'importe quel type d'objet, mais je trouve que, plutôt qu'un simple rectangle ou cercle, un texte me permet de voir d'une façon rapide et facile ce à quoi ressemble le filtre quand il est appliqué à une forme complexe.

Create a filter on the test object using one of the methods described in Part 48, and, if necessary, remove any existing filter primitives. Now add a single “Image” primitive to the filter chain, and take a look at its minimal controls at the bottom of the dialog. The “Source of Image” field will be used to hold the path and filename of an external image file, or the XML id of another element in your image. For now, you should choose an external bitmap image by clicking on the “Image File” button and picking one from your hard drive. We'll use our tried and tested Mona Lisa image, giving us the following output (unfiltered text on the left, filtered on the right) when the filter is created in Inkscape 0.48 (bottom left). Now you don't need to be an expert in renaissance art to notice that the image has been distorted somewhat. Now the same filter created in 0.91 (bottom right).

Créez un filtre sur l'objet test en utilisant une des méthodes décrites dans la partie 48 et, si nécessaire, enlevez toutes les primitives existantes. Maintenant, ajoutez une seule primitive Image à la chaîne de filtrage, et vérifiez que les contrôles sont au minimum en bas du dialogue. Le champ « Source de l'image » sera utilisé pour déterminer le chemin et le nom de fichier du fichier image externe ou l'identifiant XML d'un autre élément de votre image. Pour l'instant, vous choisissez une image bitmap externe en cliquant sur le bouton « Fichier image » et la sélectionnant sur votre disque dur. Nous utiliserons notre image de Mona Lisa déjà essayée et adoptée, nous donnant la sortie suivante (texte non filtré à gauche, filtré à droite) quand le filtre est créé dans Inkscape 0.48 (en bas à gauche).

Vous n'avez vraiment pas besoin d'être un expert en art de la Renaissance pour voir que l'image est quelque peu déformée. Et voici le même filtre créé dans la 0.91 (en bas à droite).

Well, we've lost the distorted aspect ratio, but it doesn't exactly fill the filter area – although we can do something about that, as we'll see shortly. This change in behaviour could potentially mean that drawings created in 0.48 may not appear the same in 0.91 if they make use of this filter primitive. In 0.48, you're stuck with the default position and size of the image – i.e. stretched to fill the bounding box of the object. The official Inkscape manual makes it sound as though you can at least set the position and size of the image within the filter by using the XML editor, but, despite many attempts, I haven't been able to achieve this. To be fair, the manual does state that the implementation in Inkscape “doesn't correctly position images” – though that seems to be something of an understatement based on my own tests.

Eh bien, nous avons perdu la déformation du format, mais la zone de filtre n'est pas vraiment remplie ; cependant, nous pouvons y remédier et nous verrons cela sous peu. Ce changement de comportement pourrait éventuellement signifier que l'apparence des dessins créés dans la 0.48 pourraient ne pas être la même dans la 0.91 si vous utilisiez cette primitive de filtrage.

Dans la 0.48, la position par défaut et la taille de l'image nous sont imposées, c'est-à-dire étirée pour remplir la boîte englobante de l'objet. Le manuel officiel d'Inkscape laisse entendre que vous pouvez au moins régler la position et la taille de l'image dans le filtre en utilisant l'éditeur XML, mais, malgré tous mes essais, je n'ai pas réussi. Pour être honnête, le manuel dit que son implémentation dans Inkscape « ne positionne pas correctement les images », ce qui, d'après mes tests, est un euphémisme.

2

With 0.91, things fare a little better – though you'll still have to make your way to the XML editor to change the parameters, as they're still not reflected in the GUI. Dig out Part 31 of this series if you need a refresher on how to use the XML editor. The XML element you'll need to modify is the <svg:feImage> which is inside an <svg:filter> in the <svg:defs> section of the file. You can add 'x', 'y', 'width', and 'height' attributes, although, in my tests, none of them took effect until I also added a 'preserveAspectRatio' attribute. In subsequent tests, once such an attribute was already present, I had to change it to a different value and back again for changes in the other attributes to be reflected in Inkscape's canvas. Changing it to an invalid value and back does the trick, so you can just add a single letter to the end of the existing value, click “Set”, remove the letter, then click “Set” again. So just what is a valid value for preserveAspectRatio? A good starting point is the word “none” - that will cause Inkscape to ignore the aspect ratio of the original image, and stretch it to fill the bounding box of the object, resulting in a similar appearance as with version 0.48. But there are other options – lots of them, all similarly and confusingly named! They all start with a lowercase 'x' and are followed immediately by 'Min', 'Mid' or 'Max' (which, for the x direction, basically means left aligned, centered or right aligned), then followed immediately by an uppercase 'Y' and another 'Min', 'Mid' or 'Max' (top, middle or bottom aligned), followed by a space and an optional keyword of 'meet' (scale the image so that it's all visible) or 'slice' (scale the image to fill the bounding box, whilst preserving the aspect ratio, but hide any parts that extend beyond the bounding box – i.e. just show a slice of the image). Confusing, isn't it? Perhaps some examples (below) would help.

Avec la 0.91, c'est un peu mieux, bien qu'il faille toujours passer par l'éditeur pour modifier les paramètres, car ils ne figurent toujours pas dans l'interface utilisateur. Replongez-vous dans la partie 31 de cette série si vous voulez rafraîchir votre mémoire au sujet de l'édition du XML. L'élément XML que vous devez modifier est <svg:feImage> qui est dans un <svg:filter> de la section <svg:defs> du fichier. Vous pouvez ajouter les attributs « x », « y », « width » (largeur) et « height » (hauteur), bien que, dans mes tests, aucun d'eux n'ait eu d'effet jusqu'à ce que j'ajoute aussi l'attribut « preserveAspectRatio » (préserver le rapport hauteur/largeur). Dans les tests suivants, une fois un tel attribut présent, j'ai dû changer sa valeur et retourner modifier les autres paramètres pour que ça soit pris en compte sur le canevas d'Inkscape. Si vous changez pour une valeur invalide et revenez à la valeur originale, cela fera l'affaire ; ainsi, il suffit de mettre une lettre à la fin de la valeur existante, cliquer sur « Définir », enlever la lettre et re-cliquer sur « Définir ».

Mais qu'est-ce qu'une bonne valeur pour preserveAspectRatio ? Un bon point de départ est le mot « none » (aucun), qui fera qu'Inkscape ignorera le rapport d'aspect de l'image originale et l'étirera pour remplir la boîte englobante de l'objet, le résultat ressemblant à celui de la version 0.48. Mais il y a beaucoup d'autres options, toutes avec des noms similaires et déconcertants ! Elles commencent toutes par la lettre minuscule « x », immédiatement suivie de « Min », « Mid » ou « Max » (ce qui, pour la direction x, signifie aligné à gauche, centré ou aligné à droite), suivis par un « Y » majuscule et un autre « Min », « Mid » ou « Max » (aligné en haut, au milieu ou en bas), suivie d'un espace et du mot-clé optionnel « meet » (recadrer l'image pour qu'elle soit entièrement visible) ou « slice » (mettre l'image à l'échelle pour remplir la boîte englobante, tout en préservant le ratio d'aspect, mais en cachant tout ce qui dépasse de la boîte englobante, c'est-à-dire, n'afficher qu'une tranche de l'image). Confus, n'est-ce pas ? Quelques exemples (ci-dessous) vont peut-être aider.

No, I don't know why the SVG working group went for the confusingly similar 'Min' and 'Mid', nor why 'x' is lowercase whilst 'Y' is uppercase, nor why they chose the words 'meet' and 'slice' rather than 'scale' and 'crop'. I do know, however, that my examples are just the tip of the iceberg: there are 19 possible combinations, without considering the aforementioned 'x', 'y', 'width' and 'height', which can have a dramatic effect on what actually appears in your filter. Until Inkscape gains a UI to make some sense of this madness, I recommend leaving the advanced options of this filter to the experts. But if you do want your image to be distorted to fit the bounding box, per 0.48, you will have to take a deep breath, roll up your sleeves, and wade into the XML editor to deliver a swift dose of preserveAspectRatio=“none”. There's one last thing worth noting about the Image primitive, when used with external images. By default, Inkscape will put the entire path to your image into the filter UI. In order to keep your drawings more portable I strongly recommend keeping any required images in the same folder as your drawing, and then manually editing the entry in the filter settings to remove the path, leaving just the filename. You might consider embedding your image into your document, rather than keeping it in an external file, but read on

Non, je ne sais pas pourquoi le groupe de travail SVG en est arrivé à une similarité déroutante de « Min » et « Mid », pas plus que pourquoi « x » est en minuscule alors que « Y » est en majuscule, ni pourquoi il a choisi les mots « meet » et « slice » plutôt que « scale » (échelle) et « crop » (rogner). Je sais bien, cependant, que mes exemples ne sont que la partie visible de l'iceberg : il y a 19 combinaisons possibles, sans considérer les « x », « Y », « width » et « height » déjà cités, qui peuvent avoir un effet important sur ce qui apparaît dans votre filtre.

Jusqu'à ce qu'Inkscape dispose d'une interface utilisateur qui rende plus compréhensible toute cette folie, je recommande de laisser les options avancées de ce filtre à des experts. Mais si vous voulez déformer votre image pour qu'elle remplisse la boîte englobante, comme dans la 0.48, vous devrez prendre une grande respiration, remonter vos manches, et intervenir dans l'éditeur XML pour y mettre une rapide dose de preserveAspectRatio=“none”.

Il y a une dernière chose intéressante à noter à propos de la primitive Image, quand vous utilisez des images externes. Par défaut, Inkscape, mettra le chemin complet vers votre image dans l'interface utilisateur. Pour rendre vos dessins plus portables, je vous recommande fortement de conserver les images nécessaires dans le même dossier que votre dessin, et, ensuite, de modifier manuellement la saisie des réglages du filtre pour enlever le chemin, ne laissant que le nom du fichier. Vous pourriez préférer incorporer votre image dans votre document, plutôt que la garder comme fichier externe, mais lisez la suite.

The Image primitive should have one more trick up its sleeve. but, yet again, it's broken. It's possible to select an object (or group) in your Inkscape image and then click the “Selected SVG Element” – at which point the Source of Image box will populate with the ID of the element. In this way, it should be possible to pull any other SVG element into your filter chain… except that it doesn't work. It does appear to function in 0.48, in that a rasterised version of the element is pulled in and stretched to fill the bounding box, but in 0.91 even that limited ability seems to have vanished. So there you have the Image primitive – a filter that promises so much, but delivers so little. The useful parts that work in 0.48 are broken in 0.91, whilst the useful parts from 0.91 require you to wade into the XML editor. Meanwhile, the pitiful UI sits back, laughing at your efforts to attempt something as audacious as setting the position of your image within the bounding box. Let's hope that UI gains a little flesh in a future release, and that the ability to use SVG elements makes a welcome return.

La primitive Image devrait avoir une astuce de plus dans son jeu, mais, une fois encore, c'est hors d'usage. Il est possible de sélectionner un objet (ou un groupe) dans votre image Inkscape et ensuite de cliquer sur « Élément SVG sélectionné », ce qui remplit la boîte Image Source avec l'identifiant de l'élément. De cette façon, il devrait être possible d'incorporer n'importe quel autre élément SVG dans votre chaîne de filtrage… sauf que ça ne fonctionne pas. Ça l'air de marcher dans la 0.48,puisqu'une version pixelisée de votre élément est incorporée et étirée pour remplir la boîte englobante, mais, dans la 0.91, même cette possibilité réduite a disparu.

Vous avez donc la primitive Image - un filtre qui promet beaucoup, mais en donne si peu. Les parties utiles qui fonctionnent dans la 0.48 sont hors d'usage dans la 0.91, alors que les parties utilisables de la 0.91 vous obligent à plonger dans l'éditeur XML. Dans le même temps, la triste interface utilisateur baisse les bras, se gaussant de vos efforts pour réaliser quelque chose d'aussi audacieux que la réglage de la position de votre image dans la boîte englobante. Espérons que l'interface utilisateur sera plus étoffée dans une future publication, et que la possibilité d'utiliser les éléments SVG fera un retour bienvenu.

3

That concludes our look at the “fill” primitives in Inkscape. The SVG spec, though, has one other – “Tile” – which lets you feed in the output from another primitive to be repeated (“tiled”) over the whole of the filter region. In order for this to work, the incoming primitive needs to have a filter region that is smaller than the one it's going to be tiled into; but, as Inkscape uses a single filter region definition for the entire filter chain, even if this primitive were to be implemented, it would have no practical effect. It hardly seems fair to have wasted your reading time with a description of one poorly implemented filter, and another that hasn't been implemented at all, so I'll finish this instalment by adding another useful primitive to your toolbox: Morphology. Despite its fancy sounding name, this is a very simple filter: all it does is makes things thicker or thinner. And it does so with the minimum of fuss: there's just a drop-down to select between “erode” (make things thinner) and “dilate” (make things thicker), and a pair of optionally linked “radius” sliders to set the amount of erosion or dilation that will take place. Let's see this filter in action – in each case the first text object is unfiltered, and the second is filtered as described, with a radius of 2.5.

Ceci conclut notre tour des primitives de remplissage d'Inkscape. Cependant, la spécificité SVG en a une autre : Tile (Tuile), qui vous permet d'inclure la sortie d'une autre primitive qui sera répétée (tuilée) sur la totalité de la région du filtre. Pour qu'elle marche, la primitive qui rentre doit avoir une région de filtre plus petite que celle ou elle sera tuilée ; mais, comme Inkscape utilise une région de filtre unique pour la totalité de la chaîne de filtrage, même si cette primitive devait être implémentée, elle n'aurait aucun effet visible.

Ça ne paraît pas très sympa de vous avoir fait perdre votre temps à lire la présentation d'un filtre aussi pauvrement implémenté et d'un autre pas du tout implémenté ; aussi, je finirai cet article par une autre primitive utile de la boîte à outils : Morphologie.

En dépit de son joli nom, c'est un filtre très simple : tout ce qu'il fait est de rendre les choses plus épaisses ou plus fines. Et il le fait avec le minimum de chichis : il n'y a qu'une liste déroulante, pour sélectionner « Contracter » (rendre les choses plus fines) ou « Dilater » (les rendre plus épaisses) et une paire de réglettes « Rayon », liées en option, pour ajuster la quantité de finesse ou d'épaisseur appliquée. Regardons ce filtre en action ; dans chaque cas, le premier objet texte est non filtré, et le second est filtré comme indiqué, avec un rayon de 2,5.

These filters are particularly useful when used with the Composite primitive, often in “In” or “Out” modes. In the following example, I've used a Flood filter to create a translucent white fill, then used a Composite “In” to trim it to the size of my eroded text. A little Gaussian Blur and Offset later, and you've got a filter that gives a 3D appearance to your text. “Out” can work well with dilation, to punch out the center of the dilated image. As a simple case, consider a Morphology primitive that dilates the source, then a Composite Out that leaves only those parts of the image that are outside the original source object. What you're left with is an outline of your object, with a transparent middle. Now, rather than punching out the source object, what if you punch out another dilated version, such that you're removing a small dilation from the core of a large dilation. Merge the original object back in, and you have an outline that surrounds the original, at a distance set by the smaller dilation with a thickness equal to the difference between the inner and outer dilations (you may need to increase the size of the filter region to avoid the result being cropped).

Ces filtres sont particulièrement utiles quand ils sont utilisés avec la primitive Composite, souvent en mode « In » ou « Out ». Dans l'exemple suivant, j'ai utilisé un filtre Remplissage pour créer un remplissage blanc translucide, puis j'ai utilisé une Composite « In » pour l'ajuster à la taille de mon texte contracté. Après un peu de Flou gaussien et d'Offset, vous obtenez un filtre qui donne une apparence 3D à votre texte.

« Out » peut bien fonctionner avec la dilatation, pour creuser le centre de l'image dilatée. Comme exemple simple, considérez une primitive Morphologie que dilate la source, puis une Composite « Out » qui ne garde que les parties de cette image qui dépassent de l'objet source d'origine. Il ne reste que le contour de votre objet, dont l'intérieur est transparent.

Maintenant, plutôt que d'enfoncer l'objet source, que se passe-t-il si vous enfoncez une autre version dilatée, de sorte que vous enlevez une petite excroissance au cœur d'une plus grosse dilatation ? Fusionnez avec l'objet original et vous avez un contour qui entoure l'original, à une distance réglé par la plus petite dilatation, avec une épaisseur égale à la différence entre les dilatations intérieure et extérieure (vous devrez peut-être augmenter la taille de la région du filtre pour éviter que le résultat soit tronqué).

Finally, how about taking the previous idea and stacking it up a little further. You can have several outlines, all at different distances from the original object, then just merge everything together at the end. Things start to get a little complex as you add more outlines, because you're juggling a pair of Morphology primitives and a Composite for each layer of the onion, but, in principle, it's possible to carry on adding as many as you like, so long as you can keep track of them all. Or how about this version, where I've also used Color Matrix primitives in Hue Rotate mode in order to give each outline its own color: It's worth remembering that filters are bitmap operations that take place at the rendering stage. Although you can think of the Morphology primitive as thinning or thickening your image, it's not doing so in a vector sense, but rather by just adding or removing pixels in a bitmap version of your object. With that in mind, it also makes sense that you can apply this primitive to bitmap images imported via the Image primitive. This allows you to hide the fine details of an image by eroding them away, or blotting them out through dilation of adjacent areas, without introducing the sort of softness you would expect if you just blurred the images. In either case, Mona ends up looking somewhat worse for the experience!

Enfin, que se passe-t-il si vous prenez l'idée précédente et la complétez un peu plus ? Vous pouvez avoir plusieurs contours, à des distances différentes de l'objet d'origine, que vous fusionnez ensemble pour terminer. Plus vous ajoutez de contours, plus les choses deviennent compliquées, car vous jonglez avec une paire de primitives Morphologie et une Composite pour chaque couche de l'oignon ; mais, théoriquement, il est possible d'en rajouter autant que vous voulez, tant que vous ne vous perdez pas en route.

Et que dire de cette version, où j'ai utilisé aussi des primitives Matrice des couleurs en mode Décalage de teinte de façon à attribuer une couleur à chaque contour :

Il est bon de se rappeler que les filtres sont des opérations bitmap qui ont lieu pendant la phase de rendu. Bien que vous puissiez penser que la primitive Morphologie rétrécit ou dilate votre image, ce n'est pas réalisé dans un sens vectoriel, mais plutôt en ajoutant ou en retirant des pixels dans une version bitmap de votre objet. En gardant cela en tête, il paraît possible d'appliquer la primitive à des images bitmap importées via la primitive Image. Ceci vous permet de cacher les détails précis d'une image en les dégradant un peu, ou en les masquant par une dilatation des zones adjacentes, sans introduire la sorte d'adoucissement que vous attendriez en floutant les images. Dans les deux cas, Mona se sort bien mal d'un tel essai !

Image Credits “La Gioconda” (aka “Mona Lisa”) by Leonardo da Vinci http://en.wikipedia.org/wiki/File:Mona_Lisa,_by_Leonardo_da_Vinci,_from_C2RMF_retouched.jpg

Crédits images

La Joconde (alias Mona Lisa) par Léonard de Vinci http://en.wikipedia.org/wiki/File:Mona_Lisa,_by_Leonardo_da_Vinci,_from_C2RMF_retouched.jpg

issue112/inkscape.txt · Dernière modification : 2016/08/31 18:54 de auntiee