SVG "Filter" 에 대한 정리 - 3

조경석·2023년 2월 12일
1
post-thumbnail

썸네일 출처 : https://www.oxxostudio.tw/articles/201407/svg-15-filter-feComponentTransfer.html

<feComponentTransfer>

가장 많이 쓰이고, 가장 복잡한 <feComponentTransfer>에 대해 알아보자.

이름에서는 용도를 추측하기 어렵지만, 필터 영역에 대한 색상 구성 요소(Component)를 재매핑하는 역할을 수행한다.
색조, 채도, 밝기 변경부터 색조화(Color Balance)임계처리(Thresholding)같은 포토샵에서 볼 법한 조정, 처리가 가능한 강력한 기능을 자랑한다.

Red, Green, Blue, Alpha의 모든 채널을 참조, 조정할 수 있으며 이를 위해 <feFuncR>, <feFuncB>, <feFuncG> 그리고 <feFuncA>의 하위 요소를 가질 수 있다.

<feFuncR, G, B, A>

<feFuncR>, <feFuncB>, <feFuncG> 그리고 <feFuncA>는 픽셀별 색상 채널을 전달하기 위한 함수 요소이다.
주요 특성으로 type을 가지며, type의 값에 의해 색상 전달 함수 요소로서의 성질이 결정된다.

픽셀별 해당 채널의 색상값 C를 기준으로 아래 특성값에 의해 값이 조정된다.
아래에서는 이해하기 쉽도록 색상값, 결과값 C는 0부터 255 사이의 값이라고 생각하고 설명하겠다.

type="identity"

identity 타입은 말 그대로 원래 type이 적용된 feFunc 색상값 C를 그대로 전달한다.
별도로 type을 설정하지 않은 경우 지정되는 기본값이다.

type="table"

feFunc에 같이 지정된 tableValues 특성에 지정된 값의 배열을 통해 함수를 정의한다.

tableValues는 반드시 공백으로 구분한 0부터 1 사이의 2개 이상의 값을 지정해야 하며, 이 값의 갯수 - 1개 만큼의 칸으로 균등한 간격으로 색상값을 분할한 색상표(table)가 설정된다.

예를 들어, tableValues="1 .25 0"인 경우 값이 3개이므로,
색상값 0부터 255의 범위를 2개의 칸으로 분할한다.
[0 ~ 127]과 [128 ~ 255]인 균등한 간격의 두 칸으로 분할되며,
각 칸의 범위에 맞춰 tableValues에 지정한 색상의 상대 위치로 매핑된다.
기존 [0 ~ 127]의 범위에 [255 64]의 범위가 매핑되고, (256 * 1, 256 * 0.25)
기존 [128 ~ 255]의 범위에 [64 0]의 범위가 매핑된다. (256 * 0.25, 256 * 0)

글로 써놓으면 당연히 이해가 가지 않는 법, 아래 참고용 이미지를 보자.

화살표를 통해 입력 색상값이 리매핑되는 패턴을 표시해두었다.
위에서 볼 수 있듯이, 원래 색상값의 상대 위치를 기준으로 새로운 색상표의 상대 위치로 리매핑된다.
이 예제에서는 쉽게 이해할 수 있도록 tableValues을 내림차순의 0 ~ 1 사이의 숫자를 사용했지만, 실제로는 연속된 숫자를 사용해야 할 필요는 없다.

아래 이미지는 간단한 예시로, 윗 줄의 사각형 네개가 원래 색상이고, 아래 줄의 네 사각형이 아래의 필터가 적용된 도형이다.

<filter id="feComponentTransferRedTable" x="0" y="0" width="100%" height="100%">
	<feComponentTransfer>
    	<feFuncR type="table" tableValues="1 0"/>
	</feComponentTransfer>
</filter>

<feFuncR>만 type="table"로 지정되었고, tableValues는 "1 0"이다.
위에서 확인했던 참고용 이미지를 보면, tableValues가 "1 0"이므로 단순하게 색상값 C가 뒤집힌다고 생각할 수 있다.

