imagetoCanvas.ts 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import { Image2CanvasConfig } from '@models';
  2. /**
  3. * 将一个image对象转变为一个canvas对象
  4. *
  5. * @param {image} image
  6. *
  7. * @typedef {Object=} config - 转变为canvas时的一些参数配置
  8. * @param {number} width - canvas图像的宽度,默认为image的宽度
  9. * @param {number} height - canvas图像的高度,默认为image的高度
  10. * @param {number} scale - 相对于image的缩放比例,范围0-10,默认不缩放;
  11. * 设置config.scale后会覆盖config.width和config.height的设置;
  12. * @param {number} orientation - 图片旋转参数,默认不旋转,参考如下:
  13. * 参数 旋转方向
  14. * 1 0°
  15. * 2 水平翻转
  16. * 3 180°
  17. * 4 垂直翻转
  18. * 5 顺时针90°+水平翻转
  19. * 6 顺时针90°
  20. * 7 顺时针90°+垂直翻转
  21. * 8 逆时针90°
  22. * @type {config}
  23. *
  24. * @returns {Promise(canvas)}
  25. */
  26. export default async function imagetoCanvas(image: HTMLImageElement, config: Image2CanvasConfig = {}): Promise<HTMLCanvasElement> {
  27. const myConfig = { ...config };
  28. const cvs = document.createElement('canvas');
  29. const ctx = cvs.getContext('2d');
  30. let height;
  31. let width;
  32. for (const i in myConfig) {
  33. if (Object.prototype.hasOwnProperty.call(myConfig, i)) {
  34. myConfig[i] = Number(myConfig[i]);
  35. }
  36. }
  37. // 设置宽高
  38. if (!myConfig.scale) {
  39. width = myConfig.width || myConfig.height * image.width / image.height || image.width;
  40. height = myConfig.height || myConfig.width * image.height / image.width || image.height;
  41. } else {
  42. // 缩放比例0-10,不在此范围则保持原来图像大小
  43. const scale = myConfig.scale > 0 && myConfig.scale < 10 ? myConfig.scale : 1;
  44. width = image.width * scale;
  45. height = image.height * scale;
  46. }
  47. // 当顺时针或者逆时针旋转90时,需要交换canvas的宽高
  48. if ([5, 6, 7, 8].some(i => i === myConfig.orientation)) {
  49. cvs.height = width;
  50. cvs.width = height;
  51. } else {
  52. cvs.height = height;
  53. cvs.width = width;
  54. }
  55. // 设置方向
  56. switch (myConfig.orientation) {
  57. case 3:
  58. ctx.rotate(180 * Math.PI / 180);
  59. ctx.drawImage(image, -cvs.width, -cvs.height, cvs.width, cvs.height);
  60. break;
  61. case 6:
  62. ctx.rotate(90 * Math.PI / 180);
  63. ctx.drawImage(image, 0, -cvs.width, cvs.height, cvs.width);
  64. break;
  65. case 8:
  66. ctx.rotate(270 * Math.PI / 180);
  67. ctx.drawImage(image, -cvs.height, 0, cvs.height, cvs.width);
  68. break;
  69. case 2:
  70. ctx.translate(cvs.width, 0);
  71. ctx.scale(-1, 1);
  72. ctx.drawImage(image, 0, 0, cvs.width, cvs.height);
  73. break;
  74. case 4:
  75. ctx.translate(cvs.width, 0);
  76. ctx.scale(-1, 1);
  77. ctx.rotate(180 * Math.PI / 180);
  78. ctx.drawImage(image, -cvs.width, -cvs.height, cvs.width, cvs.height);
  79. break;
  80. case 5:
  81. ctx.translate(cvs.width, 0);
  82. ctx.scale(-1, 1);
  83. ctx.rotate(90 * Math.PI / 180);
  84. ctx.drawImage(image, 0, -cvs.width, cvs.height, cvs.width);
  85. break;
  86. case 7:
  87. ctx.translate(cvs.width, 0);
  88. ctx.scale(-1, 1);
  89. ctx.rotate(270 * Math.PI / 180);
  90. ctx.drawImage(image, -cvs.height, 0, cvs.height, cvs.width);
  91. break;
  92. default:
  93. ctx.drawImage(image, 0, 0, cvs.width, cvs.height);
  94. }
  95. return cvs;
  96. };