HTML 캔버스를 gif / jpg / png / pdf로 캡처 하시겠습니까?


719

html 캔버스에 표시된 내용을 이미지 또는 pdf로 캡처하거나 인쇄 할 수 있습니까?

캔버스를 통해 이미지를 생성하고 해당 이미지에서 png를 생성하고 싶습니다.





1
canvas2image 라이브러리가 유용 할 것입니다 : github.com/hongru/canvas2image
— noego

답변:


737

죄송합니다. 원래의 대답은 비슷한 질문에만 해당되었습니다. 이것은 수정되었습니다 :

var canvas = document.getElementById("mycanvas");
var img    = canvas.toDataURL("image/png");

IMG의 값으로 다음과 같이 새 이미지로 쓸 수 있습니다.

document.write('<img src="'+img+'"/>');

15
질문 하나 더,이 태그에있는 이미지를 서버에 어떻게 저장할 수 있습니까? 어떤 추측 ??
— Surya

7
그러나 만약 내가 var img = canvas.toDataURL ( "image / jpeg"); 배경이 완전한 검정색으로 표시됩니다. 수정 방법
— gauti

181
오 어서. 나는 2009 년에 이것을 대답했다. 당신은 무엇을 기대합니까?
— donohoe

35
@donohoe 실제로 당신은 2010 년 8 월에 답변했습니다 :)
— nick nick

13
같은 작업을 수행하는 데 훨씬 적은 메모리를 사용합니다 var img = new Image(); img.src = canvas.toDataURL(); document.body.appendChild(img);. document.write코드 그들이 다음 DOM에 해당 문자열의 복사본을 넣어하는 HTML 문자열을 만들고, 데이터 URL을하고, 브라우저는 다음, 이미지 요소에 다른 사본을 넣어, 그 HTML 문자열을 구문 분석을 켜 다시 구문 분석 할 수있다 데이터 URL을 이미지 데이터에 삽입 한 다음 이미지를 표시 할 수 있습니다. 엄청난 양의 메모리 / 복사 / 파싱 인 화면 크기 이미지의 경우. 단지 제안
— gman

116

HTML5는 Opera, Firefox 및 Safari 4 베타에서 구현되는 Canvas.toDataURL (mimetype)을 제공합니다. 그러나 여러 가지 보안 제한이 있습니다 (주로 다른 출처에서 캔버스로 콘텐츠를 그리는 것과 관련이 있습니다).

따라서 추가 라이브러리가 필요하지 않습니다.

예 :

 <canvas id=canvas width=200 height=200></canvas>
 <script>
      window.onload = function() {
          var canvas = document.getElementById("canvas");
          var context = canvas.getContext("2d");
          context.fillStyle = "green";
          context.fillRect(50, 50, 100, 100);
          // no argument defaults to image/png; image/jpeg, etc also work on some
          // implementations -- image/png is the only one that must be supported per spec.
          window.location = canvas.toDataURL("image/png");
      }
 </script>

이론적으로 이것은 중간에 녹색 사각형이있는 이미지를 만들고 탐색해야하지만 테스트하지 않았습니다.


2
이미지가 저장 될 곳. 내 지역의 위치는?
— chinna_82

5
이미지가 브라우저에 이미지로 표시됩니다. 그런 다음 디스크 나 다른 곳에 저장할 수 있습니다. 다음은 페이지의 첫 번째 캔버스를 PNG로 변환하여 브라우저에 새 창으로 표시하는 빠르고 더러운 일반 "Canvas2PNG"책갈피입니다.javascript:void(window.open().location = document.getElementsByTagName("canvas")[0].toDataURL("image/png"))
— Kai Carver

이미지 크기가 몇 MB 인 경우 브라우저 충돌을 준비하십시오 (FireFox에서 잠시 전에 다시 수행했습니다).
— jahu

1
여러 이미지를 렌더링하기 위해 어떻게 수정할 수 있습니까?
— Mentalist

데이터 URI의 길이는 최대이므로 데이터 URL에 넣을 수있는 이미지 크기에는 상한이 있습니다.
— Juha Syrjälä

44

나는이 질문의 범위를 조금 확장 하고이 문제에 유용한 몇 가지 유용한 정보를 제공 할 것이라고 생각했습니다.

캔버스를 이미지로 가져 오려면 다음을 수행해야합니다.

var canvas = document.getElementById("mycanvas");
var image = canvas.toDataURL("image/png");

이를 사용하여 이미지를 페이지에 쓸 수 있습니다.

document.write('<img src="'+image+'"/>');

여기서 "image / png"는 MIME 유형입니다 (png는 지원해야하는 유일한 유형입니다). 지원되는 유형의 배열을 원하면 다음 행을 따라 무언가를 수행 할 수 있습니다.