원래 빨간색이 255였던 첫번째 사각형은 빨간색이 0이 되어 검은색이 되었고,
빨간색이 0이었던 두번째, 세번째 사각형은 기존 색상에 빨간색 255가 추가되어 각각 노랑(255, 255, 0), 마젠타(255, 0, 255)가 되었다.
마지막으로, 모든 색상이 0이었던 마지막 사각형 역시 빨간색 255가 추가된 것을 이해할 수 있다.

실제로는 각각 (254, 254, 61), (255, 0, 249)로 약간의 오차가 있는데, SVG에서 기본값으로 사용하는 linearRGB 색상 공간의 한계이다.
SVG에 color-interpolation-filters="sRGB"를 지정하면 아래와 같이 약간 다른 결과가 나오지만, 절대로 255 색으로 리매핑된 결과가 나오지는 않는다.

type="discrete"

discrete는 한국어로 '불연속형'으로 번역되며, 뜻 자체는 '별개의, 분리된'으로 separate와 유사한 의미를 가지는 단어다.
type="table"과 마찬가지로, feFunc에 같이 지정된 tableValues 특성에 지정된 값의 배열을 통해 함수를 정의한다.

tableValues는 공백으로 구분한 0부터 1 사이의 1개 이상의 값을 지정해야 하며, 이 값의 갯수 만큼의 칸으로 균등한 간격으로 색상값을 분할한다.
상대 위치를 기준으로 리매핑하던 type="table"과 달리, type="discrete"는 tableValues에 지정한 값으로 고정해버린다.

예를 들어, tableValues=".5 .25 1 0"인 경우 값이 4개이므로,
색상값 0부터 255의 범위를 4개의 칸으로 분할한다.
[0 ~ 63], [64 ~ 127], [128 ~ 191], [192 ~ 255]인 균등한 간격의 네 칸으로 분할되며,
각 칸의 범위의 색상은 해당하는 칸의 tableValues에 지정한 색상이 매핑된다.
기존 [0 ~ 63]의 범위에 127(256 * 0.5),
기존 [64 ~ 127]의 범위에 64(256 * 0.25),
기존 [128 ~ 191]의 범위에 255(256 * 1),
기존 [192 ~ 255]의 범위에 0(256 * 0)이 매핑된다.

화살표를 통해 입력 색상값이 리매핑되는 패턴을 표시해두었다.
위에서 볼 수 있듯이, 원래 색상값의 상대 위치에 상관없이 새로운 색상표의 고정 위치로 리매핑된다.

아래 이미지는 간단한 예시로, 윗 줄의 사각형 네개는 각각 빨간색을 100%, 75%, 25%, 0%만 적용한 원래 도형이고,
아래 줄의 네 사각형이 아래의 필터가 적용된 도형이다.

<filter id="feComponentTransferRedDiscrete" x="0" y="0" width="100%" height="100%">
	<feComponentTransfer>
		<feFuncR type="discrete" tableValues="1 0"/>
	</feComponentTransfer>
</filter>

<feFuncR>만 type="discrete"로 지정되었고, tableValues는 "1 0"이다.
기존 색상의 [0% 50%] 범위는 1, [50% 100%] 범위는 0으로 리매핑된다.

원래 빨간색이 100%였던 첫번째 사각형과 75%인 두번째 사각형은 빨간색이 0이 되어 검은색이 되었고,
빨간색이 25%였던 세번째 사각형과 0%인 네번째 사각형이 빨간색이 1이 되어 빨간색이 된 것을 볼 수 있다.

type="linear"

선형인 linear는 말그대로 기준 색상을 선형적으로 변형시킨다.

slope와 intercept를 특성값으로 가질 수 있으며, 단순하게 아래 계산식을 기준으로 색상을 리매핑한다.

결과값 = (slope * 기존값) + intercept

type="gamma"

gamma는 기준 색상을 지수적으로 변형시킨다. 지수 곡선을 조정하는 포토샵의 커브와 유사한 결과를 보여준다.

amplitude와 exponent, offset을 특성값으로 가질 수 있으며, 아래 계산식을 기준으로 색상을 리매핑한다.

결과값 = amplitude * 기존값^exponent + offset

2개의 댓글

comment-user-thumbnail
2023년 4월 26일

SVG 필터에 어떤 게 있는지 궁금해서 찾아보는 중인데 정리가 무척 잘 되어있네요! 좋은 글 감사합니다 👍

1개의 답글