Линейная функция svg feComponentTransfer

Линейная функция SVG feComponentTransfer работает не так, как я ожидал. Наклон -1 и пересечение 1, применяемые к изображению в градациях серого, должны инвертировать изображение: черный -> белый, белый -> черный, 25% серого -> 75% серого, 50% серого без изменений и т. д.

Мои ожидания основаны на http://www.w3.org/TR/filter-effects/#feComponentTransferElement, в котором говорится, что «C' = наклон * C + точка пересечения», где «C — исходный компонент (например, 'feFuncR'), C' — переназначенный компонент; оба в замкнутом интервале [0, 1].".

Следующий фильтр

<filter id="linear">
  <feComponentTransfer>
    <feFuncR type="linear" slope="-1" intercept="1" />
    <feFuncG type="linear" slope="-1" intercept="1" />
    <feFuncB type="linear" slope="-1" intercept="1" />
  </feComponentTransfer>
</filter>

отображает черный в белый и белый в черный, но промежуточные значения отключены, например. 50 % серого соответствует 90 % серого, а 75 % серого соответствует 98 % серого. Простой пример см. на http://jsfiddle.net/Rpjs2/. Я получаю те же результаты в Firefox и Safari.

Это моя первая попытка использовать фильтры SVG, поэтому я подозреваю, что неправильно понимаю спецификации. Может ли кто-нибудь исправить меня?


person BobW    schedule 26.12.2012    source источник
comment
Посмотрите этот пример из исходного кода WebKit. Использование подобного фильтра инвертирует градиент (посмотрите на определения фильтров, так как текст, описывающий их, неверен), но не полностью. Кажется, что он немного смещен влево.   -  person seliopou    schedule 27.12.2012
comment
На самом деле он довольно сильно сдвинут влево, и это далеко не то, что можно было бы получить, применив -1*c+1. Моя первая мысль заключается в том, что это ошибка, поскольку она не соответствует спецификации w3, но странно, что Safari и Firefox реализовали ее одинаковым (очевидно, неправильным) способом. Я отправил отчеты об ошибках в Mozilla и WebKit и сообщу, если они сочтут это ошибкой.   -  person BobW    schedule 27.12.2012
comment
Вы вдохновили меня на документацию feComponentTransfer в документации по веб-платформе. Дайте мне знать, что вы думаете: docs.webplatform.org/wiki/svg/elements/feComponentTransfer   -  person Michael Mullany    schedule 31.12.2012
comment
@MichaelMullany Это выглядит очень полезно. Жаль, что я не видел его, когда работал над этим на прошлой неделе! (stackoverflow.com/questions/14043585/colorizing-grayscale-image иллюстрирует то, что я пытался сделать.)   -  person BobW    schedule 31.12.2012


Ответы (2)


Фильтры обычно работают в цветовом пространстве linearRGB. В этом варианте использования требуется sRGB, поэтому вам просто нужно установить color-interpolation-filters="sRGB" на фильтрующем элементе

person Robert Longson    schedule 27.12.2012
comment
Спасибо, я только что попробовал это. Он работает в Firefox и Chrome, но Safari игнорирует этот параметр. (Раздражает, что в выпускной сборке Safari используются более старые версии WebKit, чем Chrome. В Safari есть много ошибок SVG, которые были исправлены несколько месяцев назад в WebKit и не появляются в Chrome.) - person BobW; 27.12.2012

Вы можете в основном исправить это, используя перенос другого компонента после исходного.

  <feComponentTransfer>
    <feFuncR type="gamma" offset="0" amplitude="1" exponent="4.84"/>
    <feFuncG type="gamma" offset="0" amplitude="1" exponent="4.84"/>
    <feFuncB type="gamma" offset="0" amplitude="1" exponent="4.84"/>
  </feComponentTransfer>

Это позволит более правильно распределить цветовой диапазон, используя «двойную» гамма-коррекцию 2.2 ^ 2 = 4.84.

person Michael Mullany    schedule 31.12.2012