2012-10-09 7 views
9

Ich unsing die canvas2Image.js Plugin:Canavas2Image.js speichern base64 img als png über das Element klicken

/* 
* Canvas2Image v0.1 
* Copyright (c) 2008 Jacob Seidelin, [email protected] 
* MIT License [http://www.opensource.org/licenses/mit-license.php] 
*/ 

var Canvas2Image = (function() { 

    // check if we have canvas support 
    var bHasCanvas = false; 
    var oCanvas = document.createElement("canvas"); 
    if (oCanvas.getContext("2d")) { 
     bHasCanvas = true; 
    } 

    // no canvas, bail out. 
    if (!bHasCanvas) { 
     return { 
      saveAsBMP : function(){}, 
      saveAsPNG : function(){}, 
      saveAsJPEG : function(){} 
     } 
    } 

    var bHasImageData = !!(oCanvas.getContext("2d").getImageData); 
    var bHasDataURL = !!(oCanvas.toDataURL); 
    var bHasBase64 = !!(window.btoa); 

    var strDownloadMime = "image/octet-stream"; 

    // ok, we're good 
    var readCanvasData = function(oCanvas) { 
     var iWidth = parseInt(oCanvas.width); 
     var iHeight = parseInt(oCanvas.height); 
     return oCanvas.getContext("2d").getImageData(0,0,iWidth,iHeight); 
    } 

    // base64 encodes either a string or an array of charcodes 
    var encodeData = function(data) { 
     var strData = ""; 
     if (typeof data == "string") { 
      strData = data; 
     } else { 
      var aData = data; 
      for (var i=0;i<aData.length;i++) { 
       strData += String.fromCharCode(aData[i]); 
      } 
     } 
     return btoa(strData); 
    } 

    // creates a base64 encoded string containing BMP data 
    // takes an imagedata object as argument 
    /*var createBMP = function(oData) { 
     var aHeader = []; 

     var iWidth = oData.width; 
     var iHeight = oData.height; 

     aHeader.push(0x42); // magic 1 
     aHeader.push(0x4D); 

     var iFileSize = iWidth*iHeight*3 + 54; // total header size = 54 bytes 
     aHeader.push(iFileSize % 256); iFileSize = Math.floor(iFileSize/256); 
     aHeader.push(iFileSize % 256); iFileSize = Math.floor(iFileSize/256); 
     aHeader.push(iFileSize % 256); iFileSize = Math.floor(iFileSize/256); 
     aHeader.push(iFileSize % 256); 

     aHeader.push(0); // reserved 
     aHeader.push(0); 
     aHeader.push(0); // reserved 
     aHeader.push(0); 

     aHeader.push(54); // dataoffset 
     aHeader.push(0); 
     aHeader.push(0); 
     aHeader.push(0); 

     var aInfoHeader = []; 
     aInfoHeader.push(40); // info header size 
     aInfoHeader.push(0); 
     aInfoHeader.push(0); 
     aInfoHeader.push(0); 

     var iImageWidth = iWidth; 
     aInfoHeader.push(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth/256); 
     aInfoHeader.push(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth/256); 
     aInfoHeader.push(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth/256); 
     aInfoHeader.push(iImageWidth % 256); 

     var iImageHeight = iHeight; 
     aInfoHeader.push(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight/256); 
     aInfoHeader.push(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight/256); 
     aInfoHeader.push(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight/256); 
     aInfoHeader.push(iImageHeight % 256); 

     aInfoHeader.push(1); // num of planes 
     aInfoHeader.push(0); 

     aInfoHeader.push(24); // num of bits per pixel 
     aInfoHeader.push(0); 

     aInfoHeader.push(0); // compression = none 
     aInfoHeader.push(0); 
     aInfoHeader.push(0); 
     aInfoHeader.push(0); 

     var iDataSize = iWidth*iHeight*3; 
     aInfoHeader.push(iDataSize % 256); iDataSize = Math.floor(iDataSize/256); 
     aInfoHeader.push(iDataSize % 256); iDataSize = Math.floor(iDataSize/256); 
     aInfoHeader.push(iDataSize % 256); iDataSize = Math.floor(iDataSize/256); 
     aInfoHeader.push(iDataSize % 256); 

     for (var i=0;i<16;i++) { 
      aInfoHeader.push(0); // these bytes not used 
     } 

     var iPadding = (4 - ((iWidth * 3) % 4)) % 4; 

     var aImgData = oData.data; 

     var strPixelData = ""; 
     var y = iHeight; 
     do { 
      var iOffsetY = iWidth*(y-1)*4; 
      var strPixelRow = ""; 
      for (var x=0;x<iWidth;x++) { 
       var iOffsetX = 4*x; 

       strPixelRow += String.fromCharCode(aImgData[iOffsetY+iOffsetX+2]); 
       strPixelRow += String.fromCharCode(aImgData[iOffsetY+iOffsetX+1]); 
       strPixelRow += String.fromCharCode(aImgData[iOffsetY+iOffsetX]); 
      } 
      for (var c=0;c<iPadding;c++) { 
       strPixelRow += String.fromCharCode(0); 
      } 
      strPixelData += strPixelRow; 
     } while (--y); 

     var strEncoded = encodeData(aHeader.concat(aInfoHeader)) + encodeData(strPixelData); 

     return strEncoded; 
    } 
*/ 

    // sends the generated file to the client 
    var saveFile = function(strData) { 
     document.location.href = strData; 
    } 

    var makeDataURI = function(strData, strMime) { 
     return "data:" + strMime + ";base64," + strData; 
    } 

    // generates a <img> object containing the imagedata 
    var makeImageObject = function(strSource) { 
     var oImgElement = document.createElement("img"); 
     oImgElement.src = strSource; 
     return oImgElement; 
    } 

    var scaleCanvas = function(oCanvas, iWidth, iHeight) { 
     if (iWidth && iHeight) { 
      var oSaveCanvas = document.createElement("canvas"); 
      oSaveCanvas.width = iWidth; 
      oSaveCanvas.height = iHeight; 
      oSaveCanvas.style.width = iWidth+"px"; 
      oSaveCanvas.style.height = iHeight+"px"; 

      var oSaveCtx = oSaveCanvas.getContext("2d"); 

      oSaveCtx.drawImage(oCanvas, 0, 0, oCanvas.width, oCanvas.height, 0, 0, iWidth, iHeight); 
      return oSaveCanvas; 
     } 
     return oCanvas; 
    } 

    return { 

     saveAsPNG : function(oCanvas, bReturnImg, iWidth, iHeight) { 
      if (!bHasDataURL) { 
       return false; 
      } 
      var oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight); 
      var strData = oScaledCanvas.toDataURL("image/png"); 
      if (bReturnImg) { 
       return makeImageObject(strData); 
      } else { 
       saveFile(strData.replace("image/png", strDownloadMime)); 
      } 
      return true; 
     }, 

     saveAsJPEG : function(oCanvas, bReturnImg, iWidth, iHeight) { 
      if (!bHasDataURL) { 
       return false; 
      } 

      var oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight); 
      var strMime = "image/jpeg"; 
      var strData = oScaledCanvas.toDataURL(strMime); 

      // check if browser actually supports jpeg by looking for the mime type in the data uri. 
      // if not, return false 
      if (strData.indexOf(strMime) != 5) { 
       return false; 
      } 

      if (bReturnImg) { 
       return makeImageObject(strData); 
      } else { 
       saveFile(strData.replace(strMime, strDownloadMime)); 
      } 
      return true; 
     }, 

    /* saveAsBMP : function(oCanvas, bReturnImg, iWidth, iHeight) { 
      if (!(bHasImageData && bHasBase64)) { 
       return false; 
      } 

      var oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight); 

      var oData = readCanvasData(oScaledCanvas); 
      var strImgData = createBMP(oData); 
      if (bReturnImg) { 
       return makeImageObject(makeDataURI(strImgData, "image/bmp")); 
      } else { 
       saveFile(makeDataURI(strImgData, strDownloadMime)); 
      } 
      return true; 
     }*/ 
    }; 

})(); 

