image-rotate.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. export const imageRotate = async (
  2. url: string,
  3. direction: "row" | "column" = "row"
  4. ): Promise<void | Blob> => {
  5. const img = new Image();
  6. img.src = url;
  7. await new Promise((resolve) => (img.onload = resolve));
  8. let width = img.width;
  9. let height = img.height;
  10. if (width > height) {
  11. if (direction === "row") {
  12. return;
  13. }
  14. width = img.height;
  15. height = img.width;
  16. } else {
  17. if (direction === "column") {
  18. return;
  19. }
  20. width = img.height;
  21. height = img.width;
  22. }
  23. const canvas = document.createElement("canvas");
  24. canvas.width = width;
  25. canvas.height = height;
  26. const ctx = canvas.getContext("2d")!;
  27. const center =
  28. direction === "row" ? [img.width / 2, height / 2] : [img.height / 2, width / 2];
  29. ctx.translate(center[0], center[1]);
  30. ctx.rotate(((direction === "row" ? -1 : 1) * Math.PI) / 2);
  31. ctx.translate(-center[0], -center[1]);
  32. ctx.drawImage(img, 0, 0);
  33. return await new Promise<Blob>((resolve) =>
  34. canvas.toBlob(resolve as any, "image/png", 1)
  35. );
  36. };
  37. export const loadImage = async (blob: Blob) => {
  38. const img = new Image();
  39. img.src = URL.createObjectURL(blob);
  40. return new Promise<HTMLImageElement>((resolve) => (img.onload = () => resolve(img)));
  41. };
  42. export const fixImageSize = async (
  43. blob: Blob,
  44. max: number,
  45. min: number,
  46. scale = true
  47. ) => {
  48. const img = await loadImage(blob);
  49. let width = img.width;
  50. let height = img.height;
  51. if (!scale) {
  52. const diff = max - min;
  53. if (width > max) {
  54. max = width;
  55. min = max - diff;
  56. } else if (height > max) {
  57. max = height;
  58. min = max - diff;
  59. }
  60. }
  61. if (width > max) {
  62. height = (height / width) * max;
  63. width = max;
  64. } else if (height > max) {
  65. width = (width / height) * max;
  66. width = max;
  67. }
  68. let size = width > height ? width : height;
  69. size = size > min ? size : min;
  70. console.log(size, width, height);
  71. const $canvas = document.createElement("canvas");
  72. $canvas.width = size;
  73. $canvas.height = size;
  74. const ctx = $canvas.getContext("2d")!;
  75. ctx.rect(0, 0, size, size);
  76. ctx.fillStyle = "#fff";
  77. ctx.fill();
  78. ctx.drawImage(img, (size - width) / 2, (size - height) / 2, width, height);
  79. const newBlob = await new Promise<Blob | null>((resolve) =>
  80. $canvas.toBlob(resolve, "png")
  81. );
  82. return newBlob;
  83. };
  84. export const coverImageSize = async (
  85. blob: Blob,
  86. coverWidth: number,
  87. coverHeight: number,
  88. scale = true
  89. ) => {
  90. const img = await loadImage(blob);
  91. let width = img.width,
  92. useWidth;
  93. let height = img.height,
  94. useHeight;
  95. const proportion = coverWidth / coverHeight;
  96. const cProportion = width / height;
  97. if (cProportion > proportion) {
  98. useWidth = width;
  99. useHeight = width / proportion;
  100. } else if (cProportion < proportion) {
  101. // h偏大
  102. useWidth = height * proportion;
  103. useHeight = height;
  104. }
  105. const $canvas = document.createElement("canvas");
  106. $canvas.width = useWidth;
  107. $canvas.height = useHeight;
  108. const ctx = $canvas.getContext("2d")!;
  109. ctx.rect(0, 0, useWidth, useHeight);
  110. ctx.fillStyle = "#fff";
  111. ctx.fill();
  112. ctx.drawImage(img, (useWidth - width) / 2, (useHeight - height) / 2, width, height);
  113. const newBlob = await new Promise<Blob | null>((resolve) =>
  114. $canvas.toBlob(resolve, "png")
  115. );
  116. return {
  117. blob: newBlob!,
  118. width: useWidth,
  119. height: useHeight,
  120. };
  121. };