SVG path 좌표 추출, d 속성 숫자 읽는 법

SVG 아이콘 하나를 Canvas나 게임 엔진, 애니메이션 라이브러리로 옮기려는데 <path> 태그 속 d="M10 10 L20 20 C..." 문자열이 암호처럼 보였다면, 답부터 말씀드리겠습니다. 그 문자열은 '명령어 글자 + 숫자 좌표'의 반복일 뿐입니다.

규칙만 알면 손으로도 좌표를 뽑아낼 수 있고, 이 변환기는 그 반복 규칙을 코드로 옮겨 JSON·포인트 리스트·CSV 세 형식으로 정리해 줍니다. 다만 결과를 잘못 읽기 쉬운 지점이 몇 군데 있어서, 계산 과정과 함께 그 부분까지 짚겠습니다.

요약d 속성은 M(이동)·L(직선)·C(곡선)·Z(닫기) 같은 명령어 글자와 그 뒤 숫자들로 좌표를 나타냅니다. ② 이 도구는 글자를 명령어로, 나머지 숫자를 2개씩 x·y로 묶어 JSON·포인트·CSV로 뽑습니다. ③ 대문자는 절대좌표·소문자는 상대좌표이고, C 곡선은 제어점까지 좌표로 함께 잡힙니다.

d 속성 하나가 통째로 넘어올 때

디자이너가 준 SVG 아이콘에서 <path d="..."> 한 줄만 복사해 왔다고 해 보겠습니다. 이걸 HTML <canvas>에 똑같이 그리거나, Three.js의 정점(vertex) 배열로 바꾸거나, 모션 라이브러리에 키프레임 좌표로 넣으려면 결국 필요한 건 숫자 좌표 목록입니다.

문제는 d 속성이 사람이 읽기 좋게 정리돼 있지 않다는 점입니다. M10,10L20,20C30,30 40,30 50,20Z처럼 공백이 들쭉날쭉하고 명령어와 숫자가 붙어 있어서, 어디까지가 한 좌표인지 눈으로 세기 어렵습니다.

게다가 아이콘 하나에 좌표가 수십·수백 개씩 들어 있는 경우가 흔합니다. 이걸 일일이 손으로 끊어 읽는 것이 이 글이 다루는 문제입니다.

먼저, 도구 없이 d 속성을 직접 읽는 법

d 속성은 문법이 단순합니다. 글자(명령어) 하나가 나오면 새 명령이 시작되고, 그 뒤에 붙은 숫자들이 그 명령의 값입니다. 명령어마다 필요한 숫자 개수가 정해져 있습니다.

  • M x y — 펜을 (x, y)로 이동 (선을 긋지 않고 시작점만 옮김)
  • L x y — 현재 점에서 (x, y)까지 직선
  • H x — 수평선 (x값 1개만)
  • V y — 수직선 (y값 1개만)
  • C x1 y1 x2 y2 x y — 3차 베지어 곡선 (제어점 2개 + 끝점)
  • Z — 시작점으로 되돌아가 경로를 닫음 (숫자 없음)

여기서 가장 중요한 규칙 하나. 대문자는 절대좌표, 소문자는 상대좌표입니다. L20 20은 "SVG 원점(왼쪽 위 0,0) 기준 (20,20)으로"라는 뜻이고, l20 20은 "현재 점에서 오른쪽으로 20, 아래로 20"이라는 뜻입니다. 글자만 다르고 숫자가 같아도 실제 위치는 완전히 달라집니다.

기본 예시 M10,10 L20,20 C30,30 40,30 50,20 Z를 손으로 읽어 보겠습니다.

  • M10,10 → 펜을 (10, 10)으로 이동
  • L20,20 → (10,10)에서 (20,20)까지 직선
  • C30,30 40,30 50,20 → 곡선. 제어점1 = (30,30), 제어점2 = (40,30), 끝점 = (50,20)
  • Z → 시작점 (10,10)으로 닫기

여기서 곡선이 실제로 지나는 점은 끝점 (50,20)뿐입니다. (30,30)과 (40,30)은 곡선을 휘게 만드는 '손잡이'일 뿐, 그림이 그 위를 지나가지는 않습니다. 이 구분이 뒤에서 결과를 읽을 때 핵심이 됩니다.

이렇게 명령어의 숫자 개수(M·L=2, H·V=1, C=6, Z=0)만 알면 어떤 d 속성이든 손으로 끊어 좌표를 뽑을 수 있습니다. 다만 좌표가 수백 개면 손으로 하기엔 지치고, 실수도 나옵니다.

