development

HTML5 / Canvas / JavaScript를 사용하여 브라우저 내 스크린 샷 찍기

big-blog 2020. 9. 28. 09:31
반응형

HTML5 / Canvas / JavaScript를 사용하여 브라우저 내 스크린 샷 찍기


Google의 "버그 신고"또는 "피드백 도구"를 사용하면 브라우저 창의 영역을 선택하여 버그에 대한 피드백과 함께 제출되는 스크린 샷을 만들 수 있습니다.

Google 피드백 도구 스크린 샷 제이슨 작은으로 스크린 샷은 게시 중복 질문 .

그들은 이것을 어떻게하고 있는가? 구글의 자바 스크립트 피드백 API가에서로드 여기피드백 모듈의 자신의 개요는 스크린 샷 기능을 시연 할 예정이다.


JavaScript는 DOM을 읽고 canvas. HTML을 캔버스 이미지로 변환하는 스크립트를 작업하고 있습니다. 설명하신대로 피드백을 보내도록 구현하기로 오늘 결정했습니다.

스크립트를 사용하면 양식과 함께 클라이언트의 브라우저에서 만든 스크린 샷을 포함하는 피드백 양식을 만들 수 있습니다. 스크린 샷은 DOM을 기반으로하므로 실제 스크린 샷을 만들지 않고 페이지에서 사용 가능한 정보를 기반으로 스크린 샷을 빌드하므로 실제 표현에 100 % 정확하지 않을 수 있습니다.

그것은 서버에서 모든 렌더링을 필요로하지 않습니다 전체 이미지가 클라이언트의 브라우저에 생성 될 때,. HTML2Canvas 스크립트 자체는 내가 원하는 CSS3 속성을 거의 파싱하지 못하며 프록시를 사용할 수 있어도 CORS 이미지를로드하는 것을 지원하지 않기 때문에 여전히 실험적인 상태입니다.

여전히 상당히 제한된 브라우저 호환성 (더 많은 것을 지원할 수 없기 때문이 아니라 더 많은 크로스 브라우저 지원을 제공 할 시간이 없었기 때문).

자세한 내용은 여기에있는 예를 참조하십시오.

http://hertzen.com/experiments/jsfeedback/

edit html2canvas 스크립트는 이제 여기에서 별도로 사용할 수 있으며 여기 에서 몇 가지 예를 사용할 수 있습니다 .

edit 2 Google이 매우 유사한 방법을 사용한다는 또 다른 확인 (사실 문서에 따르면 유일한 주요 차이점은 탐색 / 그리기의 비동기 방법입니다)은 Google 피드백 팀의 Elliott Sprehn이이 프레젠테이션에서 찾을 수 있습니다. http : //www.elliottsprehn.com/preso/fluentconf/


이제 웹 앱에서 다음을 사용하여 클라이언트 전체 데스크톱의 '기본'스크린 샷을 찍을 수 있습니다 getUserMedia().

이 예를 살펴보십시오.

https://www.webrtc-experiment.com/Pluginfree-Screen-Sharing/

클라이언트는 현재 크롬을 사용해야하며 chrome : // flags에서 화면 캡처 지원을 활성화해야합니다.


으로 니클라스 언급 당신은 사용할 수 있습니다 html2canvas의 브라우저에서 JS를 사용하여 스크린 샷을 라이브러리를. 이 라이브러리를 사용하여 스크린 샷을 찍는 예를 제공하여이 시점에서 그의 답변을 확장하겠습니다.