in html i tun:

<script type="text/javascript"> 
    $(document).ready(function(){ 
    var _txt = "hey"; 
    $('#qrcode').qrcode({ 
     text :_txt 
    }); 
    $("#qrcode-canvas").attr("download","file.png"); 
    var oCanvas = document.getElementById("qrcode-canvas"); 
    $("#download-qrcode").on('click',function(){ 
     Canvas2Image.saveAsPNG(oCanvas); 
    }) 
    }); 
    </script> 

<div id="qrcode" class="" style="" ></div> 
<a class="btn btn-large btn-inverse" id="download-qrcode"><i class="icon icon-download-alt icon-white"></i> download</a> 

Ich habe Probleme, i ist mit MacOSX FF, Chrome Opera und Safari, dann nenne ich das saveAsPNG() Methode über das Element

das Bild auf ein Dokument ohne Erweiterung zurück gespeichert werden:

data:image/octet-stream;base64,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 

Ich mag würde es als Bild zu speichern, würde png mag:/

ist das möglich?

Ursache ich kann ich das mit Daten beheben: Bild/Png, etc .. aber es wird ein neues Fenster im Browser öffnen.

+1

Wenn Sie ihm keinen korrekten MIME-Typ geben, wie soll er wissen, unter welcher Art von Bilddatei er gespeichert werden soll? – Barmar