var imageMimes = ['image/png', 'image/bmp', 'image/gif', 'image/jpeg', 'image/tiff']; //Extend as necessary 
var acceptedMimes = new Array();
for(i = 0; i < imageMimes.length; i++) {
    if(canvas.toDataURL(imageMimes[i]).search(imageMimes[i])>=0) {
        acceptedMimes[acceptedMimes.length] = imageMimes[i];
    }
}

페이지 당 한 번만 실행하면되며 페이지 수명주기 동안 변경되지 않아야합니다.

파일을 저장 한 상태에서 사용자가 다운로드하도록하려면 다음을 수행하십시오.

var canvas = document.getElementById("mycanvas");
var image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"); //Convert image to 'octet-stream' (Just a download, really)
window.location.href = image;

다른 MIME 유형과 함께 사용하는 경우 image / octet-stream이 아닌 image / png의 두 인스턴스를 모두 변경하십시오. 캔버스 렌더링에 도메인 간 리소스를 사용하는 경우 toDataUrl 메서드를 사용하려고 할 때 보안 오류가 발생한다는 점도 언급 할 가치가 있습니다.


1
파일 다운로드 솔루션으로 사용하고 싶은 소프트웨어를 선택해야합니다. 조금 불편합니다 ... 일단 다운로드 한 MIME을 PNG로 바꾸는 방법이 있습니까?
— So4ne

1
@ So4ne 나는 그렇게 생각하지 않는다. 이미지 / 옥텟 스트림이어야 사용자에게 다운로드를 요구한다. 해당 줄을 제거하면 페이지가 이미지로 리디렉션됩니다. 그래도 다른 사람이 잘 할 수있는 방법을 알고 있는지 알고 싶습니다.
— meiamsome

2
<a> 링크의 target = "_ blank"및 .click ()을 사용하여 다운로드를 트리거 할 수도 있습니다 (text / csv 및 text / plain의 경우 FF data-urls 및 download = "filename"으로 테스트 됨)
— Ax3l

대단하다. 감사! 그러나 로컬이 아닌 서버에 저장하려면 어떻게해야합니까? 양식 파일 입력이 img src를 업로드 가능한 것으로 받아들입니까?
— 최고 연금술사

죄송합니다. 답을 찾았습니다. 다른 사람도 찾고있는 경우에 이전 질문
— 최고 연금술사

34
function exportCanvasAsPNG(id, fileName) {

    var canvasElement = document.getElementById(id);

    var MIME_TYPE = "image/png";

    var imgURL = canvasElement.toDataURL(MIME_TYPE);

    var dlLink = document.createElement('a');
    dlLink.download = fileName;
    dlLink.href = imgURL;
    dlLink.dataset.downloadurl = [MIME_TYPE, dlLink.download, dlLink.href].join(':');

    document.body.appendChild(dlLink);
    dlLink.click();
    document.body.removeChild(dlLink);
}

저장된 파일은 .svg 형식으로 유지됩니다. png로 저장하는 방법?
— nullpointer

이것은 IE에서 작동하지 않을 수 있다는 점을 제외하고는 훌륭한 솔루션입니다. "시스템 호출로 전달되는 데이터 영역이 너무 작습니다"
— Jose Cherian

Chrome에서는 "네트워크 오류"라고 표시되고 Firefox에서는 훌륭하게 작동합니다. (Linux의 경우)
— Ecker00

20

" wkhtmltopdf "를 사용합니다. 그냥 잘 작동합니다. Chrome, Safari 등에서 사용되는 웹킷 엔진을 사용하며 매우 사용하기 쉽습니다.

wkhtmltopdf stackoverflow.com/questions/923885/ this_question.pdf

그게 다야!

시도 해봐


1
나는 wkhtmltopdf 캠프에도 있습니다. 아카이빙 및 놀라운 용도로 사용하고 있습니다.
— Daniel Szabo 2016 년

로그인 정보가 필요한 페이지에서 WKHTMLtoPDF를 사용하는 방법은 무엇입니까? Jsreport를 사용하여 PDF로 변환하고 있지만 HTML2Canvas로 컨텐츠를 캡처합니다. Canvas를 매개 변수로 JSreport에 전송하는 데 문제가 있습니다
— khaled Dehia


15

서버를 통해 다운로드를 수행하는 경우 다음과 같은 도움이됩니다 (이 방법으로 파일의 이름을 지정 / 변환 / 후 처리 / 등화 할 수 있음).

사용하여 데이터 게시 toDataURL

머리글 설정

$filename = "test.jpg"; //or png
header('Content-Description: File Transfer');
if($msie = !strstr($_SERVER["HTTP_USER_AGENT"],"MSIE")==false)      
  header("Content-type: application/force-download");else       
  header("Content-type: application/octet-stream"); 
header("Content-Disposition: attachment; filename=\"$filename\"");   
header("Content-Transfer-Encoding: binary"); 
header("Expires: 0"); header("Cache-Control: must-revalidate"); 
header("Pragma: public");

