HTML कैनवास को gif / jpg / png / pdf के रूप में कैप्चर करें?


719

क्या HTML कैनवास में छवि या पीडीएफ के रूप में प्रदर्शित करना या प्रिंट करना संभव है?

मैं कैनवास के माध्यम से एक छवि उत्पन्न करना चाहता हूं, और उस छवि से एक पीएनजी उत्पन्न करने में सक्षम होना चाहता हूं।




यहाँ उदाहरण freakyjolly.com/-
कोड स्पाई

1
आप इसके लिए कैनवास 2image लाइब्रेरी उपयोगी पा सकते हैं: github.com/hongru/canvas2image
noego

जवाबों:


737

उफ़। मूल उत्तर एक समान प्रश्न के लिए विशिष्ट था। यह संशोधित किया गया है:

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

IMG में मान के साथ आप इसे एक नई छवि के रूप में लिख सकते हैं:

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

15
एक और सवाल, मैं इस टैग में मिली छवि को सर्वर पर कैसे सहेज सकता हूं। कोई अंदाजा??
सूर्या

7
लेकिन अगर मैं var img = कैनवस .toDataURL ("इमेज / जेपीईजी") का उपयोग करता हूं; मैं पूरा काला के रूप में पृष्ठभूमि मिल रहा है। इसे कैसे सुधारा जाए
guti

181
ओह अब छोड़िए भी। मैंने 2009 में इसका उत्तर दिया। आप क्या उम्मीद करते हैं?
डोनोहे

35
वास्तव में @donohoe आप अगस्त 2010 में :) ने इसका उत्तर दिया
निक

13
यह कुछ करने के लिए बहुत कम मेमोरी का उपयोग करेगा var img = new Image(); img.src = canvas.toDataURL(); document.body.appendChild(img);document.writeकोड, डेटा यूआरएल कर रहा है उन्हें एक HTML स्ट्रिंग बनाकर, फिर डोम में कि स्ट्रिंग की एक प्रति डालने के बाद ब्राउज़र उस कि HTML स्ट्रिंग पार्स करने, छवि तत्व पर अन्य प्रति शब्दों में कहें, तो फिर चालू करने के लिए उसे पार्स है डेटा URL छवि डेटा में, फिर अंत में यह छवि दिखा सकता है। एक स्क्रीन आकार की छवि के लिए जो मेमोरी / कॉपी / पार्सिंग की एक बड़ी मात्रा है। बस एक सुझाव
gman

116

HTML5 Canvas.toDataURL (mimetype) प्रदान करता है जो ओपेरा, फ़ायरफ़ॉक्स और सफारी 4 बीटा में लागू किया गया है। हालाँकि, कई सुरक्षा प्रतिबंध हैं, (अधिकतर कैनवास पर किसी अन्य मूल से ड्राइंग सामग्री के साथ करने के लिए)।

इसलिए आपको एक अतिरिक्त पुस्तकालय की आवश्यकता नहीं है।

जैसे

 <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
जहां इमेज सेव होगी। मेरे स्थानीय में स्थान?
चिन्ना_ 17२

5
आपके ब्राउज़र में छवि को छवि के रूप में प्रदर्शित किया जाएगा। फिर आप इसे डिस्क पर या जो भी सहेज सकते हैं। यहाँ एक त्वरित और गंदा जेनेरिक "Canvas2PNG" बुकमार्कलेट है जो पृष्ठ के पहले कैनवास को PNG में परिवर्तित करता है और इसे ब्राउज़र में एक नई विंडो में प्रदर्शित करता है:javascript:void(window.open().location = document.getElementsByTagName("canvas")[0].toDataURL("image/png"))
Kai Carver

यदि छवि कुछ एमबी आकार की है, तो अपने ब्राउज़र को क्रैश करने की तैयारी करें (मैंने कुछ समय पहले ही फायरफॉक्स में किया था)।
जाहू मारा

1
यह कैसे कई छवियों को प्रस्तुत करने के लिए संशोधित किया जा सकता है?
मेंटलिस्ट

डेटा यूआरआई की अधिकतम लंबाई होती है, इसलिए एक छवि के आकार की ऊपरी सीमा होती है जिसे आप डेटा यूआरएल में डाल सकते हैं।
जूहा सिरजला

