반응형

html2canvas를 이용해서 특정영역을 캡쳐했다면 이것을 서버에 이미지 파일로 저장을 하고 이를 활용해야 할 수 있습니다. 필자는 이렇게 하기위해 html상에서 ajax를 사용해서 html2canvas로 만들어진 스샷을 base64포맷으로 django의 views에 있는 함수로 요청을 보냈고 django에서는 python의 base64라는 모듈을 사용해 이미지 바이너리 코드로 디코딩해서 파일에 쓰고 저장을 하였습니다.

Screen Shot 2020-01-14 at 7 43 36 PM
> base64란?
64개의 char(A-Z,a-z,0-9,/,+,=(padding))를 사용해서 binary data를 text로 변환을 하는 것이다. 즉, 64진법으로 바이너리데이터를 문자열로 바꾸는 것이다. 하지만 이미지나 오디오를 base64로 encoding을 하면 데이터의 양이 대략 33%가 증가한다고 한다. 그러나 이메일이나 Html에서 이러한 이미지나 오디오를 ASCII로 인코딩하여 전송을 하면 7bits로 인코딩을 하여 나머지 1bit 처리 방식이 시스템별로 상이한 문제, 일부 제어문자가 시스템 벼롤 다른 코드값을 갖는 문제때문에 안전하지 않다고 한다. 따라서 웹상에서 안전하게 바이너리 데이터를 전송하기위해서는 base64를 사용한다고 한다.

html2canvas를 사용해 스샷을 base64로 만들기

<script src="https://code.jquery.com/jquery-2.2.1.min.js"></script>
<script src="http://html2canvas.hertzen.com/dist/html2canvas.js"></script>

<script>
$(function(){
  $("#save").click(function() { 
    html2canvas($('#screenshot').get(0)).then( function (canvas) {
      var data = canvas.toDataURL();
      console.log(data)
      // data:image/png;base64,iVBORw0KGgoAAAANSUhE.....
    });
  });
});
</script>

toDataURL()을 사용하면 캡쳐된 것이 base64로 인코딩 되어 반환이 된다.

log를 통해 확인을 해보면 data:image/png;base64, iV...(이하생략)과 같이 base64로 인코딩이 된 것을 확인할 수 있다.

ajax통신을 통해 views로 data보내기

<script>
$(function(){
  $("#save").click(function() { 
    html2canvas($('#retrocon').get(0)).then( function (canvas) {

      var data = canvas.toDataURL();

      // ajax통신
      $.ajax({
        type: 'POST',
        url: '/hoay/saveImage/',
        data: {data:data},
        success: function(result) {
          var filename = result['filename'];
          sendLinkKakao(filename);
        },
        error: function(e) { alert("에러발생");}
      });

    });
  });
});
</script>

ajax 통신에 대해 설명이 필요하다면 ajax통신하기에서 확인 가능.

django views에서 이미지 파일로 저장하기

# canvas 이미지 저장
@csrf_exempt
def canvasToImage(request):
    data = request.POST.__getitem__('data')
    data = data[22:]        # 앞의 'data:image/png;base64'부분을 제거
    number = random.randrange(1,10000)    # 동시에 다른 사용자가 접근시 최대한 중복을 막기위함.

  # 저장할 경로 및 파일명을 지정
    path = str(os.path.join(settings.STATIC_ROOT, 'resultImg/'))
    filename = 'image' + str(number) + '.png'

  # "wb"(즉, 바이너리파일 쓰기전용)으로 파일을 open
    image = open(path+filename, "wb")
  # `base64.b64decode()`를 통하여 디코딩을 하고 파일에 써준다.
    image.write(base64.b64decode(data))
    image.close()

  # filename을 json형식에 맞추어 response를 보내준다.
    answer = {'filename': filename}
    return JsonResponse(answer)

필요한 설명은 주석으로 대부분 설명하였습니다.

마무리하며

이렇게 html2canvas로 html 특정 영역을 스크린샷하고 이 이미지를 서버에 저장하는 방법까지 알아보았습니다. 저는 정말로 유용하게 썼고 이번 계기를 통하여 base64라는 포맷도 알게되어 좋았습니다. 이 방법을 사용해보면 html상에서 javascript사용, jquery의 ajax통신 사용, python의 file관련 모듈 사용 등 이것 저것 사전지식이 살짝은 필요해서 여러가지 학습에 좋았던 것 같습니다. 역시 웹으로는 못하는게 없는 것 같다는걸 한번 더 느끼게 해줍니다..ㅋㅋ

반응형

BELATED ARTICLES

more