메뉴 건너뛰기

?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄 첨부
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄 첨부

Javascript 기술은 점점 발전하여 단순 JS만으로도 많은 기능을 사용할 수 있는데, 이번엔 화면을 캡처하는 방법을 알아보겠습니다.

 

요청사항 중 특정 요소를 캡처하여 이미지 데이터를 서버에 전송하고 저장을 원하였습니다.

화면 캡처 후 다운로드 기능은 사실 이미 많이 공유되고 있는데, 제가 겪었던 문제점에 대한 대응책이나 이런부분이 잘 보이질 않아 추가적으로 적어볼까합니다.

 

일단 html2canvas를 사용하여 동작시킬 예정이므로 해당 라이브러리를 추가합니다.

 

 

html2canvas를 통한 캡처 후 전송하기

<script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>

아래는 공식사이트입니다.

https://html2canvas.hertzen.com/

 

이제 전송을 위해 ajax를 활용하여 전송 예제를 만들어보겠습니다.

-HTML

<section id="chart_box">
    <div class="chart">
     ...//차트에 해당하는 요소들
    </div>
</section>

 

 

-JS

$("#btn").on("click", function() {
	sreenShot($("#chart_box"));
});

function sreenShot(target) {
	if (target != null && target.length > 0) {
		var t = target[0];
		html2canvas(t).then(function(canvas) {
			var myImg = canvas.toDataURL("image/png");
			myImg = myImg.replace("data:image/png;base64,", "");

			$.ajax({
				type : "POST",
				data : {
					"imgSrc" : myImg
				},
				dataType : "text",
				url : contextPath + "/public/ImgSaveTest.do",
				success : function(data) {
					console.log(data);
				},
				error : function(a, b, c) {
					alert("error");
				}
			});
		});
	}
}

넣고 싶은 요소 $("#chart_box")를 매개변수로 집어넣고 0번째 데이터를 html2canvas 첫번째 파라미터에 처리합니다.

html2canvas는 Promise를 사용하는것으로 보이는데, 요소 처리가 완료되면 다음 이행동작을 정의합니다.

 

매개변수로 나온 canvas의 toDataURL을 통해 이미지 바이너리 데이터를 받을 수 있습니다.

거기서 앞에 붙는 데이터타입과 인코딩타입을 제거하고 서버로 전송하면 js부분은 끝입니다.

전송은 ajax를 통해 처리하였습니다.

 

 

-Server(java)

@ResponseBody
@RequestMapping(value = { "ImgSaveTest" }, method = RequestMethod.POST)
public ModelMap ImgSaveTest(@RequestParam HashMap<Object, Object> param, final HttpServletRequest request, final HttpServletResponse response) throws Exception {
	ModelMap map = new ModelMap();
	
	String binaryData = request.getParameter("imgSrc");
	FileOutputStream stream = null;
	try{
		System.out.println("binary file   "  + binaryData);
		if(binaryData == null || binaryData.trim().equals("")) {
		    throw new Exception();
		}
		binaryData = binaryData.replaceAll("data:image/png;base64,", "");
		byte[] file = Base64.decodeBase64(binaryData);
		String fileName=  UUID.randomUUID().toString();
		
		stream = new FileOutputStream("E:/test2/"+fileName+".png");
		stream.write(file);
		stream.close();
		System.out.println("캡처 저장");
	    
	}catch(Exception e){
		e.printStackTrace();
		System.out.println("에러 발생");
	}finally{
		if(stream != null) {
			stream.close();
		}
	}
	
	map.addAttribute("resultMap", "");
	return map;
}

파라미터로 넘긴 데이터를 문자열로 전달받고 바이너리 데이터를 스트림을 통해 읽어서 파일쓰기를 통해 파일을 남깁니다.

 

 

사용예시

html Page

 

 

전송버튼을 누르고 지정한 test2 디렉토리에 저장되는지 확인해보겠습니다.

 

 

 

 

정상적으로 파일이 써진 모습을 볼 수 있습니다.

 

 

개발시 주의사항

*아래 기재한 주의사항은 개인적으로 적용과 테스트를 해보면서 겪은 문제들입니다.

 

1. html2canvas에 넣는 첫번째 요소가 jQuery 선택자인 경우 id값일지라도 배열의 인덱스가 필요합니다.

ex) $("#test")[0]

 

