본문 바로가기
React

react-img-mapper 그리고 html2canvas와 html-to-image, jsPDF [이미지 처리에 관하여]

by invelog 2024. 5. 14.
반응형

이 부분에 대해서는 쓸 내용이 많다.

단순히 이미지 처리에 대한 내용 뿐만 아니라 관련되어 있는 환경 설정 문제까지 다 엮여버리는 바람에 프로젝트 시작 후 손에 꼽을 정도로 힘든 작업이었다. 

 

일단! 내가 하려고 한 기능적인 부분은 특정 이미지가 있고 그 이미지에서 원하는 지점(Spot)에 표시를 하는 내용이었다. 

1차적으로 단순히 이미지만 띄우는게 아니고 interaction이 있기 때문에 img 태그가 아닌 해당 기능을 부분적으로라도 지원해주는 라이브러리를 사용하려 했고 조사할때 제일 눈에 많이 띄었던 react-image-mapper 를 사용하기로 했다.

처음엔 너무 간단했다.

import ImageMapper from "react-image-mapper";

<ImageMapper 
    key={clickCounter}
    src={anatomyImage}
    width={500}
    imgWidth={500}
    map={{
      name: 'anatomy-map',
      areas: generateAreas()
    }}
    onImageMouseMove={handleImageMapperMove}
    onImageClick={handleImageMapperClick}
/>

 

src만 크기만 맞춰주면 잘 뜬다. key값은 넣었었지만 그리드에서 row 값에 따라 이미지가 바뀌어야하는 경우가 있었는데 그때 key 값이 바뀌면서 이미지가 새로 그려져 마치 사라졌다 다시 뜨는 듯한 현상때문에 제거해주게 되었다.

map 속성에 generateAreas() Function은 내가 원하는 특정 Spot을 찍는 로직 부분이다. 자세히 보지 않아 잘 몰랐지만 react-image-mapper는 이미 4년전에 업데이트가 멈췄고 더 이상 관리되고 있지 않은거 같았다. 적용하다 보지 이곳 저곳에서 deprecated 된 부분들이 많았고 자잘한 에러들이 많았다. 

 

조금더 찾아보니 react-img-mapper 라는 라이브러리가 있었고 현재도 관리되고 있는 라이브러린데 내가 보기엔 react-image-mapper를 개선한 라이브러리 같다. 여튼 설치하고 import만 해주고 동일하게 작성했는데도 정상 동작하는걸 보니 아무래도 맞는듯

여기까지는!!! 순탄했다

 

이제 처리한 이미지를 포함한 데이터를 PDF로 출력시켜주는 부분이 필요했는데 처음엔 사용하려는 고객의 특성상 한글파일을 지원해줘야 할 것 같아 그렇게 처리하려 했으나 한글을 제어하기가 여간 까다로운게 아니더라. 한컴? 쪽에서도 그런식으로 개발자가 제어하는 것에 대해 엄청 예민하고 싫어하기도 하는듯.

 

그래서 많이들 사용하는 jsPDF 라이브러리를 사용하여 작업하였고 표는 jsPDF 내 autotable을 사용하여 작성했다. 이 부분에서는 크게 어려운 부분이 없었는데 이제 이 PDF에 아까 작업한 이미지를 떠서 넣어야했는데 많이들 짝으로 사용하는 html2canvas를 사용하여 html 요소를 캡처(?)해서 PDF에 넣는데 드디어 난관...

 

일단 base64 형태로 인코딩하여 해당 라이브러리에서 이미지 넣는 method - addImage에 파라미터로 넣어줘야했는데 아무리 해도 출력이 안되는 것이다. 무수한 시행착오 끝에 onload하는 Function 안에서 이미지를 로드하면서 넣어줘야 한다고 판단했고 그렇게 처리 하니 이미지는 들어갔는데 이거... 사용하지 못할정도로 이미지가 너무 저화질로 다운그레이드 된 것이다.

 

다시 원점... 어떻게든 제공해주는 property나 method로 화질을 좀 올릴 수 있는 방법이 있나 시도해봤지만 이미 디폴트로 제공하는 값들이 최고 화질 상태인데 그 모양이었다.

 

개인적인 판단으로는 라이브러리 자체에서 넣을때 이미지의 질을 떨어트리는 부분이 있다고 생각. 왜냐하면 해당 라이브러리의 깃헙 이슈에도 해당 글이 많이 존재했다. 이미지의 질이 너무 떨어져서 사용할 수 없다는 글들.

 

다시 구현할 생각으로 html-to-image라는 비교적 최신 라이브러리를 사용했고 구현방식은 거의 99% 동일해서 import만 변경해줘도 정상적으로 동작했다.역시나 이미지 질이 확 달라졌다 거의 화면에서 띄어져 있던 이미지와 동일한 상태로 PDF에 잘 들어갔다.

 

근데 또 html-to-image로 바꾸고 나니 프로젝트 자체에 걸려있던 webfont 관련 부분들이 cors에 걸리기 시작하면서 다 터지기 시작...

하... 이미지를 버리고 기존의 라이브러리를 사용하자니 너무 질이 떨어져서 사용할 수 없고 결국 이 문제를 해결하자고 결정하고는 http-proxy-middle 로 proxy 설정을 해줘봤지만 소용 없었고 index.html 파일에서 해당 파일 가져오는 부분을 주석처리 해봤지만 이런식의 접근은 아니라고 생각이 들기도 했고 해당 폰트를 안 받아오니 기본으로 쓰고 있는 폰트가 너무 별로!

 

나름대로의 아이디어! 해단 font 파일들을 CDN으로 받아오는게 아니라 프로젝트 내에 파일 생성해서 해당 CSS 내용들을 저장하고 index.html 에서는 로컬의 그 파일 경로를 잡아오면 cors에 걸리는 문제는 사라지겠다 판단했고 역시 그렇게 해보니 해결되었다. 하지만 이게 분명 정석적인 접근방법은 아닐거 같고 나름 나에게는 최선이라 판단해서 이렇게 처리하고 넘어가기로.

(왜냐하면 폰트 파일같은거는 크게 변경되거나 실시간으로 반영되어 업데이트 돼야 할 부분이 많지 않을 것이라 판단했기 때문)

 

무튼 이래저래 해결이 되었고 이미지 하나를 PDF에 넣어보자는 것이 이렇게까지 일이 커졌다. 어찌됐든 그 기능 부분이 상당히 이 프로젝트에서 중요한 부분이었고 깔끔하게 해결했다는 점에서는 만족!

 

나름대로 image와 PDF 다루는 방법은 습득을 한거 같아 혹시나 물어보면 아는 한도 내에서 성실하게 알려주겠음

 

 

 

 

반응형