Come salvare la tela come immagine con canvas.toDataURL ()?


141

Attualmente sto creando un'app Web HTML5 / un'app nativa Phonegap e non riesco a capire come salvare la mia tela come immagine con canvas.toDataURL(). Qualcuno può darmi una mano?

Ecco il codice, cosa c'è che non va?

// La mia tela è stata chiamata "canvasSignature"

JavaScript:


function putImage()
{
  var canvas1 = document.getElementById("canvasSignature");        
  if (canvas1.getContext) {
     var ctx = canvas1.getContext("2d");                
     var myImage = canvas1.toDataURL("image/png");      
  }
  var imageElement = document.getElementById("MyPix");  
  imageElement.src = myImage;                           

}  

HTML5:


<div id="createPNGButton">
    <button onclick="putImage()">Save as Image</button>        
</div>

4
La domanda di OP non ha ricevuto risposta. Ha detto chiaramente che questo è per Phonegap / iPad. Le risposte fornite sono per il salvataggio su un browser desktop.
tshm001,

1
Non sono sicuro di phonegap, ma l'ho fatto da zero in iOS nativo usando JavaScript dall'altra parte, acquisisco i dati con .toDataURL(), quindi uso window.location per puntare il browser appname://[data url]. Sul lato app, UIWebView ha un metodo delegato che dice se deve o meno caricare una pagina. Lo ascolto appname://e lo interrompo quando arriva, rifiuto il caricamento della pagina e acquisisco l'URL dei dati in una stringa nativa ... quanto conosci il codice iOS / Obiettivo C attuale?
Doug,

Risposte:


121

Ecco un po 'di codice. senza alcun errore.

var image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");  // here is the most important part because if you dont replace you will get a DOM 18 exception.


window.location.href=image; // it will save locally

1
Tranne in modalità standard IE9: "Alcuni contenuti o file in questa pagina Web richiedono un programma che non è stato installato." Internet Explorer 8 e versioni successive supportano solo URI di dati per immagini in CSS, <link> e <img>: developer.mozilla.org/en-US/docs/data_URIs
Cees Timmerman,

45
funziona bene. come posso cambiare il nome del file scaricato? sta arrivando solo "download" e senza estensione. Grazie!
Leabdalla,

1
In Chrome questo si blocca il browser. Se visualizzo l'immagine in un tag immagine, funziona ma il menu di scelta rapida è disattivato, quindi non riesco ancora a salvare l'immagine.
Kokodoko,

Funziona benissimo ... Ma in Android (browser predefinito in Galaxy S3) non scarica l'immagine, ma ricevo il messaggio "Download ..." per sempre.
Habrashat,

Ho un problema di salvataggio che qualcuno può aiutarmi a vedere questo link: stackoverflow.com/questions/25131763/…
Ramesh S

36

Questa soluzione consente di modificare il nome del file scaricato:

HTML:

<a id="link"></a>

