Html2canvas 스크린샷 to Django

강다·2022년 11월 21일
0
post-thumbnail

html2canvas screenshot to Django

전에 진행한 Play-That-Pen-Pong 페이지 중 캐릭터 꾸미기 기능이 있는 페이지가 있다. 꾸며진 캐릭터를 프로필 사진으로 자동으로 바꿔주면 우리 사이트의 아기자기한 정체성을 잘 표현할 수 있을 거라고 생각했다.

그래서, html파일이 렌더링 된 상태로 브라우저 화면을 캡처할 수 있는 기능을 찾아보다가, html2canvas를 사용해 특정 영역을 캡처해 장고 프로필 모델로 전송하기로 했다.

CLICK HERE 버튼을 누르면 자동 프로필 설정 및 png 다운로드



❗초기 설정

#models.py
class Profile(models.Model):
    profile = models.ImageField(null=True, blank=True)

    def __str__(self):
        return f'{self.pk} Profile'

#urls.py (추가 사항)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)



❗avatar.html

$(function(){
	$("#save").click(function(){ //button의 id가 "save"
		html2canvas($('#capture').get(0)).then(function(canvas){
			var data=canvas.toDataURL();
			//canvas영역 이미지 다운로드
      downloadURI(data, "new_profile.png");

      function downloadURI(uri, name){
	      var link = document.createElement("a");
        link.download = name;
        link.href = uri;
        document.body.appendChild(link);
        link.click();
       }

       //ajax 통신
       $.ajax({
	       async:false,
         type:'POST',
         url :"{% url 'diary:avatar_profile' %}",
         data:{data:data},
         success:function(result){
	         alert("프로필로 설정!")
         },
	       error: function(e){alert("error!")}
        });
			});
		});
	});
  • 캡처한 영역을 이미지 파일로 저장해야 활용이 가능하므로 html 상에서 ajax를 사용해 스크린샷을 base64 포맷으로 django views.py의 avatar_profile 함수로 요청을 보냈다.
  • django에서는 파이썬의 base64라는 모듈을 사용해 이미지 binary 코드로 디코딩 해서 파일에 쓰고 저장한다.


❗views.py

@csrf_exempt
def avatar_profile(request):
    data = request.POST.__getitem__('data')
    data = data[22:] #앞의 필요없는 부분 제거

    filename = 'profile.png'
    imgdata = base64.b64decode(data)
    img_root = settings.MEDIA_ROOT+ '/'+ filename
    with open(img_root,'wb') as f:
        f.write(imgdata)

	#프로필 모델에 이미지 파일 넘기기
    profile = Profile()
    profile.profile = Image(img_root)
    profile.save()

    return HttpResponseRedirect('avatar')
  • MEDIA_ROOT로 미디어 경로에 ajax로 전달 받은 data로 imgdata로 디코딩 해서 이미지 파일로 써준다.
    • 이 코드는 MEDIA_ROOT안에 profile.png가 하나 존재하고, 새로운 이미지가 오면 계속 덮어쓰기 되는 구조이다.
<!-- HTML에서 사용하기 -->
<img src="{{ img.profile.url }}" style="width:100%;height:100%;">

참고
https://hooongs.tistory.com/66
https://minaminaworld.tistory.com/89
https://velog.io/@chaeri93/Django-base64-%EC%9D%B8%EC%BD%94%EB%94%A9%EB%90%9C-%EC%9D%B4%EB%AF%B8%EC%A7%80-ImageField%EB%A1%9C-%EC%A0%80%EC%9E%A5

0개의 댓글