123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- /*
- * Canvas2Image v0.1
- * Copyright (c) 2008 Jacob Seidelin, cupboy@gmail.com
- * MIT License [http://www.opensource.org/licenses/mit-license.php]
- */
- var Canvas2Image = (function() {
- // check if we have canvas support
- var oCanvas = document.createElement("canvas"),
- sc = String.fromCharCode,
- strDownloadMime = "image/octet-stream",
- bReplaceDownloadMime = false;
- // no canvas, bail out.
- if (!oCanvas.getContext) {
- return {
- saveAsBMP : function(){},
- saveAsPNG : function(){},
- saveAsJPEG : function(){}
- }
- }
- var bHasImageData = !!(oCanvas.getContext("2d").getImageData),
- bHasDataURL = !!(oCanvas.toDataURL),
- bHasBase64 = !!(window.btoa);
- // ok, we're good
- var readCanvasData = function(oCanvas) {
- var iWidth = parseInt(oCanvas.width),
- 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 i, aData, strData = "";
- if (typeof data == "string") {
- strData = data;
- } else {
- aData = data;
- for (i = 0; i < aData.length; i++) {
- strData += sc(aData[i]);
- }
- }
- return btoa(strData);
- }
- // creates a base64 encoded string containing BMP data takes an imagedata object as argument
- var createBMP = function(oData) {
- var strHeader = '',
- iWidth = oData.width,
- iHeight = oData.height;
- strHeader += 'BM';
- var iFileSize = iWidth*iHeight*4 + 54; // total header size = 54 bytes
- strHeader += sc(iFileSize % 256); iFileSize = Math.floor(iFileSize / 256);
- strHeader += sc(iFileSize % 256); iFileSize = Math.floor(iFileSize / 256);
- strHeader += sc(iFileSize % 256); iFileSize = Math.floor(iFileSize / 256);
- strHeader += sc(iFileSize % 256);
- strHeader += sc(0, 0, 0, 0, 54, 0, 0, 0); // data offset
- strHeader += sc(40, 0, 0, 0); // info header size
- var iImageWidth = iWidth;
- strHeader += sc(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth / 256);
- strHeader += sc(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth / 256);
- strHeader += sc(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth / 256);
- strHeader += sc(iImageWidth % 256);
- var iImageHeight = iHeight;
- strHeader += sc(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight / 256);
- strHeader += sc(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight / 256);
- strHeader += sc(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight / 256);
- strHeader += sc(iImageHeight % 256);
- strHeader += sc(1, 0, 32, 0); // num of planes & num of bits per pixel
- strHeader += sc(0, 0, 0, 0); // compression = none
- var iDataSize = iWidth*iHeight*4;
- strHeader += sc(iDataSize % 256); iDataSize = Math.floor(iDataSize / 256);
- strHeader += sc(iDataSize % 256); iDataSize = Math.floor(iDataSize / 256);
- strHeader += sc(iDataSize % 256); iDataSize = Math.floor(iDataSize / 256);
- strHeader += sc(iDataSize % 256);
- strHeader += sc(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); // these bytes are not used
- var aImgData = oData.data,
- strPixelData = "",
- c, x, y = iHeight,
- iOffsetX, iOffsetY, strPixelRow;
- do {
- iOffsetY = iWidth*(y-1)*4;
- strPixelRow = "";
- for (x = 0; x < iWidth; x++) {
- iOffsetX = 4*x;
- strPixelRow += sc(
- aImgData[iOffsetY + iOffsetX + 2], // B
- aImgData[iOffsetY + iOffsetX + 1], // G
- aImgData[iOffsetY + iOffsetX], // R
- aImgData[iOffsetY + iOffsetX + 3] // A
- );
- }
- strPixelData += strPixelRow;
- } while (--y);
- return encodeData(strHeader + strPixelData);
- }
- // sends the generated file to the client
- var saveFile = function(strData) {
- if (!window.open(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, iWidth);
- return oSaveCanvas;
- }
- return oCanvas;
- }
- return {
- saveAsPNG : function(oCanvas, bReturnImg, iWidth, iHeight) {
- if (!bHasDataURL) return false;
- var oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight),
- strMime = "image/png",
- strData = oScaledCanvas.toDataURL(strMime);
- if (bReturnImg) {
- return makeImageObject(strData);
- } else {
- saveFile(bReplaceDownloadMime ? strData.replace(strMime, strDownloadMime) : strData);
- }
- return true;
- },
- saveAsJPEG : function(oCanvas, bReturnImg, iWidth, iHeight) {
- if (!bHasDaaURL) return false;
- var oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight),
- strMime = "image/jpeg",
- 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(bReplaceDownloadMime ? strData.replace(strMime, strDownloadMime) : strData);
- }
- return true;
- },
- saveAsBMP : function(oCanvas, bReturnImg, iWidth, iHeight) {
- if (!(bHasDataURL && bHasImageData && bHasBase64)) return false;
- var oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight),
- strMime = "image/bmp",
- oData = readCanvasData(oScaledCanvas),
- strImgData = createBMP(oData);
- if (bReturnImg) {
- return makeImageObject(makeDataURI(strImgData, strMime));
- } else {
- saveFile(makeDataURI(strImgData, strMime));
- }
- return true;
- }
- };
- })();
|