file.ts 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import { base64ToBlob, uuid } from "./comm";
  2. export type CanvasToPngOptions = {
  3. canvasId: string;
  4. proxy?: ComponentPublicInstance;
  5. canvasRef: UniElement;
  6. };
  7. /**
  8. * 将canvas转换为png图片
  9. * @param options 转换参数
  10. * @returns 图片路径
  11. */
  12. export function canvasToPng(options: CanvasToPngOptions): Promise<string> {
  13. return new Promise((resolve) => {
  14. // #ifdef APP
  15. options.canvasRef.parentElement!.takeSnapshot({
  16. success(res) {
  17. resolve(res.tempFilePath);
  18. },
  19. fail(err) {
  20. console.error(err);
  21. resolve("");
  22. }
  23. });
  24. // #endif
  25. // #ifdef H5
  26. const url = URL.createObjectURL(
  27. base64ToBlob(
  28. (options.canvasRef as unknown as HTMLCanvasElement)
  29. .querySelector("canvas")
  30. ?.toDataURL("image/png", 1) ?? ""
  31. )
  32. );
  33. resolve(url);
  34. // #endif
  35. // #ifdef MP
  36. uni.createCanvasContextAsync({
  37. id: options.canvasId,
  38. component: options.proxy,
  39. success(context) {
  40. // 获取2D绘图上下文
  41. const ctx = context.getContext("2d")!;
  42. const canvas = ctx.canvas;
  43. // 将canvas转换为base64格式的PNG图片数据
  44. const data = canvas.toDataURL("image/png", 1);
  45. // 获取base64数据部分(去掉data:image/png;base64,前缀)
  46. const bdataBase64 = data.split(",")[1];
  47. // 获取文件系统管理器
  48. const fileMg = uni.getFileSystemManager();
  49. // 生成临时文件路径
  50. // @ts-ignore
  51. const filepath = `${wx.env.USER_DATA_PATH}/${uuid()}.png`;
  52. // 将base64数据写入文件
  53. fileMg.writeFile({
  54. filePath: filepath,
  55. data: bdataBase64,
  56. encoding: "base64",
  57. success() {
  58. // 写入成功返回文件路径
  59. resolve(filepath);
  60. },
  61. fail() {
  62. // 写入失败返回空字符串
  63. resolve("");
  64. }
  65. });
  66. },
  67. fail(err) {
  68. console.error(err);
  69. resolve("");
  70. }
  71. });
  72. // #endif
  73. });
  74. }