2012-06-20 25 views
51

Mam element canvas z rysunkiem w nim i chcę utworzyć przycisk, który po kliknięciu zapisze obraz jako plik PNG. Tak powinno otworzyć się okno Zapisywanie, otwieranie, zamykanie dialogowe ...jak zapisać płótno jako obraz png?

to zrobić przy użyciu tego kodu

var canvas = document.getElementById("myCanvas"); 
window.open(canvas.toDataURL("image/png")); 

Ale kiedy przetestować go w IE9, nowe okno otwiera się powiedzenie „im strona nie może zostać wyświetlona” a URL to jest:

dane: image/png; base64, iVBORw0KGgoAAAANSUhEUgAAAmAAAABpCAYAAACd + 58xAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAADRwSURBVHhe7V0HgBVF0q7ZJSlJwRxAPUFRD39RFLN34qGnnomoqIjhzBlFPROIgsoZzogR5AQEzJ4BPFAUEUwgJjgQkCQKooggaf/6el6/6ZnpSW/zUn237u5MdXX1172 + z6rqaqeEG6VsJet + PDW/vkdrfx3H3yfT2tVzaP26X6hkw1q/Boei/280/29JwznZxJPUyXtBQBAQBAQ BQaBcECjefmi56BWlZYtAeqajx/WokfrJYEqOIikOFRfXoVq161PtOk2odu0t + ectqKiojnrntWhC46QhYOtXfUarl79Ivy9/ldau + H + TX/8b2SbjJ07pWFQy2Uqnp2yXSrQJAoKAICAICALJCAgBS8ao8iTi/UvpSZlBxiwqwWOKimsxCWtEdettR3XqbEfFtRonkrBYArZh3fe0 + senadWyEbRm1UzasP53K45ZiFc84RKyVXkbVUYWBAQBQUAQyIqAELCsiFW2fDQpSyZk8UQMMysqKmaPWCOqt8mOVK/eTuQU1YuccCQBW7dyIq38/j 5a/fn/ad3a5QGXmqsvLfGKJl0ZCFdONEOPyl5lGV8QEAQEAUGghiMgBKzqLHCeHqVOrILtduF4MpZExEqoVq167A3bmjap34J/bmoFqcj2dM3Pr9GK + b1p5bJXmXz9nEC + 3FiorYF4hcmXlo + Gurk + um/+ e + QoVWfxxRJBQBAQBAQBQUAQqBwE8uzCwiMiaEqOWYR5jJ2/6Hl58nYHk0Pr1v1Ov62cTytXfE5r1yyyc6RgDhjI16 + L + tLqFZ9xnteGUKc0Xi876YpYkFDCfpqFEz9YGpRERhAQBAQBQaB8ERAPWPnim157JreX6/eK7eJ/Ge0RS8oPc9gT1pTqN2jFocltfdPxecBU2HHxgBTky + 71CjPGCO + YyU4j0TU9ZcGf0y + JSAoCgoAgIAgIAoJATUcgG2dQ0jpKZ/XP + PlLtEcs3huGQhO/r17K3rBvuGrEUt8i5HPAkHC/Yt6lKuwYKiuRM9TtGbY0rcerTBLwC/KY1fSNJ/MTBAQBQUAQqAwExANWGaiHx0z2aJl9CknET + MRc2XsVSKKaNP6O1CDhvtwYn5dJZf3gOG0IxLuS0e LB4vw9sVhiwmHywmF6xqLLdYIQgIAoKAICAICAJVAQHTo2XmkNtzv6K5R7RXLOwRs3MaW + + 5 + 47SNkG9oRxZQmun6qbImCo84VSE PR3/zvFZJni/7e8tTHiCeqCkAqsKKig2CgCAgCAgCgoAgUG0RCBKzMLmwkzHdL4pk4XlUAn7Uu3XrVtPqVfO4lurPSq0KQa5cdAv9snBgqM5XFPlKSsSPM8o3mcxES2hZtf0rEMMFAUFAEKiBCEgIsqotavpk/OiwZViHPQk/LgHfHo5EnbCGjVpxeYo9yNmw9oeSn2YeTatWTPNzozzX8ZOeWPJlJVRJnrOoxUtJtmLEUmqoartH7BEEBAFBQBCoJggIASu/hUqkUokC2rZkwSSCBU12wpadhNXbpAk13vwwKlJ3O/L1QmYrxPNlDxuGyVtyIn6K8KSZHwY3XsRX + W0L0VyTEPjwM6KuFxN1uiB6Vkv48MpdjxLt9ieieQvscuvWE13eh2jnQ9zv + F2aICAICAKCQGEIRH22559H5IqnDTMGeU/SgUJ7WNLjOVH9g8/Xrv2Fa4P9SM6K7y4t + WXRw76sfVc42fPV936iJ5 + LKrbqTU0P3rA + 0dZbEh20L9HJHYj23I2oVrHFT5U5NFnY4m6svUA0Pvo8efbvjCBqtr0nN + IVot4Dkvv1v5aoy/HJcpUpsfI3olffdknV0uWuJfv9kWjkw55VIFAfM073PE4EkqZbEBf9HMTs8C6e3KhHiPbdqzJnKWMLAoJAeSMgHrDyRrj0 + rOEGvVoYY9Y0inIeE + YQQ + cqGGj3dgDtvJjC/mKm7BHmG68lGjO + 0T