Javascript:

  var link = document.getElementById('link');
  link.setAttribute('download', 'MintyPaper.png');
  link.setAttribute('href', canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"));
  link.click();

Grazie per questo, mi ha aiutato moltissimo!
Mike Moon,

22

È possibile utilizzare canvas2image per richiedere il download.

Ho avuto lo stesso problema, ecco un semplice esempio che aggiunge l'immagine alla pagina e forza il browser a scaricarla:

<html>
    <head>
        <script src="http://hongru.github.io/proj/canvas2image/canvas2image.js"></script>
        <script>
            function draw(){
                var canvas = document.getElementById("thecanvas");
                var ctx = canvas.getContext("2d");
                ctx.fillStyle = "rgba(125, 46, 138, 0.5)";
                ctx.fillRect(25,25,100,100); 
                ctx.fillStyle = "rgba( 0, 146, 38, 0.5)";
                ctx.fillRect(58, 74, 125, 100);
            }

            function to_image(){
                var canvas = document.getElementById("thecanvas");
                document.getElementById("theimage").src = canvas.toDataURL();
                Canvas2Image.saveAsPNG(canvas);
            }
        </script>
    </head>
    <body onload="draw()">
        <canvas width=200 height=200 id="thecanvas"></canvas>
        <div><button onclick="to_image()">Draw to Image</button></div>
        <image id="theimage"></image>
    </body>
</html>

2
Appena provato, salverà un file senza nome né estensione in Chrome.
Malber l'

come menzionato qui nihilogic.dk/labs/canvas2image non è possibile impostare il nome del file: "Sarebbe davvero bello se in qualche modo un nome file potesse essere allegato ai dati, ma non ho trovato alcun modo per farlo. Per ora, devi specificare tu stesso il nome del file. "
SColvin,

1
Il link che hai pubblicato è interrotto
Oliver Nybroe,

9

Puoi provare questo; creare un ancoraggio HTML fittizio e scaricare l'immagine da lì come ...

// Convert canvas to image
document.getElementById('btn-download').addEventListener("click", function(e) {
    var canvas = document.querySelector('#my-canvas');

    var dataURL = canvas.toDataURL("image/jpeg", 1.0);

    downloadImage(dataURL, 'my-canvas.jpeg');
});

// Save | Download image
function downloadImage(data, filename = 'untitled.jpeg') {
    var a = document.createElement('a');
    a.href = data;
    a.download = filename;
    document.body.appendChild(a);
    a.click();
}

1
Mi piace il fatto che tutto sia stato fatto in JS, inclusa la creazione dell'elemento link. Funziona alla grande per scopi di automazione
Jeromy Adofo

Soluzione perfetta
Hidayt Rahman,

8

Ho creato una piccola libreria che lo fa (insieme ad altre utili conversioni). Si chiama reimg ed è davvero semplice da usare.

ReImg.fromCanvas(yourCanvasElement).toPng()


Bella biblioteca. Grazie. C'è un piccolo problema nella documentazione di esempio però. Ho aperto un problema su Github per portarlo alla tua attenzione.
jmknoll,

7

Questo lavoro per me: (solo Google Chrome)

<html>
<head>
    <script>
            function draw(){
                var canvas = document.getElementById("thecanvas");
                var ctx = canvas.getContext("2d");
                ctx.fillStyle = "rgba(125, 46, 138, 0.5)";
                ctx.fillRect(25,25,100,100);
                ctx.fillStyle = "rgba( 0, 146, 38, 0.5)";
                ctx.fillRect(58, 74, 125, 100);
            }

            function downloadImage()
            {
                var canvas = document.getElementById("thecanvas");
                var image = canvas.toDataURL();

                var aLink = document.createElement('a');
                var evt = document.createEvent("HTMLEvents");
                evt.initEvent("click");
                aLink.download = 'image.png';
                aLink.href = image;
                aLink.dispatchEvent(evt);
            }
    </script>
</head>
<body onload="draw()">
    <canvas width=200 height=200 id="thecanvas"></canvas>
    <div><button onclick="downloadImage()">Download</button></div>
    <image id="theimage"></image>
</body>
</html>

Forse potresti spiegare la parte del tuo codice che risponde alla domanda invece di incollarla senza commenti?
Gediminas Masaitis,

6

Simile alla risposta di 1000Bugy ma più semplice perché non è necessario creare un ancoraggio al volo e inviare manualmente un evento clic (più una correzione IE).

Se rendi il tuo pulsante di download un ancoraggio, puoi lanciarlo prima che venga eseguita la funzionalità di ancoraggio predefinita. Quindi onAnchorClickpuoi impostare l'href di ancoraggio sull'immagine canvas base64 e l'attributo di download dell'ancoraggio su qualunque cosa tu voglia nominare la tua immagine.

Questo non funziona in IE (corrente) perché non implementa l'attributo download e impedisce il download di uris di dati. Ma questo può essere risolto usando window.navigator.msSaveBlobinvece.

Così il vostro gestore di eventi click ancoraggio sarebbe come segue (dove anchor, canvase fileNamesono le ricerche di ambito):

function onClickAnchor(e) {
  if (window.navigator.msSaveBlob) {
    window.navigator.msSaveBlob(canvas.msToBlob(), fileName);
    e.preventDefault();
  } else {
    anchor.setAttribute('download', fileName);
    anchor.setAttribute('href', canvas.toDataURL());
  }
}

Ecco un violino


1

Invece di imageElement.src = myImage;te dovresti usarewindow.location = myImage;

E anche dopo questo il browser visualizzerà l'immagine stessa. È possibile fare clic con il tasto destro del mouse e utilizzare "Salva collegamento" per scaricare l'immagine.

Controlla questo link per maggiori informazioni.


Wow, grazie, mi ha davvero aiutato molto :) Ma come si ottiene una finestra di salvataggio pop-up, in modo che qualcuno possa salvare su una destinazione specifica (come la cartella delle immagini Android)?
Wardenclyffe,

Dipende dal browser specifico. Il browser Android di solito scarica i file in una cartella specifica direttamente, per esempio.
Hakan Serce,

In Chrome funziona, ma il menu di scelta rapida è disattivato. Quando si tenta di "trascinare" l'immagine fuori dal browser, Chrome si arresta in modo anomalo.
Kokodoko,

groups.google.com/a/chromium.org/forum/#!topic/blink-dev/… L' apertura dell'URL dei dati in questo modo verrà bloccata a quanto pare.
KeyOfJ,

0

Non è possibile utilizzare i metodi precedentemente menzionati per scaricare un'immagine durante l'esecuzione in Cordova. Dovrai usare il Plugin File Cordova . Ciò ti consentirà di scegliere dove salvarlo e sfruttare diverse impostazioni di persistenza. Dettagli qui: https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/

In alternativa, puoi convertire l'immagine in base64 quindi archiviare la stringa in localStorage ma questo riempirà la tua quota abbastanza rapidamente se hai molte immagini o ad alta risoluzione.


-9

@Wardenclyffe e @SColvin, entrambi state provando a salvare l'immagine usando la tela, non usando il contesto della tela. entrambi dovresti provare a ctx.toDataURL (); Prova questo:

var canvas1 = document.getElementById("yourCanvasId");  <br>
var ctx = canvas1.getContext("2d");<br>
var img = new Image();<br>
img.src = ctx.toDataURL('image/png');<br>
ctx.drawImage(img,200,150);<br>

Inoltre puoi fare riferimento ai seguenti link:

http://tutorials.jenkov.com/html5-canvas/todataurl.html

http://www.w3.org/TR/2012/WD-html5-author-20120329/the-canvas-element.html#the-canvas-element


TypeError non rilevato: l'oggetto # <CanvasRenderingContext2D> non ha un metodo 'toDataURL'.
Brandon Aubie,

Questo è sbagliato in quanto l'elemento di contesto non ha una toDataURLfunzione: developer.mozilla.org/en-US/docs/Web/API/… . Vuoi chiamare toDataURLl'elemento canvas: developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/…
Crashalot
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.