저희 도구로 확인하기.

SVG Path에서 좌표 추출 및 배열 변환기

설치·로그인 없이 브라우저에서 실행되며, 입력한 d 속성을 서버로 보내지 않고 JSON·포인트·CSV로 변환합니다.

이 도구가 숫자를 뽑아내는 과정

이 변환기는 방금 손으로 한 작업을 그대로 코드로 합니다. 서버로 보내지 않고 브라우저 안에서 처리합니다. 순서는 이렇습니다.

1단계 — 명령어 단위로 자릅니다. 입력한 d 문자열을 '글자 1개 + 뒤따르는 숫자들' 덩어리로 쪼갭니다. 그래서 M10,10 L20,20 C... Z가 M 덩어리, L 덩어리, C 덩어리, Z 덩어리 네 개로 나뉩니다.

2단계 — 글자와 숫자를 분리합니다. 각 덩어리의 맨 앞 글자를 명령어로, 나머지 문자열을 공백·쉼표 기준으로 쪼개 숫자 배열로 바꿉니다. 이때 10-20처럼 음수가 붙어 있으면 앞에 공백을 넣어 10 -20으로 나눕니다.

3단계 — 고른 형식으로 출력합니다. 형식은 세 가지이고, '좌표 추출하기' 버튼을 눌러야 결과가 나옵니다. 입력만 바꿔서는 자동으로 갱신되지 않습니다.

JSON 구조화 — 명령어와 파라미터를 그대로 담습니다.

[
  { "command": "M", "parameters": [10, 10] },
  { "command": "L", "parameters": [20, 20] },
  { "command": "C", "parameters": [30, 30, 40, 30, 50, 20] },
  { "command": "Z", "parameters": [] }
]

X, Y 포인트 리스트 — 각 명령어의 숫자를 2개씩 묶어 좌표 쌍으로 평탄화합니다.

[
  { "x": 10, "y": 10, "cmd": "M" },
  { "x": 20, "y": 20, "cmd": "L" },
  { "x": 30, "y": 30, "cmd": "C" },
  { "x": 40, "y": 30, "cmd": "C" },
  { "x": 50, "y": 20, "cmd": "C" }
]

CSV TableCommand,X,Y 표로 뽑습니다.

Command,X,Y
M,10,10
L,20,20
C,30,30
C,40,30
C,50,20
Z,,

세 형식을 나란히 보면 규칙이 보입니다. JSON은 명령어별로 숫자를 통째로 보여주고, 포인트·CSV는 그 숫자를 무조건 2개씩 x·y로 짝짓습니다. 이 '2개씩 짝짓기'가 편리한 동시에, 아래에서 볼 혼동의 원인이기도 합니다.

결과를 읽을 때 흔히 헷갈리는 것들

첫째, 곡선의 제어점도 좌표로 함께 잡힙니다. 위 포인트 리스트에서 (30,30)·(40,30)·(50,20) 세 개가 모두 C 명령의 좌표로 나옵니다. 하지만 앞서 봤듯 그림이 실제로 지나는 점은 (50,20)뿐이고, 앞의 둘은 제어점입니다. 이걸 모두 '통과점'으로 쓰면 곡선이 아닌 엉뚱한 모양이 됩니다.

둘째, 숫자가 1개인 명령어는 칸이 어긋납니다. 도구는 숫자를 무조건 x부터 채우기 때문에, V80(수직선)의 80은 사실 y값인데도 CSV에서는 X칸에 들어가고 Y칸이 빕니다. 포인트 리스트에서는 짝이 없어 아예 빠집니다.

셋째, 대문자·소문자 구분은 그대로 넘어오지만 위치로 환산되지는 않습니다. 도구는 cmd에 원래 글자(M인지 m인지)를 보존하지만, 소문자(상대좌표)를 절대좌표로 계산해 주지는 않습니다. 소문자 명령의 숫자는 '이전 점으로부터의 이동량'이라는 점을 직접 감안해야 합니다.

명령어숫자 개수결과에서 보이는 모습
M / L2이동 / 직선x, y 한 쌍 그대로
H1 (x)수평선CSV는 X만 채우고 Y는 빈칸, 포인트 리스트엔 없음
V1 (y)수직선위와 같으나 값(y)이 X칸에 들어감
C6곡선제어점 2개 + 끝점, 세 쌍 모두 좌표로 잡힘
Z0닫기JSON은 빈 배열, CSV는 Z,, 빈 행, 포인트 리스트엔 없음