2. 다운받으려는 특정요소는 width, height등 요소의 영역이 정확하게 지정되어 있어야합니다.

지정되지 않은 요소를 받게되면 브라우저상에서는 잘 보일지라도 전송된 데이터는 비어있거나 잘렸거나 등등 여러가지 문제가 발생할 수 있습니다.

 

3. 다운받으려는 특정요소의 위치가 position등을 통해 억지로 맞춰진 경우 정상출력이 되지 않을 수 있습니다.

 

4. div태그 내부의 img태그등 정보를 받아오는 데이터가 외부인 경우 정상적으로 출력되지 않습니다.

다른 예시 블로그 글들을 보면 http~를 통해 이미지를 가져오고 다운로드 받는다고 되어있는데, 막상 따라해보면 흰색 화면만 받아졌습니다. 서버 내부에 존재하는 이미지를 넣고 다운로드시 정상 출력되었습니다.

 

5. 인터셉터 관련 서버 코드 문제

저같은 경우는 XSS악성 스크립트 방지를 위해 서버코드로 넘어가는 모든 파라미터를 검사하는 로직을 추가해놨습니다.

html2canvas로 읽는 데이터가 얼마 안되는 경우에는 큰 문제가 없지만 복잡한 이미지를 만들게되면 그만큼 바이너리 데이터 또한 매우 커집니다. 캡처의 바이너리만 해도 문자열 길이가 약 7만5천개정도가 되었습니다. 여기서 로직을 체크하는 함수와 문자열이 겹치면서 서버로 전송이 안되는 이슈가 있어서, 해당 파라미터만 검사를 안하거나 url에 따라 예외처리등 약간의 극복(?)이 필요했습니다.

 

6. 바이너리 데이터를 넘기다보니 더욱 복잡한 이미지를 이미지화하여 전송하게되면 데이터는 더욱 커지게 되고 tomcat의 maxPortSize를 강제로 키우거나 -1처리를 통해 무제한으로 변경해야 할 수도 있습니다.

 

7. 높이가 body보다 큰 영역을 처리할 때 잘릴 수가 있습니다. 처리하는동안 body태그의 값을 제어하여 영역과 동일하게 또는 그 보다 크게 처리하였다가 원래 사이즈로 처리하는 로직이 필요합니다. - 20201126 추가


List of Articles
번호 제목 날짜 조회 수
187 jquery offset()을 이용한 부드러운 스크롤 이동 2016.09.01 7277
186 지금 보고 있는 웹페이지 창을 닫으려고 합니다." 안나타나게 하기 2014.02.27 7185
185 이동 가능한 레이어팝업 소스 2016.09.01 7166
184 연관배열 사용하기 2016.09.21 7134
183 접근성 윈도우 팝업 띄우기 2016.12.22 7114
182 특정 HTML DOM 엘레멘트로 스크롤 이동하기 2016.09.09 7075
181 'setTimeout', 타이머를 사용하자! file 2015.02.03 7033
180 활용예제 : 체크박스 전체선택 전체해제 /라디오버튼 2014.03.01 7020
179 마우스를 오버해서 이미지를 확대해서 보기 2014.02.27 7003
178 onkeypress 키보드 이벤트 처리하는 법 – text, textarea 2016.09.21 7001
177 jQuery 이미지 슬라이드 오버시 큰이미지 보여주기 소스 file 2014.03.01 6975
176 iframe사용시 높이 자동 조절 2015.06.19 6958
175 쿠키(Cookie)에 값 저장하기 2016.09.21 6952
174 이미지에 마우스 올렸을때 확대 이미지 나오게 하기 (onmouseover 2014.03.01 6923
173 자바스크립트 소수점 자리수 계산 2014.03.01 6897
172 입력된 폼의 내용 똑같이 복사 file 2014.03.01 6892
171 form 값 iframe 으로 넘기기 2014.03.01 6872
170 정규식을 이용한 콤마(comma) 제거하기 2015.06.19 6804
169 예제 - 이미지를 원본 크기로 볼 수 있도록 새창으로 열기 확장 (리사이징 및 이미지 드래그) file 2015.06.19 6798
168 차단된 팝업창을 허용하라는 스크립트 2014.02.27 6751
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 ... 13 Next
/ 13

하단 정보를 입력할 수 있습니다

© k2s0o1d4e0s2i1g5n. All Rights Reserved