123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- /*
- * Canvas2Image v0.1
- * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk
- * 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;
- }
- };
- })();
|