web-dev-qa-db-fra.com

Canvas HTML5 en fichier PNG

J'essaie de convertir une toile HTML5 en une image. C'est ce que j'ai eu jusqu'à présent:

var tmp_canvas = document.getElementById('canvas');
var dataURL = tmp_canvas.toDataURL("image/png");
$('#thumbnail_list').append($('<img/>', { src : dataURL }).addClass('image'));

mais le problème est que je reçois ce code:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAEsCAYAAADtt+XCAAAgAElEQVR4nNS6Z1xVaZbvv/c+CVOZc6mYEMlJMZRizgljGRARs6AgOSMGQATBSM5ZyTkoOQkSzJWrp3t6etLt6Z7pmf/c++L7f3EOiBZW2dM9dz73xfdzztl7n3Oe/Txrrd9a69mCTC4gkwvIZAKSTECUBARRQBA+jii+46f.......class="image">

Je veux un chemin d'image normal que l'utilisateur peut télécharger!

De l'aide?

45
Test Test

Info: IE10 + ne prend pas en charge la méthode ci-dessous. D'autres personnes ont déjà effectué le travail et mis en œuvre des solutions multi-navigateurs . This est l'un d'entre eux.

Tout d'abord, ajoutez l'URL de données générée à l'attribut href d'une balise <a> . Toutefois, sur certains navigateurs, cela seul ne déclenchera pas de téléchargement. Au lieu de cela, il ouvrira l'image liée dans une nouvelle page.

Boîte de dialogue de téléchargement pour une image base64:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...." class="image" />

En vous basant sur l'exemple ci-dessus, convertissez le type MIME de l'URL de données en ceci:

<a href="data:application/octet-stream;base64,iVBORw0KGgoAAAANSUhEUg....">Download</a>

En indiquant au navigateur que les données sont application/octet-stream, il vous demandera de les sauvegarder sur votre disque dur.


Spécifier un nom de fichier:

Comme Adi dans les commentaires ci-dessous, il n'existe pas de méthode standard pour définir un nom de fichier à l'aide de cette méthode. Mais, il existe deux approches qui pourraient fonctionner dans certains navigateurs.

A) L'attribut download introduit par Google Crome

<a download="image.png" href="...">

B) Définition des en-têtes HTTP dans l'URL de données
headers=Content-Disposition: attachment; filename=image.png

<a href="data:application/octet-stream;headers=Content-Disposition%3A%20attachment%3B%20filename=image.png;base64,iVBORw0KGgoAAAA">

Cela a fonctionné au moins dans certaines versions plus anciennes d'Opera. Voici une discussion à ce sujet.

En examinant les systèmes de bogues/de suivi des fonctionnalités des principaux navigateurs, on constate que définir un nom de fichier est un grand souhait de la communauté. Nous verrons peut-être une solution compatible entre plusieurs navigateurs dans un proche avenir! ;)


Enregistrer RAM et ressources CPU:

Si vous ne souhaitez pas surcharger la RAM du navigateur de votre visiteur, vous pouvez également générer l'URL de données de manière dynamique:

<a id="dl" download="Canvas.png">Download Canvas</a>
function dlCanvas() {
    var dt = canvas.toDataURL('image/png');
    this.href = dt;
};
dl.addEventListener('click', dlCanvas, false);

De cette façon, votre navigateur peut toujours afficher le canevas en tant que fichier image . Si vous souhaitez augmenter la probabilité d'ouvrir une boîte de dialogue de téléchargement, vous devez étendre la fonction ci-dessus, de sorte que le remplacement s'effectue comme indiqué ci-dessus:

function dlCanvas() {
    var dt = canvas.toDataURL('image/png');
    this.href = dt.replace(/^data:image\/[^;]/, 'data:application/octet-stream');
};
dl.addEventListener('click', dlCanvas, false);

Enfin, ajoutez l'en-tête HTTP pour vous assurer que la plupart des navigateurs vous proposent un nom de fichier valide! ;)


EXEMPLE COMPLET:
var canvas = document.getElementById("cnv");
var ctx = canvas.getContext("2d");

/* FILL CANVAS WITH IMAGE DATA */
function r(ctx, x, y, w, h, c) {
  ctx.beginPath();
  ctx.rect(x, y, w, h);
  ctx.strokeStyle = c;
  ctx.stroke();
}
r(ctx, 0, 0, 32, 32, "black");
r(ctx, 4, 4, 16, 16, "red");
r(ctx, 8, 8, 16, 16, "green");
r(ctx, 12, 12, 16, 16, "blue");

/* REGISTER DOWNLOAD HANDLER */
/* Only convert the canvas to Data URL when the user clicks. 
   This saves RAM and CPU ressources in case this feature is not required. */
function dlCanvas() {
  var dt = canvas.toDataURL('image/png');
  /* Change MIME type to trick the browser to downlaod the file instead of displaying it */
  dt = dt.replace(/^data:image\/[^;]*/, 'data:application/octet-stream');

  /* In addition to <a>'s "download" attribute, you can define HTTP-style headers */
  dt = dt.replace(/^data:application\/octet-stream/, 'data:application/octet-stream;headers=Content-Disposition%3A%20attachment%3B%20filename=Canvas.png');

  this.href = dt;
};
document.getElementById("dl").addEventListener('click', dlCanvas, false);
<canvas id="cnv" width="32" height="32"></canvas>
<a id="dl" download="Canvas.png" href="#">Download Canvas</a>

81
Nippey

Vous pouvez utiliser la bibliothèque reimg pour convertir le canevas en objet image et même déclencher le téléchargement pour l'utilisateur.

Après avoir inséré la bibliothèque dans votre page, utilisez simplement ceci: ReImg.fromCanvas(yourCanvasElement).downloadPng()

6
gillyb

Vous avez 2 options (les deux fonctionnent sur presque tous les navigateurs):

1- POST les données sur le serveur:
Sur le serveur, vous disposerez d’un script qui gérera les données, puis demandera au navigateur d’inviter l’utilisateur au téléchargement.

header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=something.png");
header("Content-Type: image/png");
echo base64_decode($_POST['imageData']);
exit;

2- Demander le téléchargement à l’utilisateur en utilisantDownloadify

<div id="clickMe"></div>

Downloadify.create( 'clickMe', {
   data: base64String,
   dataType: 'base64',
   filename: 'something.png'
});
5
Adi

Vous pouvez également envisager d’utiliser Concrete.js http://www.concretejs.com , qui est un framework HTML5 Canvas très léger qui permet des opérations de ce type, comme les téléchargements. Vous voudriez juste faire ceci:

canvas.download({
  fileName: 'my-file.png'
});

et tu as fini.

0
Eric Rowell