본문 바로가기
Web

Javascript- html2canvas (현재 웹화면을 스크린샷 찍어서 서버로?) (feat. java spring)

by 모닝위즈 2023. 7. 12.
반응형

먼저.. 공식 사이트 

https://html2canvas.hertzen.com/

 

html2canvas - Screenshots with JavaScript

Try out html2canvas Test out html2canvas by rendering the viewport from the current page. Capture

html2canvas.hertzen.com

 

function screenshot() {
    return new Promise((resolve, reject) => {
        html2canvas(document.querySelector('#capture_element')).then((canvas) => {
            resolve(canvas.toDataURL());
        }).catch((error) => {
            reject(error);
        });
    });
}

그냥 바로 전송하지 않고 값을 가져온다음 추가 가공이 필요하다면, 위와 같이 비동기 함수로 만들어준다.

그리고 querySelector안에 엘리멘트의 id, name, class를 지정할 수 있다.

const screenshot_data = await screenshot().then((data) => {return data;});

위와 같이 변수에 담을 수 있다.

그러면 아래와 같이 http://내 서버/proc.mitw 로 이미지를 다운로드를 받을 수도 있고, 서버로 전송할 수도 있다. 

나는 서버에 꼭 전송을 하고 싶다..  왜냐면...

쉿.. 아무 이유 없다. 하지만, 다양하게 활용이 가능할 것 같다..

 

아래는 그냥 예제 소스라고 봐두면 된다.

async function send_server() {
    const screenshot_data = await screenshot().then((data) => {return data;});
    const abortsController = new AbortController();
    const signal = abortsController.signal;
    const timeouter = setTimeout(() => {
        abortsController.abort();
        console.error('Connection Timeout');
    }, 5000); // 5초의 타임아웃 설정
    return fetch("http://내 서버/proc.mitw", {
        method: "POST",
        headers: {"Content-Type": "application/json"},
        body: JSON.stringify({
            screenshot_image : screenshot_data
        }),
        signal: signal
    }).then((result) => {
        clearTimeout(timeouter);
        if (!result) {
            throw new Error('Error :' + result.status + ', ' + result.statusText + ' error');
        }
        return r.json();
    }).then((d) => d).catch((err) => {
        console.error(err);
    });
}

 

이제 서버로 전송을 했으니까.. 서버에서 받아볼까?

/**
 *  스크린샷 수집  *
 *  */
@ResponseBody
@RequestMapping(value = "/proc.mitw")
public JSONObject getScreenshot(
        @RequestBody HashMap<String, Object> map
) throws Exception {
    JSONObject object = new JSONObject();
    String result = "success";
    String message = "completed images save!";
    Date createDate = new Date();
    String year = (new SimpleDateFormat("yyyy").format(createDate)); //년도
    String month = (new SimpleDateFormat("MM").format(createDate)); //월
    String day = (new SimpleDateFormat("dd").format(createDate)); //일
    //Path를 설정한다.
    String path = "/data/mitw_files/screenshot/" + year + month + day + "/";
    //이미지로 저장
    String my_screenshot_image = "screenshot.png";
    if(map.get("screenshot_image")!= null){
        Base64ToImgDecodeUtil.decoder(
        	map.get("screenshot_image"), 
            path, 
            my_screenshot_image
        );
    } else {
    	result = "failed";
        message = "not found image!!!";
    }
    object.put("result", result);
    object.put("message", message);
    return object;
}

 위와 같이 서버에 SAVE가 가능하다!

 그러면 이번에는 이미지 업로드에 핵심적인 역할을 하는 Base64ToImgDecodeUtil.decoder()를 만들어 보자.

 Base64ToImgDecodeUtil 클래스를 작성한다.

package com.mitw.application.common.utils;

import javax.imageio.ImageIO;
import javax.xml.bind.DatatypeConverter;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;

/**
 * Base64로 압축된 데이터를 디코딩하여 저장한다.
 * @author mitw
 * @version 1.0
 */
public class Base64ToImgDecodeUtil {

    public static boolean decoder(String base64, String target, String filename){
        // 디렉토리가 없다면 생성을 하자.
        File directory = new File(target);
        if (!directory.exists()) {
            directory.mkdirs();
        }
        String data = base64.split(",")[1];
        byte[] imageBytes = DatatypeConverter.parseBase64Binary(data);
        try {
            BufferedImage bufImg = ImageIO.read(new ByteArrayInputStream(imageBytes));
            // RGB 색상 모델 생성
            ColorModel colorModel = new ComponentColorModel(bufImg.getColorModel().getColorSpace(),
                    bufImg.getColorModel().hasAlpha(), bufImg.getColorModel().isAlphaPremultiplied(),
                    bufImg.getColorModel().getTransparency(), DataBuffer.TYPE_BYTE);
            // 새로운 BufferedImage 생성
            BufferedImage image = new BufferedImage(colorModel, bufImg.getRaster(), false, null);
            //ImageIO.setUseCache(false);
            ImageIO.write(image, "png", new File(target + "/" + filename));
        } catch (IOException e) {
            e.printStackTrace();
            return true;
        }
        return true;
    }
}

이러면 이미지가 저장이 된다.

 

이렇게 화면캡처에 특화된 라이브러리를 알아보았다.

여러분들도 이렇게 화면을 캡처해보세요!

 

댓글