Outils pour utilisateurs

Outils du site


issue116:inkscape

Ceci est une ancienne révision du document !


There's one last filter primitive to visit in this series, which I've kept until last simply because it's a new addition in 0.91, so isn't available to users who are still using version 0.48. The filter is called Component Transfer, and its purpose is to use a function (called a “transfer function”) to adjust the distribution of values within each color channel (or “component”). It allows you to adjust brightness or contrast, or to set hard thresholds for posterization effects. As usual, I'll begin by considering the filter's operation on a single color channel, then you can extrapolate from there to how it behaves with three channels plus alpha. A single color channel of a single pixel is represented by a number from 0 (no color) to 255 (completely saturated). The distribution of the values is linear – ramping up along a straight line – and the default settings for the Component Transfer primitive leave this line untouched. A value of 0 into the filter results in 0 out. 136 in gives 136 out. And so on. This can be represented as a graph, where the value of the channel coming into the filter is shown on the x-axis, and the value that comes out of the filter is shown on the y-axis. In practice, this primitive maps the input values to a range from 0 to 1 rather than 0 to 255, but the result is the same: with the default settings in the filter (“Identity”), every input channel is mapped to the output without being affected. The purpose of the Component Transfer filter is to play around with that simple 45° graph to let you change the way that input values are mapped to output values.

Basic mathematics tells us that a straight line graph like this can be defined by the slope of the line and the point at which it intercepts with the y-axis. One way to modify the mapping, therefore, is to alter the slope and the intercept point – a pair of values provided by the “Linear” option in the filter. The identity line has a slope of 1 – that is, for every increase of 1 along the x axis, the y value also increases by 1. By setting it to a value of 2 we can make the slope steeper, causing the output to appear brighter. Here's how it looks for one channel in the filter dialog: As well as showing the effect on the slope, I've also included a grayscale version of Mona, with the right-hand side showing the result of applying this change to all the color channels: Changing the slope to a smaller value, 0.5 in this case, reduces the brightness of the image: By changing the intercept you can alter the contrast of the image; you may also want to tweak the slope to ensure you don't also change the brightness at the same time (unless that's your intention). For example, setting an intercept of 0.5 with a slope of 1 would give you this result: Bear in mind that color channels can't go below 0 or above 127, so the graph changes shape when you hit these limits. As you can see, it becomes horizontal halfway along the x-axis, washing out any values above 127 by turning them completely white. Compensating for this by changing the slope to 0.5 preserves the detail a lot more, because all 255 input values are mapped, rather than just clamping half of them.

The intercept value can also be negative, to give a darker output, again with reduced contrast. It's worth noting that the slope can also be negative, which inverts the mapping so that larger input values are converted to small output values, and vice versa. With a slope of -1 and an intercept of 1, the output from the channel is completely inverted: The linear mode of this filter primitive assumes that you want a simple mapping from input to output, to adjust the brightness or contrast by altering the slope and position of a single line. But there are times when a single straight line (even one that flattens out at the limits of the color range) just doesn't cut it. What happens if you want the output to ramp up, then down again, such that values at the extreme ends of the range are mapped to low numbers, whilst those in the middle are mapped to high numbers? For that we have the “Table” mode. “Table” may be a little misleading, as the table you have to supply is one-dimensional. “List” might have been a better name, but table is what the SVG Working Group decided to go with, and what Inkscape exposes. The numbers in the list represent the start and end values for a series of straight line segments; the number of values in the list determines how many segments there are. For example, the table below has five values (you can use spaces and/or commas to separate them): These five values give rise to four separate segments in the graph, causing the output values to ramp up and down rapidly as the input varies:

A table consisting of just (0, 1) would be the same as the identity mapping, whereas (1, 0) would invert the image. To flatten a section of the line, use the same value twice in succession: (1, 0.5, 0.5, 0) gives an inverted image where the details in the low and high values are preserved, but the middle third of numbers are all mapped to 127: As you can see, the input range is divided evenly based on the number of values in your table, and the line ramps smoothly between them. Sometimes, however, a smooth transition is the last thing you want. Suppose that you have to reduce the number of colors in an image (“posterizing”), or even reduce it down to a stark black-and-white version. For these cases there is the “Discrete” mode. With discrete mode you still provide a “table” of values, but rather than defining start and end points that will be interpolated between, you provide a list of the only output values that are allowed, and Inkscape will map them to sections of the input range. Provide only two numbers and any input value of 127 or less will be mapped to the first value, 128 or greater will be mapped to the second value. Instant monochrome! Provide four numbers and values from 0-63 will be mapped to the first, 64-127 to the second, and so on.

Except there's a bug in Inkscape that prevents it working correctly. In discrete mode the last value in your list is skipped – so if you provide two values expecting to get a monochrome output you'll find that every input value is mapped to the first number, and the second is never used. The workaround is obviously to provide three numbers (typically just duplicating the last one), but then the filter will not work correctly in other SVG programs or web browsers. The issue is tracked on Launchpad as bug #1046093, and a fix has been committed for the forthcoming 0.92 release of Inkscape, which is good – but it does also mean that if you provide an extra value to get the filter to work in 0.91, your image will look wrong when you upgrade to 0.92. For the examples below I've pretended that Inkscape works the way it should – just bear in mind that when I say (0, 1) you should actually use (0, 1, 1) to get it to work on the current release. Speaking of which, here is that monochrome output, using a discrete table containing (0, 1): This one uses values of (1, 0.75, 0.5, 0.25, 0) to posterize Mona down to five shades of gray, whilst inverting the output at the same time:

One thing you've undoubtedly noticed about all of the modes so far is that the graphs consist entirely of straight lines – either horizontal ones in the case of Discrete, or angled in the case of Table, Linear and Identity. The last option adds a bit of curvature to the graph, but don't get too excited; it doesn't allow you to draw an arbitrary Bézier curve, but rather just supply three parameters for a gamma correction curve. In case you're not familiar with gamma correction, it's a non-linear mapping of input to output values, which is used to adjust the brightness and contrast of an image to compensate for differences in perceived brightness at the ends of the range. Think of it as a more sophisticated option than just changing the slope and intercept using the Linear mode, because it allows lower values to change at a different rate than higher values. The Gamma mode takes three parameters: Amplitude, Exponent and Offset. The output value from the transfer function is calculated using the following formula: output = Amplitude × inputExponent + Offset

That is, the input value (which is in the range 0 to 1) is raised to the power of the Exponent value, multiplied by the Amplitude and added to the Offset. Often the Amplitude is left as 1, and the Offset as 0, so the output is simply the input raised to the power of the Exponent. For an Exponent of 2, therefore, the result looks something like this: To lighten an image simply use an exponent value of less than 1 – such as in this example with a value of 0.5. Notice the similarity to the Linear mode with slope values of 0.5 (to darken) and 2 (to lighten). Gamma mode often gives a more detailed result, particularly where there are subtle changes in the darker areas of the input range. Although I've used a grayscale image to illustrate this filter, in practice you can use a different transfer function for each color component, and also for the alpha channel – useful for leaving the alpha channel untouched in Identity mode whilst you alter the color channels, or alternatively for only affecting the alpha channel whilst the colors remain untouched.

To finish, therefore, here's a final image of Mona in all her colorful glory, with four different component transfers applied. The top left quarter has a Table (1, 0) applied to just the green channel, with the others left as Identity; the top right uses Table (0, 1, 0, 1, 0) on all the color channels; the bottom right uses Discrete (0, 0.25, 0.5, 0.75, 1) on the color channels to posterize the image, and the bottom left uses Table (1, 0) on all the channels to produce a “photographic negative” effect. 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

issue116/inkscape.1483431633.txt.gz · Dernière modification : 2017/01/03 09:20 de d52fr