function report() {
  let region = document.querySelector("body"); // whole screen
  html2canvas(region, {
    onrendered: function(canvas) {
      let pngUrl = canvas.toDataURL(); // png in dataURL format
      let img = document.querySelector(".screen");
      img.src = pngUrl; 

      // here you can allow user to set bug-region
      // and send it with 'pngUrl' to server
    },
  });
}
.container {
  margin-top: 10px;
  border: solid 1px black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
<div>Screenshot tester</div>
<button onclick="report()">Take screenshot</button>

<div class="container">
  <img width="75%" class="screen">
</div>

에서 report()함수 onrendered데이터 URI로 이미지를 얻기 후에는 사용자에게 보여 그를 마우스로 "버그 영역을"그릴 다음 서버에 스크린 샷 및 지역 좌표를 보낼 수 있습니다.

에서 이 예제 async/await 버전되었다 : 좋은과 makeScreenshot()기능 .

최신 정보

스크린 샷을 찍고, 지역을 선택하고, 버그를 설명하고, POST 요청을 보낼 수있는 간단한 예제 ( 여기에서는 jsfiddle ) (주요 기능은 report())입니다.

async function report() {
    let screenshot = await makeScreenshot(); // png dataUrl
    let img = q(".screen");
    img.src = screenshot; 
    
    let c = q(".bug-container");
    c.classList.remove('hide')
        
    let box = await getBox();    
    c.classList.add('hide');

    send(screenshot,box); // sed post request  with bug image, region and description
    alert('To see POST requset with image go to: chrome console > network tab');
}

// ----- Helper functions

let q = s => document.querySelector(s); // query selector helper
window.report = report; // bind report be visible in fiddle html

async function  makeScreenshot(selector="body") 
{
  return new Promise((resolve, reject) => {  
    let node = document.querySelector(selector);
    
    html2canvas(node, { onrendered: (canvas) => {
        let pngUrl = canvas.toDataURL();      
        resolve(pngUrl);
    }});  
  });
}

async function getBox(box) {
  return new Promise((resolve, reject) => {
     let b = q(".bug");
     let r = q(".region");
     let scr = q(".screen");
     let send = q(".send");
     let start=0;
     let sx,sy,ex,ey=-1;
     r.style.width=0;
     r.style.height=0;
     
     let drawBox= () => {
         r.style.left   = (ex > 0 ? sx : sx+ex ) +'px'; 
         r.style.top    = (ey > 0 ? sy : sy+ey) +'px';
         r.style.width  = Math.abs(ex) +'px';
         r.style.height = Math.abs(ey) +'px'; 
     }
     
     
     
     //console.log({b,r, scr});
     b.addEventListener("click", e=>{
       if(start==0) {
         sx=e.pageX;
         sy=e.pageY;
         ex=0;
         ey=0;
         drawBox();
       }
       start=(start+1)%3;  		
     });
     
     b.addEventListener("mousemove", e=>{
       //console.log(e)
       if(start==1) {
           ex=e.pageX-sx;
           ey=e.pageY-sy
           drawBox(); 
       }
     });
     
     send.addEventListener("click", e=>{
       start=0;
       let a=100/75 //zoom out img 75%       
       resolve({
          x:Math.floor(((ex > 0 ? sx : sx+ex )-scr.offsetLeft)*a),
          y:Math.floor(((ey > 0 ? sy : sy+ey )-b.offsetTop)*a),
          width:Math.floor(Math.abs(ex)*a),
          height:Math.floor(Math.abs(ex)*a),
          desc: q('.bug-desc').value
          });
          
     });
  });
}

function send(image,box) {

    let formData = new FormData();
    let req = new XMLHttpRequest();
    
    formData.append("box", JSON.stringify(box)); 
    formData.append("screenshot", image);     
    
    req.open("POST", '/upload/screenshot');
    req.send(formData);
}
.bug-container { background: rgb(255,0,0,0.1); margin-top:20px; text-align: center; }
.send { border-radius:5px; padding:10px; background: green; cursor: pointer; }
.region { position: absolute; background: rgba(255,0,0,0.4); }
.example { height: 100px; background: yellow; }
.bug { margin-top: 10px; cursor: crosshair; }
.hide { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
<body>
<div>Screenshot tester</div>
<button onclick="report()">Report bug</button>

<div class="example">Lorem ipsum</div>

<div class="bug-container hide">
  <div>Select bug region</div>
  <div class="bug">    
    <img width="75%" class="screen" >
    <div class="region"></div> 
  </div>
  <div>
    <textarea class="bug-desc">Describe bug here...</textarea>
  </div>
  <div class="send">SEND BUG</div>
</div>

</body>


다음은 getDisplayMedia 를 사용하는 예입니다.

document.body.innerHTML = '<video style="width: 100%; height: 100%; border: 1px black solid;"/>';

navigator.mediaDevices.getDisplayMedia()
.then( mediaStream => {
  const video = document.querySelector('video');
  video.srcObject = mediaStream;
  video.onloadedmetadata = e => {
    video.play();
    video.pause();
  };
})
.catch( err => console.log(`${err.name}: ${err.message}`));

체크 아웃 할 가치가있는 것은 Screen Capture API 문서입니다.

참고 URL : https://stackoverflow.com/questions/4912092/using-html5-canvas-javascript-to-take-in-browser-screenshots

반응형