이미지 만들기

$data = $_POST['data'];
$img = imagecreatefromstring(base64_decode(substr($data,strpos($data,',')+1)));

이미지 를 JPEG로 내보내기

$width = imagesx($img);
$height = imagesy($img);
$output = imagecreatetruecolor($width, $height);
$white = imagecolorallocate($output,  255, 255, 255);
imagefilledrectangle($output, 0, 0, $width, $height, $white);
imagecopy($output, $img, 0, 0, 0, 0, $width, $height);
imagejpeg($output);
exit();

- 또는 투명 PNG로

imagesavealpha($img, true);
imagepng($img);
die($img);

9

또 다른 흥미로운 솔루션은 PhantomJS 입니다. JavaScript 또는 CoffeeScript로 스크립트 가능한 헤드리스 WebKit입니다.

유스 케이스 중 하나는 화면 캡처입니다. SVG 및 캔버스를 포함한 웹 컨텐츠를 프로그래밍 방식으로 캡처하거나 섬네일 미리보기로 웹 사이트 스크린 샷을 작성할 수 있습니다.

가장 좋은 진입 점은 화면 캡처 위키 페이지입니다.

다음은 RaphaelJS의 극 시계에 대한 좋은 예입니다.

>phantomjs rasterize.js http://raphaeljs.com/polar-clock.html clock.png

페이지를 PDF로 렌더링 하시겠습니까?

> phantomjs rasterize.js 'http://en.wikipedia.org/w/index.php?title=Jakarta&printable=yes' jakarta.pdf

2
+1 : PhantomJS는 간단하고 문서화가 잘되어 있으며 신중하게 고안된 시스템으로이 작업에 적합합니다. 예를 들어, 잡기 전에 페이지 나 그 일부 (JS를 통해)를 수정하여 원하는대로 보이게 할 수 있습니다. 완전한!
— johndodo

1
PhantomJs는 이제 폐기되었습니다
— Merc

3

많은 사람들이하는 jQuery를 사용하는 경우 다음과 같이 허용되는 답변을 구현합니다.

var canvas = $("#mycanvas")[0];
var img = canvas.toDataURL("image/png");

$("#elememt-to-write-to").html('<img src="'+img+'"/>');

12
여기서 jQuery 의 유일한 사용법은 캔버스 선택입니다. .toDataURL네이티브 JS입니다.
— j6m8

이 링크를 보는 데 도움이되는 문제를 저장했습니다. stackoverflow.com/questions/25131763/…
— Ramesh S

2
순수 (100 %) jQuery 솔루션은 다음과 같습니다. $('<img>').attr('src',$('#mycanvas')[0].toDataURL('image/png')).appendTo($('#element-to-write-to').empty());정확히 한 줄입니다.
— Naeel Maqsudov 5

1

jspdf를 사용하여 다음과 같이 캔버스를 이미지 또는 pdf로 캡처 할 수 있습니다.

var imgData = canvas.toDataURL('image/png');              
var doc = new jsPDF('p', 'mm');
doc.addImage(imgData, 'PNG', 10, 10);
doc.save('sample-file.pdf');

추가 정보 : https://github.com/MrRio/jsPDF


1

이것이 더 빠른지 아닌지는 실제로 알지 못하지만 문자열이없는 다른 방법입니다. toDataURL 대신 (여기에서 모든 질문이 제안하는 바와 같이). 필자의 경우 Array 버퍼 또는 뷰가 필요하므로 dataUrl / base64를 방지하고 싶습니다. HTMLCanvasElement의 다른 메소드는 toBlob입니다. (TypeScript 기능) :

    export function canvasToArrayBuffer(canvas: HTMLCanvasElement, mime: string): Promise<ArrayBuffer> {
  return new Promise((resolve, reject) => canvas.toBlob(async (d) => {
    if (d) {
      const r = new FileReader();
      r.addEventListener('loadend', e => {
        const ab = r.result;
        if (ab) {
          resolve(ab as ArrayBuffer);
        }
        else {
           reject(new Error('Expected FileReader result'));
        }
      }); r.addEventListener('error', e => {
        reject(e)
      });
      r.readAsArrayBuffer(d);
    }
    else {
      reject(new Error('Expected toBlob() to be defined'));
    }
  }, mime));
}

Blob의 또 다른 장점은 HTMLInputFile의 'files'멤버와 유사하게 ObjectUrl을 작성하여 데이터를 파일로 표시 할 수 있다는 것입니다. 더 많은 정보:

https://developer.mozilla.org/es/docs/Web/API/HTMLCanvasElement/toBlob


-1

일부 Chrome 버전에서는 다음을 수행 할 수 있습니다.

  1. 이미지 그리기 기능 사용 ctx.drawImage(image1, 0, 0, w, h);
  2. 캔버스를 마우스 오른쪽 버튼으로 클릭
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.