当前位置:   article > 正文

canvas2image.js将canvas保存为图片(将HTML5画布Canvas的内容保存为本地图片并下载)

canvas2image.js

canvas2image.js

  1. /**
  2. * covert canvas to image
  3. * and save the image file
  4. */
  5. var Canvas2Image = function () {
  6. // check if support sth.
  7. var $support = function () {
  8. var canvas = document.createElement('canvas'),
  9. ctx = canvas.getContext('2d');
  10. return {
  11. canvas: !!ctx,
  12. imageData: !!ctx.getImageData,
  13. dataURL: !!canvas.toDataURL,
  14. btoa: !!window.btoa
  15. };
  16. }();
  17. var downloadMime = 'image/octet-stream';
  18. function scaleCanvas (canvas, width, height) {
  19. var w = canvas.width,
  20. h = canvas.height;
  21. if (width == undefined) {
  22. width = w;
  23. }
  24. if (height == undefined) {
  25. height = h;
  26. }
  27. var retCanvas = document.createElement('canvas');
  28. var retCtx = retCanvas.getContext('2d');
  29. retCanvas.width = width;
  30. retCanvas.height = height;
  31. retCtx.drawImage(canvas, 0, 0, w, h, 0, 0, width, height);
  32. return retCanvas;
  33. }
  34. function getDataURL (canvas, type, width, height) {
  35. canvas = scaleCanvas(canvas, width, height);
  36. return canvas.toDataURL(type);
  37. }
  38. function saveFile (strData) {
  39. document.location.href = strData;
  40. }
  41. function genImage(strData) {
  42. var img = document.createElement('img');
  43. img.src = strData;
  44. return img;
  45. }
  46. function fixType (type) {
  47. type = type.toLowerCase().replace(/jpg/i, 'jpeg');
  48. var r = type.match(/png|jpeg|bmp|gif/)[0];
  49. return 'image/' + r;
  50. }
  51. function encodeData (data) {
  52. if (!window.btoa) { throw 'btoa undefined' }
  53. var str = '';
  54. if (typeof data == 'string') {
  55. str = data;
  56. } else {
  57. for (var i = 0; i < data.length; i ++) {
  58. str += String.fromCharCode(data[i]);
  59. }
  60. }
  61. return btoa(str);
  62. }
  63. function getImageData (canvas) {
  64. var w = canvas.width,
  65. h = canvas.height;
  66. return canvas.getContext('2d').getImageData(0, 0, w, h);
  67. }
  68. function makeURI (strData, type) {
  69. return 'data:' + type + ';base64,' + strData;
  70. }
  71. /**
  72. * create bitmap image
  73. * 按照规则生成图片响应头和响应体
  74. */
  75. var genBitmapImage = function (oData) {
  76. //
  77. // BITMAPFILEHEADER: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx
  78. // BITMAPINFOHEADER: http://msdn.microsoft.com/en-us/library/dd183376.aspx
  79. //
  80. var biWidth = oData.width;
  81. var biHeight = oData.height;
  82. var biSizeImage = biWidth * biHeight * 3;
  83. var bfSize = biSizeImage + 54; // total header size = 54 bytes
  84. //
  85. // typedef struct tagBITMAPFILEHEADER {
  86. // WORD bfType;
  87. // DWORD bfSize;
  88. // WORD bfReserved1;
  89. // WORD bfReserved2;
  90. // DWORD bfOffBits;
  91. // } BITMAPFILEHEADER;
  92. //
  93. var BITMAPFILEHEADER = [
  94. // WORD bfType -- The file type signature; must be "BM"
  95. 0x42, 0x4D,
  96. // DWORD bfSize -- The size, in bytes, of the bitmap file
  97. bfSize & 0xff, bfSize >> 8 & 0xff, bfSize >> 16 & 0xff, bfSize >> 24 & 0xff,
  98. // WORD bfReserved1 -- Reserved; must be zero
  99. 0, 0,
  100. // WORD bfReserved2 -- Reserved; must be zero
  101. 0, 0,
  102. // DWORD bfOffBits -- The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.
  103. 54, 0, 0, 0
  104. ];
  105. //
  106. // typedef struct tagBITMAPINFOHEADER {
  107. // DWORD biSize;
  108. // LONG biWidth;
  109. // LONG biHeight;
  110. // WORD biPlanes;
  111. // WORD biBitCount;
  112. // DWORD biCompression;
  113. // DWORD biSizeImage;
  114. // LONG biXPelsPerMeter;
  115. // LONG biYPelsPerMeter;
  116. // DWORD biClrUsed;
  117. // DWORD biClrImportant;
  118. // } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
  119. //
  120. var BITMAPINFOHEADER = [
  121. // DWORD biSize -- The number of bytes required by the structure
  122. 40, 0, 0, 0,
  123. // LONG biWidth -- The width of the bitmap, in pixels
  124. biWidth & 0xff, biWidth >> 8 & 0xff, biWidth >> 16 & 0xff, biWidth >> 24 & 0xff,
  125. // LONG biHeight -- The height of the bitmap, in pixels
  126. biHeight & 0xff, biHeight >> 8 & 0xff, biHeight >> 16 & 0xff, biHeight >> 24 & 0xff,
  127. // WORD biPlanes -- The number of planes for the target device. This value must be set to 1
  128. 1, 0,
  129. // WORD biBitCount -- The number of bits-per-pixel, 24 bits-per-pixel -- the bitmap
  130. // has a maximum of 2^24 colors (16777216, Truecolor)
  131. 24, 0,
  132. // DWORD biCompression -- The type of compression, BI_RGB (code 0) -- uncompressed
  133. 0, 0, 0, 0,
  134. // DWORD biSizeImage -- The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps
  135. biSizeImage & 0xff, biSizeImage >> 8 & 0xff, biSizeImage >> 16 & 0xff, biSizeImage >> 24 & 0xff,
  136. // LONG biXPelsPerMeter, unused
  137. 0,0,0,0,
  138. // LONG biYPelsPerMeter, unused
  139. 0,0,0,0,
  140. // DWORD biClrUsed, the number of color indexes of palette, unused
  141. 0,0,0,0,
  142. // DWORD biClrImportant, unused
  143. 0,0,0,0
  144. ];
  145. var iPadding = (4 - ((biWidth * 3) % 4)) % 4;
  146. var aImgData = oData.data;
  147. var strPixelData = '';
  148. var biWidth4 = biWidth<<2;
  149. var y = biHeight;
  150. var fromCharCode = String.fromCharCode;
  151. do {
  152. var iOffsetY = biWidth4*(y-1);
  153. var strPixelRow = '';
  154. for (var x = 0; x < biWidth; x++) {
  155. var iOffsetX = x<<2;
  156. strPixelRow += fromCharCode(aImgData[iOffsetY+iOffsetX+2]) +
  157. fromCharCode(aImgData[iOffsetY+iOffsetX+1]) +
  158. fromCharCode(aImgData[iOffsetY+iOffsetX]);
  159. }
  160. for (var c = 0; c < iPadding; c++) {
  161. strPixelRow += String.fromCharCode(0);
  162. }
  163. strPixelData += strPixelRow;
  164. } while (--y);
  165. var strEncoded = encodeData(BITMAPFILEHEADER.concat(BITMAPINFOHEADER)) + encodeData(strPixelData);
  166. return strEncoded;
  167. };
  168. /**
  169. * saveAsImage
  170. * @param canvasElement
  171. * @param {String} image type
  172. * @param {Number} [optional] png width
  173. * @param {Number} [optional] png height
  174. */
  175. var saveAsImage = function (canvas, width, height, type) {
  176. if ($support.canvas && $support.dataURL) {
  177. if (typeof canvas == "string") { canvas = document.getElementById(canvas); }
  178. if (type == undefined) { type = 'png'; }
  179. type = fixType(type);
  180. if (/bmp/.test(type)) {
  181. var data = getImageData(scaleCanvas(canvas, width, height));
  182. var strData = genBitmapImage(data);
  183. saveFile(makeURI(strData, downloadMime));
  184. } else {
  185. var strData = getDataURL(canvas, type, width, height);
  186. saveFile(strData.replace(type, downloadMime));
  187. }
  188. }
  189. };
  190. var convertToImage = function (canvas, width, height, type) {
  191. if ($support.canvas && $support.dataURL) {
  192. if (typeof canvas == "string") { canvas = document.getElementById(canvas); }
  193. if (type == undefined) { type = 'png'; }
  194. type = fixType(type);
  195. if (/bmp/.test(type)) {
  196. var data = getImageData(scaleCanvas(canvas, width, height));
  197. var strData = genBitmapImage(data);
  198. return genImage(makeURI(strData, 'image/bmp'));
  199. } else {
  200. var strData = getDataURL(canvas, type, width, height);
  201. return genImage(strData);
  202. }
  203. }
  204. };
  205. return {
  206. saveAsImage: saveAsImage,
  207. saveAsPNG: function (canvas, width, height) {
  208. return saveAsImage(canvas, width, height, 'png');
  209. },
  210. saveAsJPEG: function (canvas, width, height) {
  211. return saveAsImage(canvas, width, height, 'jpeg');
  212. },
  213. saveAsGIF: function (canvas, width, height) {
  214. return saveAsImage(canvas, width, height, 'gif');
  215. },
  216. saveAsBMP: function (canvas, width, height) {
  217. return saveAsImage(canvas, width, height, 'bmp');
  218. },
  219. convertToImage: convertToImage,
  220. convertToPNG: function (canvas, width, height) {
  221. return convertToImage(canvas, width, height, 'png');
  222. },
  223. convertToJPEG: function (canvas, width, height) {
  224. return convertToImage(canvas, width, height, 'jpeg');
  225. },
  226. convertToGIF: function (canvas, width, height) {
  227. return convertToImage(canvas, width, height, 'gif');
  228. },
  229. convertToBMP: function (canvas, width, height) {
  230. return convertToImage(canvas, width, height, 'bmp');
  231. }
  232. };
  233. }();
  1. <!DOCTYPE html>
  2. <html>
  3. <head> 
  4. <meta charset="utf-8"> 
  5. <title>demo</title> 
  6. <script src="../js/canvas2image/canvas2image.js"></script>
  7. <style>
  8. .doc {
  9. width: 604px;
  10. margin: 0 auto;
  11. }
  12. canvas {
  13. display: block;
  14. border: 2px solid #888;
  15. }
  16. </style>
  17. <body>
  18. <div class="doc">
  19. <canvas width="300" height="200" id="cvs"></canvas>
  20. <div>
  21. <p>
  22. <button id="save">保存</button> 或者 <button id="convert">转换为</button> :
  23. <select id="sel">
  24. <option value="png">png</option>
  25. <option value="jpeg">jpeg</option>
  26. <option value="bmp">bmp</option>
  27. </select><br/>
  28. 宽度 : <input type="number" value="300" id="imgW" /><br/>
  29. 高度 : <input type="number" value="200" id="imgH" />
  30. </p>
  31. </div>
  32. <div id="imgs">
  33. </div>
  34. </div>
  35. <script>
  36. var canvas, ctx, bMouseIsDown = false, iLastX, iLastY,
  37. $save, $imgs,
  38. $convert, $imgW, $imgH,
  39. $sel;
  40. function init () {
  41. canvas = document.getElementById('cvs');
  42. ctx = canvas.getContext('2d');
  43. $save = document.getElementById('save');
  44. $convert = document.getElementById('convert');
  45. $sel = document.getElementById('sel');
  46. $imgs = document.getElementById('imgs');
  47. $imgW = document.getElementById('imgW');
  48. $imgH = document.getElementById('imgH');
  49. bind();
  50. draw();
  51. }
  52. function bind () {
  53. canvas.onmousedown = function(e) {
  54. bMouseIsDown = true;
  55. iLastX = e.clientX - canvas.offsetLeft + (window.pageXOffset||document.body.scrollLeft||document.documentElement.scrollLeft);
  56. iLastY = e.clientY - canvas.offsetTop + (window.pageYOffset||document.body.scrollTop||document.documentElement.scrollTop);
  57. }
  58. canvas.onmouseup = function() {
  59. bMouseIsDown = false;
  60. iLastX = -1;
  61. iLastY = -1;
  62. }
  63. canvas.onmousemove = function(e) {
  64. if (bMouseIsDown) {
  65. var iX = e.clientX - canvas.offsetLeft + (window.pageXOffset||document.body.scrollLeft||document.documentElement.scrollLeft);
  66. var iY = e.clientY - canvas.offsetTop + (window.pageYOffset||document.body.scrollTop||document.documentElement.scrollTop);
  67. ctx.moveTo(iLastX, iLastY);
  68. ctx.lineTo(iX, iY);
  69. ctx.stroke();
  70. iLastX = iX;
  71. iLastY = iY;
  72. }
  73. };
  74. $save.onclick = function (e) {
  75. var type = $sel.value,
  76. w = $imgW.value,
  77. h = $imgH.value;
  78. Canvas2Image.saveAsImage(canvas, w, h, type);
  79. }
  80. $convert.onclick = function (e) {
  81. var type = $sel.value,
  82. w = $imgW.value,
  83. h = $imgH.value;
  84. $imgs.appendChild(Canvas2Image.convertToImage(canvas, w, h, type))
  85. }
  86. }
  87. function draw () {
  88. ctx.fillStyle = '#ffffff';
  89. ctx.fillRect(0, 0, 600, 400);
  90. ctx.fillStyle = 'red';
  91. ctx.fillRect(100, 100, 50, 50);
  92. }
  93. onload = init;
  94. </script>
  95. </body>
  96. </html>

效果:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/229322
推荐阅读
相关标签
  

闽ICP备14008679号