사용한 라이브러리
- html2canvas
- canvasElement 반환.
- htmlToImage
- base 64 img url 반환.
결론 :
- 외부 url 링크가 존재하고 ios 대응을 해야 한다면 html2canvas를,
- 웹만 대응하는 등 그 외의 경우엔 htmlToImage를 추천함.
👇 결론에 이르기까지의 과정 👇
htmlToImage를 사용한 이유
- html2canvas에 비해 적은 용량과 제로 디펜던시.

- CSS가 깨지지 않음.
- toPng, toJpeg 등 직관적인 사용 방법 (개인적으로 option들도 더 사용하기 쉬웠음).
- html2canvas보다 최근에 업데이트 됨.

라이브러리에 사용된 문법 정리
dom을 이미지화시킨 핵심 문법에 대해 알아보자.
- HTML <canvas> 태그
- 주로 자바스크립트와 같은 스크립트를 이용하여 그래픽 콘텐츠를 그릴 때 사용함.
- src, alt 속성이 없다는 점만 제외하면 img 태그처럼 보임. 실제로 canvas에는 width, height 두 속성만 있음. default 값은 300px * 150px임.
<canvas id="myCanvas" style="border: 2px solid black"> 이 문장은 사용자의 웹 브라우저가 canvas 요소를 지원하지 않을 때 나타납니다! </canvas> <script> var canvas = document.getElementById("myCanvas"); var context = canvas.getContext("2d"); context.fillStyle = "yellow"; context.fillRect(0,0,150,100); </script>
- getContext()
- 캔버스는 처음에 비어있기 때문에 무언가를 표시하기 위해서, 어떤 스크립트가 랜더링 컨텍스트에 접근하여 그리야 함.
getContext()
메소드는 캔버스의 드로잉 컨텍스트를 반환함.- 파라미터는
contextType
을 받음. 2d를 넣었을 때 2차원 렌더링 컨텍스트를 나타내는CanvasRenderingContext2D
객체를 생성함.
- drawImage()
- Canvas 2D API의 drawImage() 메서드는 캔버스에 이미지를 그리는 다양한 방법을 제공함.
drawImage(image, dx, dy)
- toDataURL()
- 지정된 형식으로 이미지를 나타내는 데이터 URL을 반환함.
- 원하는 파일 형식과 이미지 품질을 지정할 수 있음.
cross platform 대응
👇 간단한 프로젝트로 테스트해봄. readme 참고.
이미지가 없으면 크게 상관없음. 근데 이미지가 있으면 얘기가 달라짐.
Chrome
- 정상 동작함.
Safari
- htmlToImage를 사용했을 때 2가지 문제가 생김.
- 이미지가 나오지 않음.
- 폰트 깨짐.

- 해결 방법 요약
- toJpeg를 사용하자.
- 해당 메서드를 두 번 사용하자.
- 해결 과정
- 우선 toPng에서 toJpeg로 변경. png는 성격 상 많은 옵션들을 담고 있기에 뭔가 깨지는 게 생기나봄. mdn에도 png를 지원하려면 많은 것들이 필요하다 나와있음.
- 하지만 jpeg로 저장해도 폰트는 깨지지 않지만 이미지는 여전히 나오지 않음.
- 한 가지 알아야 할 점이 htmlToImage는 domToImage라는 라이브러리를 근간으로 하는데 domToImage가 사파리 지원을 안함.
- 이 때 domToImage에서 지원하는 메서드를 두 번 실행하면 이미지가 제대로 렌더링됨.
- safari 첫 번째 렌더링에서 이미지를 누락시키는 것으로 추정.

export const quizResultToImage = async ({ target, bgColor = "#000000", }: Props) => { await toJpeg(target, { backgroundColor: bgColor }); // 1 return await toJpeg(target, { backgroundColor: bgColor }); // 2 };

IOS
ios에는 두 가지 문제가 있음.


- 이미지 안보임 (htmlToImage 동일).
- 왜 htmlToImage에서 이미지가 보이지 않을까?
- 심지어 아이패드에서는 문제가 없었던 레이아웃까지 말썽부림.
- 이미지 저장 시 바로 저장되는 게 아닌 크롬에 저장 후 크롬 저장 페이지에서 별도로 저장해야 함.
- html을 이미지로 만들어서 팝업창에 띄우고 이를 꾹 눌러 저장시키는 방법으로 대체.
- ios에서는 다운받은 이미지를 바로 갤러리에 저장하지 못하게 함.
깃허브 레포에서 나타내는 바와 같이, 결국 htmlToImage는 ios에서 이미지를 렌더링하지 않기 때문에 html2canvas를 이용함. 그리고 깨지는 css에 대해 주먹구구식으로 스타일을 수정함.
맞는 방법일까.. 🤔
그 외 에러 )
구글 폰트 사용시 cssRules를 어긋난다는 경고
SecurityError: Failed to read the 'cssRules' property from 'CSSStyleSheet': Cannot access rules
해결
구글 폰트 사용한 link에
crossorigin="anonymous"
으로 설정해줘야 함.<link href="https://fonts.googleapis.com/css?family=Abril+Fatface&display=swap" rel="stylesheet" crossorigin="anonymous">
기타 ) 한글로 저장시키면 폰트가 깨지지 않을까?
- 깨지는 케이스 발견하지 못함.
참고 자료