Canvas2Image.js

Canvas2Image文件

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.gf.qytechs.cn/scripts/448530/1149183/Canvas2Imagejs.js

  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, filename) {
  47. var save_link = document.createElement('a');
  48. save_link.href = strData;
  49. save_link.download = filename;
  50. var event = new MouseEvent('click', { "bubbles": false, "cancelable": false });
  51. save_link.dispatchEvent(event);
  52.  
  53. }
  54.  
  55. function genImage(strData) {
  56. var img = document.createElement('img');
  57. //img.src = strData;
  58. img.src = /^data:image/.test(src) ? src : src + '?' + new Date().getTime();
  59. return img;
  60. }
  61.  
  62. function fixType(type) {
  63. type = type.toLowerCase().replace(/jpg/i, 'jpeg');
  64. var r = type.match(/png|jpeg|bmp|gif/)[0];
  65. return 'image/' + r;
  66. }
  67.  
  68. function encodeData(data) {
  69. if (!window.btoa) { throw 'btoa undefined' }
  70. var str = '';
  71. if (typeof data == 'string') {
  72. str = data;
  73. } else {
  74. for (var i = 0; i < data.length; i++) {
  75. str += String.fromCharCode(data[i]);
  76. }
  77. }
  78.  
  79. return btoa(str);
  80. }
  81.  
  82. function getImageData(canvas) {
  83. var w = canvas.width,
  84. h = canvas.height;
  85. return canvas.getContext('2d').getImageData(0, 0, w, h);
  86. }
  87.  
  88. function makeURI(strData, type) {
  89. return 'data:' + type + ';base64,' + strData;
  90. }
  91.  
  92.  
  93. /**
  94. * create bitmap image
  95. * 按照规则生成图片响应头和响应体
  96. */
  97. var genBitmapImage = function(oData) {
  98.  
  99. //
  100. // BITMAPFILEHEADER: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx
  101. // BITMAPINFOHEADER: http://msdn.microsoft.com/en-us/library/dd183376.aspx
  102. //
  103.  
  104. var biWidth = oData.width;
  105. var biHeight = oData.height;
  106. var biSizeImage = biWidth * biHeight * 3;
  107. var bfSize = biSizeImage + 54; // total header size = 54 bytes
  108.  
  109. //
  110. // typedef struct tagBITMAPFILEHEADER {
  111. // WORD bfType;
  112. // DWORD bfSize;
  113. // WORD bfReserved1;
  114. // WORD bfReserved2;
  115. // DWORD bfOffBits;
  116. // } BITMAPFILEHEADER;
  117. //
  118. var BITMAPFILEHEADER = [
  119. // WORD bfType -- The file type signature; must be "BM"
  120. 0x42, 0x4D,
  121. // DWORD bfSize -- The size, in bytes, of the bitmap file
  122. bfSize & 0xff, bfSize >> 8 & 0xff, bfSize >> 16 & 0xff, bfSize >> 24 & 0xff,
  123. // WORD bfReserved1 -- Reserved; must be zero
  124. 0, 0,
  125. // WORD bfReserved2 -- Reserved; must be zero
  126. 0, 0,
  127. // DWORD bfOffBits -- The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.
  128. 54, 0, 0, 0
  129. ];
  130.  
  131. //
  132. // typedef struct tagBITMAPINFOHEADER {
  133. // DWORD biSize;
  134. // LONG biWidth;
  135. // LONG biHeight;
  136. // WORD biPlanes;
  137. // WORD biBitCount;
  138. // DWORD biCompression;
  139. // DWORD biSizeImage;
  140. // LONG biXPelsPerMeter;
  141. // LONG biYPelsPerMeter;
  142. // DWORD biClrUsed;
  143. // DWORD biClrImportant;
  144. // } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
  145. //
  146. var BITMAPINFOHEADER = [
  147. // DWORD biSize -- The number of bytes required by the structure
  148. 40, 0, 0, 0,
  149. // LONG biWidth -- The width of the bitmap, in pixels
  150. biWidth & 0xff, biWidth >> 8 & 0xff, biWidth >> 16 & 0xff, biWidth >> 24 & 0xff,
  151. // LONG biHeight -- The height of the bitmap, in pixels
  152. biHeight & 0xff, biHeight >> 8 & 0xff, biHeight >> 16 & 0xff, biHeight >> 24 & 0xff,
  153. // WORD biPlanes -- The number of planes for the target device. This value must be set to 1
  154. 1, 0,
  155. // WORD biBitCount -- The number of bits-per-pixel, 24 bits-per-pixel -- the bitmap
  156. // has a maximum of 2^24 colors (16777216, Truecolor)
  157. 24, 0,
  158. // DWORD biCompression -- The type of compression, BI_RGB (code 0) -- uncompressed
  159. 0, 0, 0, 0,
  160. // DWORD biSizeImage -- The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps
  161. biSizeImage & 0xff, biSizeImage >> 8 & 0xff, biSizeImage >> 16 & 0xff, biSizeImage >> 24 & 0xff,
  162. // LONG biXPelsPerMeter, unused
  163. 0, 0, 0, 0,
  164. // LONG biYPelsPerMeter, unused
  165. 0, 0, 0, 0,
  166. // DWORD biClrUsed, the number of color indexes of palette, unused
  167. 0, 0, 0, 0,
  168. // DWORD biClrImportant, unused
  169. 0, 0, 0, 0
  170. ];
  171.  
  172. var iPadding = (4 - ((biWidth * 3) % 4)) % 4;
  173.  
  174. var aImgData = oData.data;
  175.  
  176. var strPixelData = '';
  177. var biWidth4 = biWidth << 2;
  178. var y = biHeight;
  179. var fromCharCode = String.fromCharCode;
  180.  
  181. do {
  182. var iOffsetY = biWidth4 * (y - 1);
  183. var strPixelRow = '';
  184. for (var x = 0; x < biWidth; x++) {
  185. var iOffsetX = x << 2;
  186. strPixelRow += fromCharCode(aImgData[iOffsetY + iOffsetX + 2]) +
  187. fromCharCode(aImgData[iOffsetY + iOffsetX + 1]) +
  188. fromCharCode(aImgData[iOffsetY + iOffsetX]);
  189. }
  190.  
  191. for (var c = 0; c < iPadding; c++) {
  192. strPixelRow += String.fromCharCode(0);
  193. }
  194.  
  195. strPixelData += strPixelRow;
  196. } while (--y);
  197.  
  198. var strEncoded = encodeData(BITMAPFILEHEADER.concat(BITMAPINFOHEADER)) + encodeData(strPixelData);
  199.  
  200. return strEncoded;
  201. };
  202.  
  203.  
  204. /**
  205. * [saveAsImage]
  206. * @param {[obj]} canvas [canvasElement]
  207. * @param {[Number]} width [optional] png width
  208. * @param {[Number]} height [optional] png height
  209. * @param {[String]} type [image type]
  210. * @param {[String]} filename [image filename]
  211. * @return {[type]} [description]
  212. */
  213. var saveAsImage = function(canvas, width, height, type, filename) {
  214. if ($support.canvas && $support.dataURL) {
  215. if (typeof canvas == "string") { canvas = document.getElementById(canvas); }
  216. if (type == undefined) { type = 'png'; }
  217. filename = filename == undefined || filename.length === 0 ? Date.now() + '.' + type : filename + '.' + type
  218. type = fixType(type);
  219.  
  220. if (/bmp/.test(type)) {
  221. var data = getImageData(scaleCanvas(canvas, width, height));
  222. var strData = genBitmapImage(data);
  223.  
  224. saveFile(makeURI(strData, downloadMimedownloadMime), filename);
  225. } else {
  226. var strData = getDataURL(canvas, type, width, height);
  227. saveFile(strData.replace(type, downloadMime), filename);
  228. }
  229. }
  230. };
  231.  
  232. var convertToImage = function(canvas, width, height, type) {
  233. if ($support.canvas && $support.dataURL) {
  234. if (typeof canvas == "string") { canvas = document.getElementById(canvas); }
  235. if (type == undefined) { type = 'png'; }
  236. type = fixType(type);
  237.  
  238. if (/bmp/.test(type)) {
  239. var data = getImageData(scaleCanvas(canvas, width, height));
  240. var strData = genBitmapImage(data);
  241. return genImage(makeURI(strData, 'image/bmp'));
  242. } else {
  243. var strData = getDataURL(canvas, type, width, height);
  244. return genImage(strData);
  245. }
  246. }
  247. };
  248.  
  249.  
  250. return {
  251. saveAsImage: saveAsImage,
  252. saveAsPNG: function(canvas, width, height, fileName) {
  253. return saveAsImage(canvas, width, height, 'png', fileName);
  254. },
  255. saveAsJPEG: function(canvas, width, height, fileName) {
  256. return saveAsImage(canvas, width, height, 'jpeg', fileName);
  257. },
  258. saveAsGIF: function(canvas, width, height, fileName) {
  259. return saveAsImage(canvas, width, height, 'gif', fileName);
  260. },
  261. saveAsBMP: function(canvas, width, height, fileName) {
  262. return saveAsImage(canvas, width, height, 'bmp', fileName);
  263. },
  264.  
  265. convertToImage: convertToImage,
  266. convertToPNG: function(canvas, width, height) {
  267. return convertToImage(canvas, width, height, 'png');
  268. },
  269. convertToJPEG: function(canvas, width, height) {
  270. return convertToImage(canvas, width, height, 'jpeg');
  271. },
  272. convertToGIF: function(canvas, width, height) {
  273. return convertToImage(canvas, width, height, 'gif');
  274. },
  275. convertToBMP: function(canvas, width, height) {
  276. return convertToImage(canvas, width, height, 'bmp');
  277. }
  278. };
  279.  
  280. }();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址