44

मुझे लगा कि मैं इस सवाल का दायरा थोड़ा बढ़ा दूंगा, इस मामले पर कुछ उपयोगी चिठ्ठियों के साथ।

चित्र के रूप में कैनवास प्राप्त करने के लिए, आपको निम्नलिखित कार्य करना चाहिए:

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

आप इसका उपयोग पृष्ठ पर चित्र लिखने के लिए कर सकते हैं:

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

जहां "छवि / पीएनजी" एक माइम प्रकार है (पीएनजी एकमात्र है जिसे समर्थित होना चाहिए)। यदि आप समर्थित प्रकारों की एक सरणी चाहते हैं, तो आप इस की तर्ज पर कुछ कर सकते हैं:

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;

यदि आप अलग-अलग माइम प्रकारों का उपयोग कर रहे हैं, तो छवि / png दोनों उदाहरणों को बदलना सुनिश्चित करें, लेकिन छवि / ऑक्टेट-स्ट्रीम नहीं। यह भी ध्यान देने योग्य है कि यदि आप अपने कैनवास को रेंडर करने में किसी भी क्रॉस-डोमेन संसाधनों का उपयोग करते हैं, तो जब आप toDataUrl पद्धति का उपयोग करने का प्रयास करते हैं, तो आप एक सुरक्षा त्रुटि का सामना करेंगे।


1
फ़ाइल डाउनलोड करने के लिए आपके समाधान के साथ, मुझे उस सॉफ़्टवेयर का चयन करना होगा जिसे मैं उपयोग करना चाहता हूं, यह थोड़ा असंबद्ध है ... क्या माइम को फिर से डाउनलोड करने के रूप में एक बार फिर से डाउनलोड करने का एक तरीका है?
So4ne

1
@ So4ne मुझे ऐसा नहीं लगता, यह उपयोगकर्ता को डाउनलोड के लिए संकेत देने के लिए एक छवि / ऑक्टेट-स्ट्रीम होना चाहिए। यदि आप उस पंक्ति से छुटकारा पा लेते हैं, तो आप छवि को पुनर्निर्देशित करने वाले पृष्ठ के साथ समाप्त हो जाएंगे। मुझे यह जानना अच्छा लगेगा कि क्या कोई और इसे अच्छी तरह से करना जानता है, हालाँकि।
मेयोनेज़ोम

2
<a> लिंक और .click () पर काम = "_ रिक्त" का उपयोग करना, यह भी काम करना चाहिए, डाउनलोड को ट्रिगर करने के लिए (परीक्षण के साथ एफएफ डेटा-यूआरएल और डाउनलोड = पाठ / सीएसवी और पाठ / सादे के लिए "फ़ाइल नाम")
Ax3x

यह भी खूब रही। धन्यवाद! लेकिन क्या होगा अगर मैं सर्वर को बचाना चाहता हूं और स्थानीय नहीं? क्या एक फॉर्म फाइल इनपुट img src को किसी ऐसी चीज के रूप में स्वीकार करेगा जो अपलोड करने योग्य है?
मुख्य रसायनज्ञ

उफ़। बस जवाब मिल गया। पिछले प्रश्न को छोड़कर मामले में किसी और के रूप में अच्छी तरह से दिख रहा है stackoverflow.com/questions/13198131/…
मुख्य रसायनज्ञ

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 प्रारूप में रहती है। इसे पींग के रूप में कैसे बचाया जाए?
nullpointer

यह एक अच्छा समाधान है सिवाय इसके कि यह IE पर काम नहीं कर सकता है। त्रुटि हो रही है "एक सिस्टम कॉल के लिए पारित डेटा क्षेत्र बहुत छोटा है"
जोस चेरियन

क्रोम में यह "नेटवर्क एरर" कहता है, जबकि फ़ायरफ़ॉक्स में यह बढ़िया काम करता है। (लिनक्स पर)
Ecker00

20

मैं " wkhtmltopdf " का उपयोग करूंगा । यह सिर्फ महान काम करता है। यह वेबकिट इंजन (क्रोम, सफारी, आदि में प्रयुक्त) का उपयोग करता है, और इसका उपयोग करना बहुत आसान है:

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

