赞
踩
canvas2image.js
- /**
- * covert canvas to image
- * and save the image file
- */
- var Canvas2Image = function () {
-
- // check if support sth.
- var $support = function () {
- var canvas = document.createElement('canvas'),
- ctx = canvas.getContext('2d');
-
- return {
- canvas: !!ctx,
- imageData: !!ctx.getImageData,
- dataURL: !!canvas.toDataURL,
- btoa: !!window.btoa
- };
- }();
-
- var downloadMime = 'image/octet-stream';
-
- function scaleCanvas (canvas, width, height) {
- var w = canvas.width,
- h = canvas.height;
- if (width == undefined) {
- width = w;
- }
- if (height == undefined) {
- height = h;
- }
-
- var retCanvas = document.createElement('canvas');
- var retCtx = retCanvas.getContext('2d');
- retCanvas.width = width;
- retCanvas.height = height;
- retCtx.drawImage(canvas, 0, 0, w, h, 0, 0, width, height);
- return retCanvas;
- }
-
- function getDataURL (canvas, type, width, height) {
- canvas = scaleCanvas(canvas, width, height);
- return canvas.toDataURL(type);
- }
-
- function saveFile (strData) {
- document.location.href = strData;
- }
-
- function genImage(strData) {
- var img = document.createElement('img');
- img.src = strData;
- return img;
- }
- function fixType (type) {
- type = type.toLowerCase().replace(/jpg/i, 'jpeg');
- var r = type.match(/png|jpeg|bmp|gif/)[0];
- return 'image/' + r;
- }
- function encodeData (data) {
- if (!window.btoa) { throw 'btoa undefined' }
- var str = '';
- if (typeof data == 'string') {
- str = data;
- } else {
- for (var i = 0; i < data.length; i ++) {
- str += String.fromCharCode(data[i]);
- }
- }
-
- return btoa(str);
- }
- function getImageData (canvas) {
- var w = canvas.width,
- h = canvas.height;
- return canvas.getContext('2d').getImageData(0, 0, w, h);
- }
- function makeURI (strData, type) {
- return 'data:' + type + ';base64,' + strData;
- }
-
-
- /**
- * create bitmap image
- * 按照规则生成图片响应头和响应体
- */
- var genBitmapImage = function (oData) {
-
- //
- // BITMAPFILEHEADER: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx
- // BITMAPINFOHEADER: http://msdn.microsoft.com/en-us/library/dd183376.aspx
- //
-
- var biWidth = oData.width;
- var biHeight = oData.height;
- var biSizeImage = biWidth * biHeight * 3;
- var bfSize = biSizeImage + 54; // total header size = 54 bytes
-
- //
- // typedef struct tagBITMAPFILEHEADER {
- // WORD bfType;
- // DWORD bfSize;
- // WORD bfReserved1;
- // WORD bfReserved2;
- // DWORD bfOffBits;
- // } BITMAPFILEHEADER;
- //
- var BITMAPFILEHEADER = [
- // WORD bfType -- The file type signature; must be "BM"
- 0x42, 0x4D,
- // DWORD bfSize -- The size, in bytes, of the bitmap file
- bfSize & 0xff, bfSize >> 8 & 0xff, bfSize >> 16 & 0xff, bfSize >> 24 & 0xff,
- // WORD bfReserved1 -- Reserved; must be zero
- 0, 0,
- // WORD bfReserved2 -- Reserved; must be zero
- 0, 0,
- // DWORD bfOffBits -- The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.
- 54, 0, 0, 0
- ];
-
- //
- // typedef struct tagBITMAPINFOHEADER {
- // DWORD biSize;
- // LONG biWidth;
- // LONG biHeight;
- // WORD biPlanes;
- // WORD biBitCount;
- // DWORD biCompression;
- // DWORD biSizeImage;
- // LONG biXPelsPerMeter;
- // LONG biYPelsPerMeter;
- // DWORD biClrUsed;
- // DWORD biClrImportant;
- // } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
- //
- var BITMAPINFOHEADER = [
- // DWORD biSize -- The number of bytes required by the structure
- 40, 0, 0, 0,
- // LONG biWidth -- The width of the bitmap, in pixels
- biWidth & 0xff, biWidth >> 8 & 0xff, biWidth >> 16 & 0xff, biWidth >> 24 & 0xff,
- // LONG biHeight -- The height of the bitmap, in pixels
- biHeight & 0xff, biHeight >> 8 & 0xff, biHeight >> 16 & 0xff, biHeight >> 24 & 0xff,
- // WORD biPlanes -- The number of planes for the target device. This value must be set to 1
- 1, 0,
- // WORD biBitCount -- The number of bits-per-pixel, 24 bits-per-pixel -- the bitmap
- // has a maximum of 2^24 colors (16777216, Truecolor)
- 24, 0,
- // DWORD biCompression -- The type of compression, BI_RGB (code 0) -- uncompressed
- 0, 0, 0, 0,
- // DWORD biSizeImage -- The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps
- biSizeImage & 0xff, biSizeImage >> 8 & 0xff, biSizeImage >> 16 & 0xff, biSizeImage >> 24 & 0xff,
- // LONG biXPelsPerMeter, unused
- 0,0,0,0,
- // LONG biYPelsPerMeter, unused
- 0,0,0,0,
- // DWORD biClrUsed, the number of color indexes of palette, unused
- 0,0,0,0,
- // DWORD biClrImportant, unused
- 0,0,0,0
- ];
-
- var iPadding = (4 - ((biWidth * 3) % 4)) % 4;
-
- var aImgData = oData.data;
-
- var strPixelData = '';
- var biWidth4 = biWidth<<2;
- var y = biHeight;
- var fromCharCode = String.fromCharCode;
-
- do {
- var iOffsetY = biWidth4*(y-1);
- var strPixelRow = '';
- for (var x = 0; x < biWidth; x++) {
- var iOffsetX = x<<2;
- strPixelRow += fromCharCode(aImgData[iOffsetY+iOffsetX+2]) +
- fromCharCode(aImgData[iOffsetY+iOffsetX+1]) +
- fromCharCode(aImgData[iOffsetY+iOffsetX]);
- }
-
- for (var c = 0; c < iPadding; c++) {
- strPixelRow += String.fromCharCode(0);
- }
-
- strPixelData += strPixelRow;
- } while (--y);
-
- var strEncoded = encodeData(BITMAPFILEHEADER.concat(BITMAPINFOHEADER)) + encodeData(strPixelData);
-
- return strEncoded;
- };
-
- /**
- * saveAsImage
- * @param canvasElement
- * @param {String} image type
- * @param {Number} [optional] png width
- * @param {Number} [optional] png height
- */
- var saveAsImage = function (canvas, width, height, type) {
- if ($support.canvas && $support.dataURL) {
- if (typeof canvas == "string") { canvas = document.getElementById(canvas); }
- if (type == undefined) { type = 'png'; }
- type = fixType(type);
- if (/bmp/.test(type)) {
- var data = getImageData(scaleCanvas(canvas, width, height));
- var strData = genBitmapImage(data);
- saveFile(makeURI(strData, downloadMime));
- } else {
- var strData = getDataURL(canvas, type, width, height);
- saveFile(strData.replace(type, downloadMime));
- }
- }
- };
-
- var convertToImage = function (canvas, width, height, type) {
- if ($support.canvas && $support.dataURL) {
- if (typeof canvas == "string") { canvas = document.getElementById(canvas); }
- if (type == undefined) { type = 'png'; }
- type = fixType(type);
-
- if (/bmp/.test(type)) {
- var data = getImageData(scaleCanvas(canvas, width, height));
- var strData = genBitmapImage(data);
- return genImage(makeURI(strData, 'image/bmp'));
- } else {
- var strData = getDataURL(canvas, type, width, height);
- return genImage(strData);
- }
- }
- };
-
-
-
- return {
- saveAsImage: saveAsImage,
- saveAsPNG: function (canvas, width, height) {
- return saveAsImage(canvas, width, height, 'png');
- },
- saveAsJPEG: function (canvas, width, height) {
- return saveAsImage(canvas, width, height, 'jpeg');
- },
- saveAsGIF: function (canvas, width, height) {
- return saveAsImage(canvas, width, height, 'gif');
- },
- saveAsBMP: function (canvas, width, height) {
- return saveAsImage(canvas, width, height, 'bmp');
- },
-
- convertToImage: convertToImage,
- convertToPNG: function (canvas, width, height) {
- return convertToImage(canvas, width, height, 'png');
- },
- convertToJPEG: function (canvas, width, height) {
- return convertToImage(canvas, width, height, 'jpeg');
- },
- convertToGIF: function (canvas, width, height) {
- return convertToImage(canvas, width, height, 'gif');
- },
- convertToBMP: function (canvas, width, height) {
- return convertToImage(canvas, width, height, 'bmp');
- }
- };
-
- }();
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>demo</title>
- <script src="../js/canvas2image/canvas2image.js"></script>
- <style>
- .doc {
- width: 604px;
- margin: 0 auto;
- }
- canvas {
- display: block;
- border: 2px solid #888;
- }
- </style>
- <body>
- <div class="doc">
- <canvas width="300" height="200" id="cvs"></canvas>
- <div>
- <p>
- <button id="save">保存</button> 或者 <button id="convert">转换为</button> :
- <select id="sel">
- <option value="png">png</option>
- <option value="jpeg">jpeg</option>
- <option value="bmp">bmp</option>
- </select><br/>
- 宽度 : <input type="number" value="300" id="imgW" /><br/>
- 高度 : <input type="number" value="200" id="imgH" />
- </p>
-
- </div>
- <div id="imgs">
-
- </div>
- </div>
- <script>
- var canvas, ctx, bMouseIsDown = false, iLastX, iLastY,
- $save, $imgs,
- $convert, $imgW, $imgH,
- $sel;
- function init () {
- canvas = document.getElementById('cvs');
- ctx = canvas.getContext('2d');
- $save = document.getElementById('save');
- $convert = document.getElementById('convert');
- $sel = document.getElementById('sel');
- $imgs = document.getElementById('imgs');
- $imgW = document.getElementById('imgW');
- $imgH = document.getElementById('imgH');
- bind();
- draw();
- }
- function bind () {
- canvas.onmousedown = function(e) {
- bMouseIsDown = true;
- iLastX = e.clientX - canvas.offsetLeft + (window.pageXOffset||document.body.scrollLeft||document.documentElement.scrollLeft);
- iLastY = e.clientY - canvas.offsetTop + (window.pageYOffset||document.body.scrollTop||document.documentElement.scrollTop);
- }
- canvas.onmouseup = function() {
- bMouseIsDown = false;
- iLastX = -1;
- iLastY = -1;
- }
- canvas.onmousemove = function(e) {
- if (bMouseIsDown) {
- var iX = e.clientX - canvas.offsetLeft + (window.pageXOffset||document.body.scrollLeft||document.documentElement.scrollLeft);
- var iY = e.clientY - canvas.offsetTop + (window.pageYOffset||document.body.scrollTop||document.documentElement.scrollTop);
- ctx.moveTo(iLastX, iLastY);
- ctx.lineTo(iX, iY);
- ctx.stroke();
- iLastX = iX;
- iLastY = iY;
- }
- };
-
- $save.onclick = function (e) {
- var type = $sel.value,
- w = $imgW.value,
- h = $imgH.value;
- Canvas2Image.saveAsImage(canvas, w, h, type);
- }
- $convert.onclick = function (e) {
- var type = $sel.value,
- w = $imgW.value,
- h = $imgH.value;
- $imgs.appendChild(Canvas2Image.convertToImage(canvas, w, h, type))
- }
-
- }
- function draw () {
- ctx.fillStyle = '#ffffff';
- ctx.fillRect(0, 0, 600, 400);
- ctx.fillStyle = 'red';
- ctx.fillRect(100, 100, 50, 50);
- }
-
-
- onload = init;
- </script>
- </body>
- </html>
效果:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。