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.