बस!

कोशिश करो


1
मैं wttmltopdf शिविर में भी हूँ। हम इसे संग्रह करने और इसके अद्भुत उपयोग के लिए उपयोग कर रहे हैं।
डैनियल स्जैबो

लॉगिन जानकारी की आवश्यकता वाले पृष्ठ में WKHTMLtoPDF का उपयोग कैसे करें? मैं पीडीएफ में बदलने के लिए Jsreport का उपयोग कर रहा हूं, लेकिन मैं HTML2Canvas के साथ अपनी सामग्री पर कब्जा कर लेता हूं, मेरे पास 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)));

जेपीईजी के रूप में -एक्सपोर्ट छवि

$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();

-साथ ही पारदर्शी पीएनजी

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

9

एक और दिलचस्प समाधान फैंटमजस है । यह जावास्क्रिप्ट या CoffeeScript के साथ एक मुखर WebKit स्क्रिप्ट करने योग्य है।

उपयोग के मामले में से एक स्क्रीन कैप्चर है: आप क्रमिक रूप से SVG और कैनवास और / या थंबनेल पूर्वावलोकन के साथ वेब साइट स्क्रीनशॉट सहित वेब सामग्री पर कब्जा कर सकते हैं।

सबसे अच्छा प्रवेश बिंदु स्क्रीन कैप्चर विकी पृष्ठ है।

यहाँ ध्रुवीय घड़ी के लिए एक अच्छा उदाहरण है (राफेलजेएस से):

>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: फैंटमजस इस काम के लिए सरल, अच्छी तरह से प्रलेखित और अच्छी तरह से सोची-समझी प्रणाली है। यह बहुत अधिक सिर्फ एक कैनवास को हथियाने की तुलना में बहुत अधिक अनुमति देता है - उदाहरण के लिए, आप इसे हथियाने से पहले पृष्ठ या उसके हिस्से (जेएस के माध्यम से) को संशोधित कर सकते हैं, ताकि आप इसे उसी तरह से देख सकें जैसे आप इसे चाहते हैं। उत्तम!
जॉन्डोडो

1
फैंटमज अब अप्रचलित है
Merc

3

यदि आप jQuery का उपयोग कर रहे हैं, जो कि बहुत सारे लोग करते हैं, तो आप इस तरह स्वीकृत उत्तर को लागू करेंगे:

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

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

12
ध्यान दें कि यहां jQuery का एकमात्र उपयोग कैनवास का चयन है। .toDataURLमूल जेएस है।
j6m8

मेरे पास इस समस्या को बचाने के लिए कोई है जो मुझे इस लिंक को देखने में मदद कर सकता है: stackoverflow.com/questions/25131763/…
रमेश एस

2
शुद्ध (100%) jQuery समाधान निम्नलिखित है: $('<img>').attr('src',$('#mycanvas')[0].toDataURL('image/png')).appendTo($('#element-to-write-to').empty());बिल्कुल एक पंक्ति।
नील मकसूदोव

1

आप इस तरह से एक छवि या पीडीएफ में एक कैनवास पर कब्जा करने के लिए jspdf का उपयोग कर सकते हैं:

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

यह दूसरा तरीका है, बिना तार के हालांकि मैं वास्तव में नहीं जानता कि यह तेज है या नहीं। इसके बजायDataURL (यहाँ सभी सवालों के प्रस्ताव के रूप में)। मेरे मामले में जब मैं एक ऐरे बफर या दृश्य की जरूरत है, डेटायूआरएल / बेस 64 को रोकना चाहता हूं। तो HTMLCanvasElement में दूसरी विधि है toBlob। (टाइपस्क्रिप्ट फ़ंक्शन):

    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));
}

ब्लॉब्स का एक और फायदा यह है कि आप HTMLInputFile के 'files' सदस्य के समान डेटा को फाइलों के रूप में दर्शाने के लिए ObjectUrls बना सकते हैं। और जानकारी:

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


-1

क्रोम के कुछ संस्करणों पर, आप यह कर सकते हैं:

  1. ड्रा छवि फ़ंक्शन का उपयोग करें ctx.drawImage(image1, 0, 0, w, h);
  2. कैनवास पर राइट-क्लिक करें
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.