SVG feMorphology: 새 경로 없이 외곽선 추가하기
feMorphology로 SourceAlpha에서 SVG 외곽선을 만들어 보세요. 원래 경로 도형을 유지하면서 팽창, 침식, 구멍과 서로 다른 축 반지름을 비교합니다.
목차
여러 색으로 구성된 SVG 실루엣 전체에 외곽선을 추가하려면 SourceAlpha를 팽창시키고, 커진 결과에서 원래 알파를 제거한 뒤, 남은 고리에 색을 입히고 원본 그림을 위에 병합하세요. 필터는 렌더링 모양을 바꾸지만 원래 경로 데이터는 그대로 유지됩니다.
더 작은 알파 실루엣이 필요하면 operator="erode"를 사용하세요. 어느 연산도 편집 가능한 오프셋 경로를 만들지는 않습니다. 형태학 연산은 원형 스트로크 오프셋 대신 사각형 이웃 영역을 사용하므로 구멍, 좁은 간격과 날카로운 모서리는 시각적으로 확인해야 합니다.
색상 채널보다 실루엣에서 시작하기
W3C Filter Effects 명세는 팽창을 사각형 이웃 영역 내 성분별 최댓값, 침식을 최솟값으로 정의합니다. SourceAlpha를 사용하면 입력은 그림의 알파 채널입니다. 따라서 청록색과 산호색 색상 채널을 따로 키우지 않고 실루엣을 얻을 수 있습니다.
이 예제는 두 경로로 구성된 그림 전체에 필터를 적용합니다. 투명한 정사각형 구멍도 알파 실루엣에 포함됩니다. 산호색 안쪽 영역은 이미 불투명한 청록색 영역 안에 있으므로 별도의 외부 경계를 만들지 않습니다.
SVG를 직접 작성하고 다섯 가지 독립 실행형 변형 파일을 브라우저에서 열었습니다. 모든 파일은 동일한 두 원본 경로 정의를 유지합니다. 아래 비교는 해당 파일을 실제로 렌더링한 결과이며, 추적한 그림이나 생성된 효과 미리보기가 아닙니다.

