D3를 이용하여 svg에 데이터를 시각화 하고나면 그 결과를 공유해야 할 일이 생길 때가 있다. 가장 간단한 방법은 웹 사이트의 링크를 공유하는 것이지만, 때에 따라 문서에 첨부하거나 파일로 저장하여 공유해야 할 수도 있다. 보통 이러한 경우 캡처 프로그램을 사용하면 아주 간단하게 원하는 작업을 수행할 수 있으나, 이미지의 크기가 한 화면에 들어오지 않거나 저장해야 하는 이미지의 개수가 많으면 캡처 프로그램으로만으로는 한계가 있다. 따라서 이번 포스트에서는 d3로 만들어낸 svg 형태의 image를 우리에게 익숙한 png image로 출력하여 저장하는 방법을 정리하고자 한다.
이 작업을 위해서 구글링을 해보니 아래와 같은 링크를 발견할 수 있었다.
http://techslides.com/save-svg-as-an-image
svg를 png로 export 하는 방법에 대해 아주 잘 정리 되어 있었다. 그러나 위의 링크 만으로 모든게 해결 되었다면 이 post를 작성하지 않았을 것이다. 위의 링크에 제시된 예제 코드를 그대로 실행하면 아무런 오류 없이 원하는 결과를 얻을 수 있었다. 그래서 작업 중이었던 코드에 삽입해서 image로 추출하는 것을 시도해보았으나 에러가 발생했다. 이럴 때마다 느끼는 거지만 정말 코딩 할 때 딱 한번에 잘 되는 경우가 잘 없다. 에러는 파이썬에서도 날 정말 많이 괴롭혔던 '인코딩'이 원인이었다. 아래의 코드에서 8번 째 줄이 에러를 발생 시키는 부분이다
Blob 이라는 자료형을 사용하는 방법이다. Blob에 대해서는 정확히 모르겠지만 utf-8 로 주소를 편하게 읽어올 수 있다는 것이 장점인 듯 하다. url을 utf-8 형식 그대로 읽고 나서 그 후의 방식은 가장 위에 첨부했던 링크에 나와 있는 방법과 거의 흡사하다. script에 이 code를 작성하기 전에 html의 body 부분에 두 개의 준비물이 필요한데 하나는 일반적인 <div> 이고 나머지 하나는 <canvas>이다. 코드의 진행과정은 다음과 같다. button을 클릭하면 svg를 미리 만들어둔 <div>에 image로 변환해 놓고 <canvas>에서 이 image를 읽어와서 파일의 형태로 만들어서 저장할 수 있게 한다. 이 때, <div>의 style을 display: none으로 해주어야 화면에는 아무런 변화가 없이 깔끔하게 추출만 할 수 있다.
마지막 37번 째 줄처럼 context를 clear해주지 않으면 데이터 변화에 따른 시각화의 변화가 갱신되지 않고 누적되기 때문에 꼭 저렇게 clear를 해주어야 한다.
인코딩 문제를 해결하고 그림을 추출하는 것까지는 성공했으나.. style sheet 정보까지 image에 포함시켜 추출시키는 것은 여전히 모르겠다. 즉, script 안에서 여러 가지 method로 선언해준 것들은 image에 포함이 되나 style 부분에서 지정해준 것은 전혀 반영이 되지 않는다. 이 문제까지 해결하면 svg의 image 파일 추출은 거의 온전하게 할 수 있을 것 같은데 쉽지가 않다.