+0

@Barmar und wie fügt man das hinzu? – sbaaaang

+0

ich meine, wenn ich image/png es öffnet neues Fenster während Bild/Oktett-Stream nicht und ich will nicht neues Fenster öffnen – sbaaaang

Antwort

9

auf diese Frage basiert: Name a PNG file saved from Canvas using an "open with" dialog, können Sie das download Attribut eines a Element verwenden, um anzuzeigen, dass die href mit dem angegebenen Namen heruntergeladen werden soll.

Besser noch können wir die href auf den Rückgabewert von toDataURL setzen, die sicherstellen wird, dass das Bild tatsächlich als PNG heruntergeladen wird.

<a class="btn btn-large btn-inverse" id="download-qrcode" download="my_file.png"> 
    <i class="icon icon-download-alt icon-white"></i> 
    download 
</a> 

$("#download-qrcode").on('click',function(){ 
    var dataUrl = oCanvas[0].toDataURL(); 
    $(this).attr('href', dataUrl); 
}); 

Wenn der Link angeklickt wird, wird die Datei als my_file.png heruntergeladen werden. Wie in dieser Frage angegeben, ist das Attribut download nicht so weit verbreitet - der obige Code funktionierte nur in Chrome, obwohl Firefox dieses Attribut scheinbar unterstützt.

Ich bin nicht wirklich sicher, wie dies zu umgehen, wie Sie nicht ein Content-Disposition in einer data: URL gesetzt, was bedeutet, dass Sie nicht den Download zwingen können, wie können Sie mit einer Server-Seite.

Sie könnten auch auschecken: http://www.joeltrost.com/blog/2012/01/29/html5-canvas-save-a-jpeg-with-extension/, die das gleiche Problem mit einem Post-Back-Ansatz behandelt. Das Schöne dabei ist, dass es die Fähigkeit des Servers nutzt, die Content-Disposition anzugeben, so dass Sie das Herunterladen des Bildes erzwingen können.

Edit:

So ist die Idee des Post-back-Konzepts ist im Grunde die Daten URL senden an den Server zurück, die es im Wesentlichen zurück Echos. Der Trick ist, dass dabei ein Content-Disposition gesetzt wird, der das Herunterladen des Bildes erzwingt.

Jetzt zeigt der Link eine Lösung in PHP, so dass Sie wahrscheinlich das Skript wiederverwenden könnten, um das Gleiche zu tun.

+0

überhaupt nicht aufgefangen Sorry, macht mir der href attr die Möglichkeit, die Datei als Image herunterzuladen? Oder schlagen Sie einen Ajax-Aufruf vor, um das Bild herunterzuladen? – sbaaaang

+0

Verwenden Sie Ihren Code beim Klicken, um den Browser herunterzuladen Öffnen Sie einen neuen Tab mit dem Bild im PNG-Format, das ist ein großer Schritt voraus, kann ich einen AJAX-Aufruf an diese URL verwenden, damit ich die Datei zum Download erhalten kann? – sbaaaang

+0

Ich meine, ich kann eine XHR-Anfrage senden die Base64-IMG-Code zu einem kleinen PHP-Skript, dass es (möglicherweise) speichert die IMG und macht mich herunterladen ... – sbaaaang

Verwandte Themen