반지름이 10이면 외곽선이 보이는 실루엣 바깥과 구멍 안으로 커집니다. 22이면 금색이 이 예제의 정사각형 구멍을 채웁니다. 18 4 버전은 세로보다 가로로 더 많이 커집니다. 침식은 불투명한 바깥 영역을 줄이고 투명한 구멍을 키우며, 아래쪽 끝점도 바꿉니다.
이 관찰은 해당 그림과 설정에만 해당합니다. 다른 로고나 아이콘에도 적용되는 일반적인 안전 반지름 규칙은 아닙니다.
바깥쪽 알파 고리 만들기
다음 완전한 예제를 outline.svg로 저장하고 브라우저에서 여세요. 캡처에 사용한 반지름 10의 SVG와 정확히 같습니다.
<svg xmlns="http://www.w3.org/2000/svg" width="300" height="220" viewBox="0 0 300 220">
<defs>
<g id="artwork">
<path fill="#173b40" fill-rule="evenodd"
d="M50 60H250V170H170L150 195L130 170H50Z M105 90H145V130H105Z"/>
<path fill="#f28567" d="M175 90H220V140H175Z"/>
</g>
<filter id="outline" filterUnits="userSpaceOnUse"
primitiveUnits="userSpaceOnUse" x="0" y="0" width="300" height="220">
<feMorphology in="SourceAlpha" operator="dilate" radius="10" result="grown"/>
<feComposite in="grown" in2="SourceAlpha" operator="out" result="ring"/>
<feFlood flood-color="#e4b84c" result="paint"/>
<feComposite in="paint" in2="ring" operator="in" result="coloredRing"/>
<feMerge>
<feMergeNode in="coloredRing"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<use href="#artwork" filter="url(#outline)"/>
</svg>필터는 네 단계로 동작합니다.
feMorphology가SourceAlpha를 팽창시켜grown을 만듭니다.feComposite가 원래 알파 바깥의grown만 남겨ring을 만듭니다.feFlood가 금색을 제공하고, 또 다른 합성 연산이 이 색을 고리 안으로 제한합니다.feMerge가 원래SourceGraphic을 색칠한 고리 위에 놓습니다.
빼기 연산에서는 입력 순서가 중요합니다. 명세의 합성 절은 in을 소스, in2를 대상에 대응시킵니다. 여기서는 in="grown", in2="SourceAlpha", operator="out"으로 팽창한 알파에서 원래 불투명 영역을 제거합니다. 입력을 반대로 하면 이 바깥 고리가 만들어지지 않습니다.
여기서 바깥은 불투명한 알파 영역 밖을 뜻하며 투명한 구멍 내부 공간도 포함합니다. 외곽선이 내부 구멍에 들어가지 않아야 한다면 이 필터가 자동으로 그 차이를 구분해 주지는 않습니다. 별도의 실루엣이나 의도한 외부를 정의하는 다른 구성이 필요합니다.
수정하지 않은 SourceGraphic을 마지막에 병합하므로 원본 색상이 보입니다. 이는 일반적인 경로 스트로크와는 별개입니다. 중앙 정렬, 내부 클리핑 또는 외부 마스킹 스트로크는 SVG 스트로크 정렬을 참고하세요. 페인트 순서는 더 단순한 스트로크·채우기 레이어 사례를 설명합니다.
알파를 침식하고 남은 색상 유지하기
외곽선 필터를 다음 정의로 바꾸고 최종 적용 부분을 filter="url(#erode)"로 변경하세요.
<filter id="erode" filterUnits="userSpaceOnUse"
primitiveUnits="userSpaceOnUse" x="0" y="0" width="300" height="220">
<feMorphology in="SourceAlpha" operator="erode" radius="10" result="shrunken"/>
<feComposite in="SourceGraphic" in2="shrunken" operator="in"/>
</filter>이 합성은 침식한 알파가 남아 있는 곳에만 원본 그림을 유지합니다. 전체 원본을 다시 위에 병합하면 의도한 얇아짐이 가려지므로 그렇게 하지 않습니다. 이 예제에서는 바깥 청록색 영역이 작아지지만 그 안의 산호색 영역은 남습니다.
실행할 예제에서는 연산자를 명시하세요. operator 참고 문서는 feMorphology의 erode, dilate와 feComposite의 in, out을 구분합니다. 같은 속성 이름이 두 요소에서 서로 다른 역할을 합니다. 형태학 연산의 기본 연산자는 erode이므로 생략하면 의도한 팽창과 반대되는 효과를 얻기 쉽습니다.
반지름 단위와 필터 영역 구분하기
radius 참고 문서는 숫자 하나 또는 두 개를 받습니다. 하나면 두 축에 모두 적용하며, 두 개면 첫 번째는 x 반지름, 두 번째는 y 반지름입니다. 추가 외곽선 두 상태를 만들려면 완전한 예제에서 radius="10"만 radius="22" 또는 radius="18 4"로 바꾸세요.
이 반지름은 primitiveUnits로 선택한 좌표계의 값이며, 모든 표시 크기에서 고정 CSS 픽셀 테두리를 보장하지 않습니다. 여기서는 0 0 300 220 viewBox와 함께 primitiveUnits="userSpaceOnUse"를 명시합니다. 표시되는 SVG 크기를 바꾸면 그림과 함께 효과의 크기도 바뀝니다.
이름이 비슷한 두 속성은 서로 다른 항목을 제어합니다.
| 속성 | 제어 대상 | 예제 설정 |
|---|---|---|
| primitiveUnits | 형태학 반지름을 포함한 프리미티브 내부 길이 값 | userSpaceOnUse |
| filterUnits | 필터 영역의 x, y, width, height | userSpaceOnUse |
| 루트 viewBox | SVG 뷰포트에 매핑하는 사용자 좌표 사각형 | 0 0 300 220 |
MDN primitiveUnits 참고 문서는 프리미티브 좌표계를 설명합니다. filterUnits 참고 문서는 바깥 영역을 별도로 설명합니다. filterUnits 기본값은 objectBoundingBox이고 primitiveUnits 기본값은 userSpaceOnUse입니다. 둘 다 명시하면 예제를 확인하기 쉽습니다.
원본은 x=50부터 250, y=60부터 195까지 차지합니다. 테스트한 동일 축 반지름의 최댓값은 22이며, 300 × 220 필터 영역과 뷰포트에는 그 결과를 담을 공간이 있습니다. 그림이나 반지름을 바꿀 때 두 경계를 다시 확인하세요. 명세는 필터 영역을 확정적인 클리핑 경계로 설명합니다. 반지름을 키워도 이 영역 밖에는 그릴 수 없습니다. SVG 필터와 뷰포트 클리핑 가이드는 이 두 가지 제한을 따로 보여 줍니다.
필터가 작동하지 않는 것 같다면 radius도 확인하세요. 기본값은 0이며, 참고 문서는 음수나 0이 프리미티브의 효과를 비활성화한다고 설명합니다. 위 예제는 두 축 모두 양수를 명시합니다.
전달 전에 구멍과 모서리 확인하기
형태학 연산의 사각형 이웃 영역 때문에 일반적인 둥근 외곽선과 모양이 다릅니다. x와 y 반지름이 같아도 이웃 영역이 원이 되지는 않습니다. 비교 이미지의 계단 모양 아래쪽 끝은 이 차이를 확인하기 좋은 부분입니다.
| 결과 | 사용 전 확인 사항 |
|---|---|
| 더 큰 바깥 외곽선 | 구멍과 인접한 모양이 시각적으로 이어질 수 있음 |
| 침식한 실루엣 | 얇은 부분이 사라지고 구멍이 커질 수 있음 |
| 축별 반지름 차이 | 가로와 세로 증가량이 의도적으로 다름 |
| 올바른 브라우저 미리보기 | 실제로 받을 편집기나 내보내기 도구에서도 따로 테스트해야 함 |
| 편집 가능한 도형 외곽선이 필요함 | 실시간 필터 결과는 원본의 새 윤곽선이 아님 |
다섯 파일 모두 여전히 동일한 d 속성의 원본 경로 두 개를 포함하는지 확인했습니다. 필터 정의는 다르지만 원본 도형은 같습니다. 편집, 오프셋 또는 제작에 사용할 경로가 필요하면 실제 SVG 객체를 확인하세요. 그 요구에는 편집기의 도형 연산을 사용하고 생성된 윤곽선을 확인해야 합니다. 이 필터를 바꾸거나 제거하는 것만으로는 그런 윤곽선이 생기지 않습니다.
필터 없는 원본과 별도의 전달용 사본을 보관하세요. 전달 파일을 실제 대상에서 열고 모서리, 내부 구멍, 색상과 경계를 비교하세요. 이 브라우저 예제가 특정 디자인 앱, 내보내기 도구 또는 커터의 지원 여부를 입증하지는 않습니다.
효과를 추가하기 전에 원본 준비하기
시작할 그림이 PNG나 JPG로만 있다면 PerfectVector가 도움이 될 수 있습니다. SVG 후보를 준비한 뒤 필터를 적용하기 전에 복원된 원본 실루엣, 작은 구멍과 색상 경계를 확인하세요. 형태학 외곽선은 의도한 도형을 고쳐 주기보다 실루엣의 문제를 더 크게 드러냅니다.
벡터 원본이 있다면 그대로 사용하세요. 단순한 기호는 직접 다시 그리는 편이 제어하기 쉬울 수 있습니다. 외곽선 효과가 합쳐진 평면 이미지를 추적해도 원래 필터 설정을 복원하거나 어느 부분이 필터 없는 모양이었는지 확정할 수 없습니다. 이미지 벡터화 개요는 이러한 재구성의 한계를 설명합니다.
FAQ
feMorphology는 편집 가능한 외곽선 경로를 만드나요? 아닙니다. 렌더링되는 필터 결과를 바꿉니다. 이 예제는 동일한 원본 경로 두 개를 유지하므로, 별도 윤곽선이 필요한 대상에는 도형 연산과 가져오기 확인이 필요합니다.
금색 외곽선이 SVG의 구멍을 채우는 이유는 무엇인가요? 고리는 불투명한 알파 밖으로 커지며 투명한 구멍 안에도 들어갑니다. 이 예제에서는 반지름 22가 정사각형 구멍을 채웁니다. 다른 그림에서는 간격과 반지름을 별도로 확인해야 합니다.
SourceGraphic 대신 SourceAlpha를 사용하는 이유는 무엇인가요? SourceAlpha는 각 원본 색상 채널을 팽창시키지 않고 실루엣에 연산하도록 합니다. 예제에서는 알파 고리에 따로 색을 입히고 SourceGraphic을 마지막에 병합해 원본 색상을 보여 줍니다.
Sources
- W3C — Filter Effects Level 1 — 형태학 연산의 사각형 이웃 영역, 합성 입력과 필터 영역 클리핑을 정의합니다.
- MDN — radius — 반지름 값 하나·두 개의 문법, 단위와 효과를 비활성화하는 값을 정의합니다.
- MDN — operator — 형태학 연산과 합성 연산을 구분합니다.
- MDN — primitiveUnits — 형태학 반지름의 좌표계를 정합니다.
- MDN — filterUnits — 바깥 필터 영역의 좌표계를 정합니다.
원본이 래스터뿐이라면 PerfectVector로 벡터 그림을 준비하고 필터 없는 실루엣과 구멍을 검증하세요. 그런 다음 외곽선을 추가하고 최종 파일을 실제로 받을 뷰어에서 비교하세요.

