webentwicklung-frage-antwort-db.com.de

HTML5 Canvas zu PNG-Datei

Ich versuche, eine HTML5-Leinwand in ein Bild zu konvertieren. Das habe ich bisher bekommen:

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

aber das Problem ist, dass ich diesen Code bekomme:

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

Ich möchte einen normalen Bildpfad, den der Benutzer herunterladen kann!

Irgendeine Hilfe?

45
Test Test

Info: IE10 + unterstützt die Methode unten nicht. Andere Leute haben bereits die Arbeit erledigt und Cross-Browser-Lösungen implementiert. This ist einer von ihnen.

Fügen Sie zunächst die generierte Daten-URL zum href-Attribut eines <a>-Tags ..__ hinzu. Bei einigen Browsern löst dies jedoch keinen Download aus. Stattdessen wird das verknüpfte Bild auf einer neuen Seite geöffnet.

Download-Dialog für ein base64-Image:

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

Konvertieren Sie den MIME-Typ der Daten-URL anhand des obigen Beispiels wie folgt:

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

Wenn Sie dem Browser mitteilen, dass die Daten application/octet-stream sind, werden Sie aufgefordert, die Daten auf Ihrer Festplatte zu speichern.


Dateiname angeben:

Wie Adi in den Kommentaren unten sagte, gibt es keine Standardmethode, um einen Dateinamen mit dieser Methode zu definieren. Es gibt jedoch zwei Ansätze, die in einigen Browsern funktionieren könnten.

A) Das von Google Crome eingeführte download-Attribut

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

B) Definieren von HTTP-Headern innerhalb der Daten-URL
headers=Content-Disposition: attachment; filename=image.png

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

Dies funktionierte zumindest in älteren Versionen von Opera. Here ist eine Diskussion darüber.

Ein Blick in die Bug-/Feature-Tracking-Systeme der wichtigsten Browser zeigt, dass die Definition eines Dateinamens ein großer Wunsch der Community ist. Vielleicht wird es in naher Zukunft eine browserübergreifende Lösung geben! ;)


Save RAM und CPU-Ressourcen:

Wenn Sie den RAM des Browsers Ihres Besuchers nicht aufblähen möchten, können Sie die Daten-URL auch dynamisch generieren:

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

Auf diese Weise wird Ihre Leinwand möglicherweise weiterhin als Bilddatei von Ihrem Browser angezeigt .. Wenn Sie die Wahrscheinlichkeit erhöhen möchten, dass ein Download-Dialogfeld geöffnet wird, sollten Sie die obige Funktion so erweitern, dass die Ersetzung wie oben gezeigt erfolgt:

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

Fügen Sie zuletzt den HTTP-Header hinzu, um sicherzustellen, dass die meisten Browser einen gültigen Dateinamen anbieten. ;)


VOLLES BEISPIEL:
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

Sie können die Bibliothek reimg verwenden, um die Leinwand in ein Bildobjekt zu konvertieren und sogar den Download für den Benutzer auszulösen.

Nachdem Sie die Bibliothek in Ihre Seite eingefügt haben, verwenden Sie einfach Folgendes: ReImg.fromCanvas(yourCanvasElement).downloadPng()

6
gillyb

Sie haben 2 Optionen (beide funktionieren in fast allen Browsern):

1- POST die Daten an den Server:
.__ Auf dem Server hätten Sie ein Skript, das die Daten verarbeitet und den Browser anweist, den Benutzer zum Herunterladen aufzufordern.

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

2- Benutzer mitDownloadify zum Download auffordern

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

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

Sie könnten auch die Verwendung von Concrete.js http://www.concretejs.com in Erwägung ziehen. Hierbei handelt es sich um ein leichtes HTML5-Canvas-Framework, das Peripheriegeräte wie das Herunterladen ermöglicht. Sie würden einfach das tun:

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

und du bist fertig.

0
Eric Rowell