ktoś wie jak to naprawić to?

+0

możliwe duplikat [Jak zapisać kanwę SVG do lokalnego systemu plików] (http://stackoverflow.com/questions/2483919/how-to-save-svg-canvas-to-local-filesystem) – Philipp

Odpowiedz

45

spróbuj tego:

var c=document.getElementById("alpha"); 
var d=c.toDataURL("image/png"); 
var w=window.open('about:blank','image from canvas'); 
w.document.write("<img src='"+d+"' alt='from canvas'/>"); 

To pokazuje obraz z płótna na nowej stronie, ale jeśli masz open popup in new tab ustawienie pokazuje about:blank w pasku adresu.

EDIT: - chociaż window.open("<img src='"+ c.toDataURL('image/png') +"'/>") nie działa w FF lub Chrome następujące prace chociaż renderowania różni się nieco od tego, co jest pokazane na płótnie, myślę, że przejrzystość jest kwestia:

window.open(c.toDataURL('image/png')); 
+0

ta działa tylko dobrze: http://jsfiddle.net/VVN8X/1/ – Blender

+0

to zawiesza się na tym poleceniu: var w = window.open ("about: blank", "image from canvas"); – sneaky

+3

Zmieniłem to na: var w = window.open ('about: blank') ;, a teraz obraz otwiera się w nowym oknie, ale jak mogę to zrobić, aby zamknąć okno zapisu, nie? t chcesz kliknąć prawym przyciskiem myszy obraz i nacisnąć Zapisz jako ... – sneaky

20

FileSaver.js powinien móc pomóżcie tutaj.

var canvas = document.getElementById("my-canvas"); 
// draw to canvas... 
canvas.toBlob(function(blob) { 
    saveAs(blob, "pretty image.png"); 
}); 
+0

to nie wydaje się działać w IE9, http://eligrey.com/demos/FileSaver.js/ – sneaky

+10

Jest wiele rzeczy, które nie działają w IE9 :-(Dość trochę można naprawić za pomocą polyfills, ale obawiam się, że jest to poza tym. czy mogę zaproponować używanie Google Chrome Frame dla użytkowników korzystających z IE – Maurice

+0

Działa doskonale – isuru

2

Być może odkryłem lepszy sposób na nie zmuszanie użytkownika do kliknięcia prawym przyciskiem myszy "zapisz obraz jako". po prostu na żywo narysuj podstawowy kod base64 w hrefu łącza i zmodyfikuj go, aby pobieranie rozpoczęło się automatycznie. Nie wiem, czy jego uniwersalna przeglądarka jest kompatybilna, ale powinna działać z głównymi/nowymi przeglądarkami.

var canvas = document.getElementById('your-canvas'); 
    if (canvas.getContext) { 
     var C = canvas.getContext('2d'); 
    } 

$('#your-canvas').mousedown(function(event) { 
    // feel free to choose your event ;) 

    // just for example 
    // var OFFSET = $(this).offset(); 
    // var x = event.pageX - OFFSET.left; 
    // var y = event.pageY - OFFSET.top; 

    // standard data to url 
    var imgdata = canvas.toDataURL('image/png'); 
    // modify the dataUrl so the browser starts downloading it instead of just showing it 
    var newdata = imgdata.replace(/^data:image\/png/,'data:application/octet-stream'); 
    // give the link the values it needs 
     $('a.linkwithnewattr').attr('download','your_pic_name.png').attr('href',newdata); 

}); 

czuć się swobodnie owinąć A wokół cokolwiek chcesz, nadziei, który pomaga nieco

+1

atrybutem pobierania nie jest przeglądarka internetowa http://caniuse.com/download –

8

Użyłem tego rozwiązania, aby ustawić nazwę plików:

HTML:

<a href="#" id="downloader" onclick="download()" download="image.png">Download!</a> 
<canvas id="canvas"></canvas> 

JavaScript:

function download(){ 
    document.getElementById("downloader").download = "image.png"; 
    document.getElementById("downloader").href = document.getElementById("canvas").toDataURL("image/png").replace(/^data:image\/[^;]/, 'data:application/octet-stream'); 
} 
0

Spróbuj tego:

jQuery('body').after('<a id="Download" target="_blank">Click Here</a>'); 

var canvas = document.getElementById('canvasID'); 
var ctx = canvas.getContext('2d'); 

document.getElementById('Download').addEventListener('click', function() { 
    downloadCanvas(this, 'canvas', 'test.png'); 
}, false); 

function downloadCanvas(link, canvasId, filename) { 
    link.href = document.getElementById(canvasId).toDataURL(); 
    link.Download = filename; 
} 

można po prostu umieścić ten kod w konsoli Firefox lub chrom i po zmienił tagu canvas ID w tym powyższego skryptu i uruchomić ten skrypt w konsoli.

Po wykonaniu tego kodu zobaczysz link jako tekst "kliknij tutaj" u dołu strony html. kliknij ten link i otwórz rysunek canvas jako obraz PNG w nowym oknie, zapisz obraz.

3

miałem ten problem i jest to najlepsze rozwiązanie bez jakichkolwiek zewnętrznych lub dodatkowych bibliotek Scenariusz: w tagach JavaScript lub pliku utworzyć tę funkcję: Zakładamy tutaj, że płótno to płótno:

function download(){ 
     var download = document.getElementById("download"); 
     var image = document.getElementById("canvas").toDataURL("image/png") 
        .replace("image/png", "image/octet-stream"); 
     download.setAttribute("href", image); 

    } 

W część ciała twojego HTML określa przycisk:

<a id="download" download="image.png"><button type="button" onClick="download()">Download</button></a> 

To działa, a łącze pobierania wygląda jak przycisk. Testowane w Firefoksie i Chrome.

+0

Niestety, w IE 11 czyści ekran i zmienia adres URL na: dane: image/oktet-stream; base64, iVBORw – Mike

0

Prześlij formularz, który zawiera wejście z wartości toDataURL płótnie ('image/png') np

// obsługa JavaScript

var canvas = document.getElementById("canvas"); 
    var url = canvas.toDataUrl('image/png'); 

Włóż wartość adres URL do ukrytego wejścia na formularzu element.

// PHP

$data = $_POST['photo']; 
    $data = str_replace('data:image/png;base64,', '', $data); 
    $data = base64_decode($data); 
    file_put_contents("i". rand(0, 50).".png", $data); 
+0

To działa ładnie, z wyjątkiem funkcji JavaScript 'canvas.toDataUrl (...)' powinno być 'canvas.toDataURL (...) '. – Brannon

-1
var canvasId = chart.id + '-canvas'; 
var canvasDownloadId = chart.id + '-download-canvas'; 
var canvasHtml = Ext.String.format('<canvas id="{0}" width="{1}" height="{2}"></canvas><a id="{3}"/>', 
canvasId, 
chart.getWidth(), 
chart.getHeight(), 
canvasDownloadId); 
var canvasElement = reportBuilder.add({ html: canvasHtml }); 

var canvas = document.getElementById(canvasId); 

var canvasDownload = document.getElementById(canvasDownloadId); 
canvasDownload.href = chart.getImage().data; 
canvasDownload.download = 'chart'; 

canvasDownload.click(); 
0

Pełny kod HTML Working. Cut + Wklej do nowego pliku .html:

Zawiera dwa przykłady:

  1. plandeki w pliku HTML.
  2. Kanwa dynamicznie utworzona za pomocą Javascript.

testowane w:

  1. Chrome
  2. Internet Explorer
  3. * Krawędź (nazwa tytuł nie pojawi)
  4. Firefox
  5. Opera

<!DOCTYPE HTML > 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <title> #SAVE_CANVAS_TEST# </title> 
    <meta 
     name ="author" 
     content="John Mark Isaac Madison" 
    > 
    <!-- EMAIL: J4M4I5M7 -[AT]- Hotmail.com --> 
</head> 
<body> 

<div id="about_the_code"> 
    Illustrates: 
    <ol> 
    <li>How to save a canvas from HTML page.  </li> 
    <li>How to save a dynamically created canvas.</li> 
    </ol> 
</div> 

<canvas id="DOM_CANVAS" 
     width ="300" 
     height="300" 
></canvas> 

<div id="controls"> 
    <button type="button" style="width:300px;" 
      onclick="obj.SAVE_CANVAS()"> 
     SAVE_CANVAS (Dynamically Made Canvas) 
    </button> 

    <button type="button" style="width:300px;" 
      onclick="obj.SAVE_CANVAS('DOM_CANVAS')"> 
     SAVE_CANVAS (Canvas In HTML Code) 
    </button> 
</div> 

<script> 
var obj = new MyTestCodeClass(); 
function MyTestCodeClass(){ 

    //Publically exposed functions: 
    this.SAVE_CANVAS = SAVE_CANVAS; 

    //:Private: 
    var _canvas; 
    var _canvas_id = "ID_OF_DYNAMIC_CANVAS"; 
    var _name_hash_counter = 0; 

    //:Create Canvas: 
    (function _constructor(){ 
     var D = document; 
     var CE = D.createElement.bind(D); 
     _canvas = CE("canvas"); 
     _canvas.width = 300; 
     _canvas.height= 300; 
     _canvas.id = _canvas_id; 
    })(); 

    //:Before saving the canvas, fill it so 
    //:we can see it. For demonstration of code. 
    function _fillCanvas(input_canvas, r,g,b){ 
     var ctx = input_canvas.getContext("2d"); 
     var c = input_canvas; 

     ctx.fillStyle = "rgb("+r+","+g+","+b+")"; 
     ctx.fillRect(0, 0, c.width, c.height); 
    } 

    //:Saves canvas. If optional_id supplied, 
    //:will save canvas off the DOM. If not, 
    //:will save the dynamically created canvas. 
    function SAVE_CANVAS(optional_id){ 

     var c = _getCanvas(optional_id); 

     //:Debug Code: Color canvas from DOM 
     //:green, internal canvas red. 
     if(optional_id){ 
      _fillCanvas(c,0,255,0); 
     }else{ 
      _fillCanvas(c,255,0,0); 
     } 

     _saveCanvas(c); 
    } 

    //:If optional_id supplied, get canvas 
    //:from DOM. Else, get internal dynamically 
    //:created canvas. 
    function _getCanvas(optional_id){ 
     var c = null; //:canvas. 
     if(typeof optional_id == "string"){ 
      var id = optional_id; 
      var d = document; 
      var c = d.getElementById(id); 
     }else{ 
      c = _canvas; 
     } 
     return c; 
    } 

    function _saveCanvas(canvas){ 
     if(!window){ alert("[WINDOW_IS_NULL]"); } 

     //:We want to give the window a unique 
     //:name so that we can save multiple times 
     //:without having to close previous 
     //:windows. 
     _name_hash_counter++    ; 
     var NHC = _name_hash_counter  ; 
     var URL = 'about:blank'   ; 
     var name= 'UNIQUE_WINDOW_ID' + NHC; 
     var w=window.open(URL, name) ; 

     if(!w){ alert("[W_IS_NULL]");} 

     //:Create the page contents, 
     //:THEN set the tile. Order Matters. 
     var DW = ""      ; 
     DW += "<img src='"     ; 
     DW += canvas.toDataURL("image/png"); 
     DW += "' alt='from canvas'/>"  ; 
     w.document.write(DW)    ; 
     w.document.title = "NHC"+NHC  ; 

    } 

}//:end class 

</script> 

</body> 
<!-- In IE: Script cannot be outside of body. --> 
</html> 
Powiązane problemy