Re: Proposal: feHSL element (was Re: [filter-effects] hue-rotate() and saturate() filters)

Hello Dirk,

Tuesday, October 15, 2013, 7:37:18 PM, you wrote:


> On Oct 15, 2013, at 6:02 PM, Chris Lilley <chris@w3.org> wrote:

>> Hello ,
>> 
>> 
>> Here is a proposal for a new feHSL element which performs hue rotation
>> and saturation changes without suffering from internal clipping. Due
>> to filter effects clipping after each primitive, saturation increases
>> will still suffer from clipping in a multi-stage pipeline.
>> 
>> I didn't provide for any operations on the L axis of HSL because
>> operations on lightness or luminance are already available by other
>> means.
>> 

> I wonder how the proposal solves the problem.

Apparently I didn't describe it well enough.

> The input is still RGB, the output is still RGB.

Correct

> It might differ between linearRGB or
> sRGB.

No; in either case (as stated in the proposal) you convert to sRGB
and thence to HSL.

> So you still have the clipping, no?

No.

OK, time for some 3D visualisation. Just close your eyes and
concentrate on the music. Ahem.

In the current matrix approach, you have colour arranged in a cube
(RGB) and all values outside the cube are clipped. The filter tilts
the cube so the lightness axis (black to white) is upright. It then
rotates the cube about that axis, *clipping to the boundary of the
original, tilted, unrotated cube*.

Visualize a sphere that is as big as it can be while still fitting in
the cube. When the cube is tilted, place a cylinder that is parallel
to the lightness axis and just fits over the sphere. Colours outside
that cylinder risk being clipped (depending on how large the rotation
angle is).

In the HSL approach, the colourspace is already a cylinder and all
in-gamut RGB colours fit in that cylinder. Hue rotation rotates the
cylinder on its axis; no part of the cylinder falls outside the
cylinder so hue rotation does not produce clipping. Saturation
decreases do not produce clipping (though, because of the nature of
HSL, you do get a reduction in hue precision). Saturation increases
can result in clipping (but the clipping is to the cylinder surface so
hue and lightness are not affected and the result is less visually
objectionable).

Hope that helped?

> Could you elaborate more
> please? Also, would the new element ignore the
> color-interpolation-filters property?

I covered that in the proposal. Perhaps too tersely?

If c-i-f is sRGB, the conversion going into the filter is sRGB -> HSL
and going out, HSL -> sRGB.

If c-i-f is linearRGB, the conversion going into the filter is
linearRGB -> sRGB -> HSL and going out, HSL -> sRGB -> linearRGB

If c-i-f is some other value (SVG2 adds other values to c-i, maybe add
them to c-i-f too?), the conversion going into the filter is
someothervalue ->sRGB -> HSL and going out, HSL -> sRGB -> someothervalue.

Of course, if the filter designer had set someothervalue to, say,
CIELCHab then they would more likely choose to do a different type of
hue rotate (directly on the H component of LCH) thus avoiding the
bunched up, uneven hue distribution of HSL, the non-independence of H
S and L in HSL, and the limited gamut of sRGB.

>> =================================================
>> 
>> Name:   feHSL
>> Categories:     Filter primitive element
>> Content model:  Any number of the following elements, in any order:
>> 
>>    <animate>
>>    <set>
>> 
>> Attributes:     
>> 
>>    core attributes — ‘id’, ‘xml:base’, ‘xml:lang’, ‘xml:space’
>>    presentation attributes — ‘alignment-baseline’, ‘baseline-shift’,
>>      ‘clip’, ‘clip-path’, ‘clip-rule’, ‘color’, ‘color-interpolation’,
>>      ‘color-interpolation-filters’, ‘color-profile’, ‘color-rendering’,
>>      ‘cursor’, ‘direction’, ‘display’, ‘dominant-baseline’,
>>      ‘enable-background’, ‘fill’, ‘fill-opacity’, ‘fill-rule’, ‘filter’,
>>      ‘flood-color’, ‘flood-opacity’, ‘font’, ‘font-family’, ‘font-size’,
>>      ‘font-size-adjust’, ‘font-stretch’, ‘font-style’, ‘font-variant’,
>>      ‘font-weight’, ‘glyph-orientation-horizontal’,
>>      ‘glyph-orientation-vertical’, ‘image-rendering’, ‘isolation’,
>>      ‘kerning’, ‘letter-spacing’, ‘lighting-color’, ‘marker’,
>>      ‘marker-end’, ‘marker-mid’, ‘marker-start’, ‘mask’, ‘mix-blend-mode’,
>>      ‘opacity’, ‘overflow’, ‘pointer-events’, ‘shape-rendering’,
>>      ‘stop-color’, ‘stop-opacity’, ‘stroke’, ‘stroke-dasharray’,
>>      ‘stroke-dashoffset’, ‘stroke-linecap’, ‘stroke-linejoin’,
>>      ‘stroke-miterlimit’, ‘stroke-opacity’, ‘stroke-width’, ‘text-anchor’,
>>      ‘text-decoration’, ‘text-rendering’, ‘unicode-bidi’, ‘visibility’,
>>      ‘word-spacing’, ‘writing-mode’
>>    filter primitive attributes — ‘x’, ‘y’, ‘width’, ‘height’, ‘result’
>>    ‘class’
>>    ‘style’
>>    ‘in’
>>    ‘type’
>>    ‘value’
>> 
>> DOM Interfaces:         SVGFEHSLElement
>> 
>> This filter applies a transformation in HSL colorspace. Input values
>> are converted (if needed) from the colorspace given by
>> 'color-interpolation-filters' to sRGB, and then to HSL for processing.
>> Results are converted from HSL to the colorspace given by
>> 'color-interpolation-filters'.
>> 
>> The calculations are performed on non-premultiplied color values.
>> 
>> Attribute definitions:
>> 
>> type = "hue" | "saturation"
>> Indicates the type of operation to be performed: hue rotation or
>> saturation/desaturation. The lacuna value for 'type' is "hue".
>> 
>> value = <number>
>> For type="hue", the value represents a hue rotation in degrees.
>> Positive and negative angles may be specified. The new hue angle H'
>> is given by
>> 
>> H' = (H + value) mod 360
>> 
>> For type="saturation", the value represents a saturation multiplier.
>> Values less than 1.0 represent desaturation; values greater than 1.0
>> represent increases in saturation.  A value of 0.0 results in full
>> desaturation to the L axis. The new saturation value S' is given by
>> 
>> S' = S * value
>> 
>> Note that results are clamped to the saturation range 0.0 ... 1.0
>> 
>> The lacuna value of 'value' depends on the value for 'type'. For
>> type="hue" the lacuna value for 'value' is 0.0 (no rotation); for
>> type="saturation" the lacuna value for 'value' is 1.0 (no change in
>> saturation).
>> 
>> =============================================================
>> 
>> Add an example or two and some suitable definition for the DOM
>> interface.
>> 
>> -- 
>> Best regards,
>> Chris                          mailto:chris@w3.org
>> 
>> 





-- 
Best regards,
 Chris                            mailto:chris@w3.org

Received on Wednesday, 16 October 2013 13:54:09 UTC