참고로 원호를 그리는 A(arc)는 숫자가 7개(반지름 2개, 회전각, 플래그 2개, 끝점 x·y)입니다. 이 도구는 이것도 2개씩 짝지으므로, 반지름이나 플래그가 좌표인 것처럼 섞여 나옵니다. AQ가 든 경로라면 숫자의 의미를 따로 확인해야 합니다.

좌표가 맞는지 직접 검증하는 법

뽑은 좌표가 맞는지 확신이 안 서면, 되돌려서 그림으로 대조하는 것이 가장 확실합니다. 방법은 두 가지입니다.

입력한 d를 그대로 그려 보기. 같은 문자열을 <svg><path d="..."/></svg>에 넣어 브라우저에서 열거나, path 시각화 도구에 붙여 넣으면 실제 모양이 나옵니다. 뽑아낸 끝점 좌표가 그림의 꼭짓점과 맞는지 눈으로 비교합니다.

좌표를 종이·그래프에 찍어 보기. 포인트 리스트의 x·y를 좌표평면에 찍되, SVG는 y축이 아래로 갈수록 커진다는 점을 기억해야 합니다. 왼쪽 위가 (0,0)이라, 수학 시간에 배운 좌표와 위아래가 뒤집혀 있습니다. 이걸 놓치면 "좌표는 맞는데 모양이 위아래로 뒤집혔다"는 착각을 하게 됩니다.

정리

  • d 속성은 '명령어 글자 + 숫자'의 반복입니다. 글자가 명령을 시작하고, 숫자 개수는 명령어마다 정해져 있습니다(M·L=2, H·V=1, C=6, Z=0).
  • 대문자는 절대좌표, 소문자는 상대좌표입니다. 이 도구는 글자를 보존만 하고 상대→절대 환산은 하지 않습니다.
  • 출력은 JSON(명령어별 숫자)·포인트 리스트·CSV(둘 다 2개씩 x·y) 세 가지이며, '좌표 추출하기' 버튼을 눌러야 나옵니다.
  • 숫자를 무조건 2개씩 짝짓기 때문에 C의 제어점까지 좌표로 잡히고, H·V·Z·A처럼 개수가 다른 명령은 칸이 어긋나거나 빠질 수 있습니다.
  • 확신이 안 서면 같은 d를 그림으로 그려 대조하되, SVG의 y축이 아래로 커진다는 점을 감안하세요.
SVG Path에서 좌표 추출 및 배열 변환기

설치·로그인 없이 브라우저에서 실행되며, 입력한 d 속성을 서버로 보내지 않고 JSON·포인트·CSV로 변환합니다.

자주 묻는 질문

곡선(C)의 제어점을 빼고 통과점만 얻을 수 있나요?

이 도구 자체는 걸러 주지 않습니다. C의 숫자 6개를 모두 2개씩 짝지어 세 좌표로 내보내기 때문에, 제어점 2개와 끝점 1개가 함께 나옵니다. 통과점만 필요하다면, 출력에서 각 C 명령의 마지막 쌍(끝점)만 골라 쓰면 됩니다. JSON 구조화 형식으로 뽑으면 명령어별로 묶여 있어 마지막 두 숫자를 집기 쉽습니다.

소문자 명령(상대좌표)이 섞여 있으면 어떻게 되나요?

숫자는 그대로 나오지만, 그 값은 '절대 위치'가 아니라 '이전 점으로부터의 이동량'입니다. 도구는 cmd 필드에 소문자를 그대로 보존할 뿐 절대좌표로 환산하지 않습니다. 절대 위치가 필요하면, 각 상대 좌표를 직전 점에 순서대로 더해 나가야 합니다.

입력한 d 속성이 서버로 전송되나요?

전송되지 않습니다. 파싱은 전부 브라우저 안에서 이뤄지며, 서버 통신이나 개인정보 수집이 없습니다. 그래서 로그인이나 설치 없이 바로 쓸 수 있습니다.

결과가 바뀌지 않아요.

d 문자열을 고친 뒤 '좌표 추출하기' 버튼을 다시 눌러야 합니다. 입력만 바꾸면 자동으로 갱신되지 않도록 되어 있습니다.

가격 보기카톡 무료 상담