Guest User

canvas2image.js

a guest
Apr 25th, 2020
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.18 KB | None | 0 0
  1. /**
  2. * covert canvas to image
  3. * and save the image file
  4. */
  5.  
  6. var Canvas2Image = function () {
  7.  
  8. // check if support sth.
  9. var $support = function () {
  10. var canvas = document.createElement('canvas'),
  11. ctx = canvas.getContext('2d');
  12.  
  13. return {
  14. canvas: !!ctx,
  15. imageData: !!ctx.getImageData,
  16. dataURL: !!canvas.toDataURL,
  17. btoa: !!window.btoa
  18. };
  19. }();
  20.  
  21. var downloadMime = 'image/octet-stream';
  22.  
  23. function scaleCanvas (canvas, width, height) {
  24. var w = canvas.width,
  25. h = canvas.height;
  26. if (width == undefined) {
  27. width = w;
  28. }
  29. if (height == undefined) {
  30. height = h;
  31. }
  32.  
  33. var retCanvas = document.createElement('canvas');
  34. var retCtx = retCanvas.getContext('2d');
  35. retCanvas.width = width;
  36. retCanvas.height = height;
  37. retCtx.drawImage(canvas, 0, 0, w, h, 0, 0, width, height);
  38. return retCanvas;
  39. }
  40.  
  41. function getDataURL (canvas, type, width, height) {
  42. canvas = scaleCanvas(canvas, width, height);
  43. return canvas.toDataURL(type);
  44. }
  45.  
  46. function saveFile (strData) {
  47. document.location.href = strData;
  48. }
  49.  
  50. function genImage(strData) {
  51. var img = document.createElement('img');
  52. img.src = strData;
  53. return img;
  54. }
  55. function fixType (type) {
  56. type = type.toLowerCase().replace(/jpg/i, 'jpeg');
  57. var r = type.match(/png|jpeg|bmp|gif/)[0];
  58. return 'image/' + r;
  59. }
  60. function encodeData (data) {
  61. if (!window.btoa) { throw 'btoa undefined' }
  62. var str = '';
  63. if (typeof data == 'string') {
  64. str = data;
  65. } else {
  66. for (var i = 0; i < data.length; i ++) {
  67. str += String.fromCharCode(data[i]);
  68. }
  69. }
  70.  
  71. return btoa(str);
  72. }
  73. function getImageData (canvas) {
  74. var w = canvas.width,
  75. h = canvas.height;
  76. return canvas.getContext('2d').getImageData(0, 0, w, h);
  77. }
  78. function makeURI (strData, type) {
  79. return 'data:' + type + ';base64,' + strData;
  80. }
  81.  
  82.  
  83. /**
  84. * create bitmap image
  85. * 按照规则生成图片响应头和响应体
  86. */
  87. var genBitmapImage = function (oData) {
  88.  
  89. //
  90. // BITMAPFILEHEADER: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx
  91. // BITMAPINFOHEADER: http://msdn.microsoft.com/en-us/library/dd183376.aspx
  92. //
  93.  
  94. var biWidth = oData.width;
  95. var biHeight = oData.height;
  96. var biSizeImage = biWidth * biHeight * 3;
  97. var bfSize = biSizeImage + 54; // total header size = 54 bytes
  98.  
  99. //
  100. // typedef struct tagBITMAPFILEHEADER {
  101. // WORD bfType;
  102. // DWORD bfSize;
  103. // WORD bfReserved1;
  104. // WORD bfReserved2;
  105. // DWORD bfOffBits;
  106. // } BITMAPFILEHEADER;
  107. //
  108. var BITMAPFILEHEADER = [
  109. // WORD bfType -- The file type signature; must be "BM"
  110. 0x42, 0x4D,
  111. // DWORD bfSize -- The size, in bytes, of the bitmap file
  112. bfSize & 0xff, bfSize >> 8 & 0xff, bfSize >> 16 & 0xff, bfSize >> 24 & 0xff,
  113. // WORD bfReserved1 -- Reserved; must be zero
  114. 0, 0,
  115. // WORD bfReserved2 -- Reserved; must be zero
  116. 0, 0,
  117. // DWORD bfOffBits -- The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.
  118. 54, 0, 0, 0
  119. ];
  120.  
  121. //
  122. // typedef struct tagBITMAPINFOHEADER {
  123. // DWORD biSize;
  124. // LONG biWidth;
  125. // LONG biHeight;
  126. // WORD biPlanes;
  127. // WORD biBitCount;
  128. // DWORD biCompression;
  129. // DWORD biSizeImage;
  130. // LONG biXPelsPerMeter;
  131. // LONG biYPelsPerMeter;
  132. // DWORD biClrUsed;
  133. // DWORD biClrImportant;
  134. // } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
  135. //
  136. var BITMAPINFOHEADER = [
  137. // DWORD biSize -- The number of bytes required by the structure
  138. 40, 0, 0, 0,
  139. // LONG biWidth -- The width of the bitmap, in pixels
  140. biWidth & 0xff, biWidth >> 8 & 0xff, biWidth >> 16 & 0xff, biWidth >> 24 & 0xff,
  141. // LONG biHeight -- The height of the bitmap, in pixels
  142. biHeight & 0xff, biHeight >> 8 & 0xff, biHeight >> 16 & 0xff, biHeight >> 24 & 0xff,
  143. // WORD biPlanes -- The number of planes for the target device. This value must be set to 1
  144. 1, 0,
  145. // WORD biBitCount -- The number of bits-per-pixel, 24 bits-per-pixel -- the bitmap
  146. // has a maximum of 2^24 colors (16777216, Truecolor)
  147. 24, 0,
  148. // DWORD biCompression -- The type of compression, BI_RGB (code 0) -- uncompressed
  149. 0, 0, 0, 0,
  150. // DWORD biSizeImage -- The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps
  151. biSizeImage & 0xff, biSizeImage >> 8 & 0xff, biSizeImage >> 16 & 0xff, biSizeImage >> 24 & 0xff,
  152. // LONG biXPelsPerMeter, unused
  153. 0,0,0,0,
  154. // LONG biYPelsPerMeter, unused
  155. 0,0,0,0,
  156. // DWORD biClrUsed, the number of color indexes of palette, unused
  157. 0,0,0,0,
  158. // DWORD biClrImportant, unused
  159. 0,0,0,0
  160. ];
  161.  
  162. var iPadding = (4 - ((biWidth * 3) % 4)) % 4;
  163.  
  164. var aImgData = oData.data;
  165.  
  166. var strPixelData = '';
  167. var biWidth4 = biWidth<<2;
  168. var y = biHeight;
  169. var fromCharCode = String.fromCharCode;
  170.  
  171. do {
  172. var iOffsetY = biWidth4*(y-1);
  173. var strPixelRow = '';
  174. for (var x = 0; x < biWidth; x++) {
  175. var iOffsetX = x<<2;
  176. strPixelRow += fromCharCode(aImgData[iOffsetY+iOffsetX+2]) +
  177. fromCharCode(aImgData[iOffsetY+iOffsetX+1]) +
  178. fromCharCode(aImgData[iOffsetY+iOffsetX]);
  179. }
  180.  
  181. for (var c = 0; c < iPadding; c++) {
  182. strPixelRow += String.fromCharCode(0);
  183. }
  184.  
  185. strPixelData += strPixelRow;
  186. } while (--y);
  187.  
  188. var strEncoded = encodeData(BITMAPFILEHEADER.concat(BITMAPINFOHEADER)) + encodeData(strPixelData);
  189.  
  190. return strEncoded;
  191. };
  192.  
  193. /**
  194. * saveAsImage
  195. * @param canvasElement
  196. * @param {String} image type
  197. * @param {Number} [optional] png width
  198. * @param {Number} [optional] png height
  199. */
  200. var saveAsImage = function (canvas, width, height, type) {
  201. if ($support.canvas && $support.dataURL) {
  202. if (typeof canvas == "string") { canvas = document.getElementById(canvas); }
  203. if (type == undefined) { type = 'png'; }
  204. type = fixType(type);
  205. if (/bmp/.test(type)) {
  206. var data = getImageData(scaleCanvas(canvas, width, height));
  207. var strData = genBitmapImage(data);
  208. saveFile(makeURI(strData, downloadMime));
  209. } else {
  210. var strData = getDataURL(canvas, type, width, height);
  211. saveFile(strData.replace(type, downloadMime));
  212. }
  213. }
  214. };
  215.  
  216. var convertToImage = function (canvas, width, height, type) {
  217. if ($support.canvas && $support.dataURL) {
  218. if (typeof canvas == "string") { canvas = document.getElementById(canvas); }
  219. if (type == undefined) { type = 'png'; }
  220. type = fixType(type);
  221.  
  222. if (/bmp/.test(type)) {
  223. var data = getImageData(scaleCanvas(canvas, width, height));
  224. var strData = genBitmapImage(data);
  225. return genImage(makeURI(strData, 'image/bmp'));
  226. } else {
  227. var strData = getDataURL(canvas, type, width, height);
  228. return genImage(strData);
  229. }
  230. }
  231. };
  232.  
  233.  
  234.  
  235. return {
  236. saveAsImage: saveAsImage,
  237. saveAsPNG: function (canvas, width, height) {
  238. return saveAsImage(canvas, width, height, 'png');
  239. },
  240. saveAsJPEG: function (canvas, width, height) {
  241. return saveAsImage(canvas, width, height, 'jpeg');
  242. },
  243. saveAsGIF: function (canvas, width, height) {
  244. return saveAsImage(canvas, width, height, 'gif');
  245. },
  246. saveAsBMP: function (canvas, width, height) {
  247. return saveAsImage(canvas, width, height, 'bmp');
  248. },
  249.  
  250. convertToImage: convertToImage,
  251. convertToPNG: function (canvas, width, height) {
  252. return convertToImage(canvas, width, height, 'png');
  253. },
  254. convertToJPEG: function (canvas, width, height) {
  255. return convertToImage(canvas, width, height, 'jpeg');
  256. },
  257. convertToGIF: function (canvas, width, height) {
  258. return convertToImage(canvas, width, height, 'gif');
  259. },
  260. convertToBMP: function (canvas, width, height) {
  261. return convertToImage(canvas, width, height, 'bmp');
  262. }
  263. };
  264.  
  265. }();
Add Comment
Please, Sign In to add comment