/**
 * @name canvas绘制多个图片
 * @param {String} canvasId
 * @param {Array} base64List    [ {width,height,base64,path},... ],
 * @param {Number} canvasWidth  canvas宽度
 * @param {Number} canvasHeight canvas高度
 * @param {Number} destWidth    输出图片宽度
 * @param {Number} destHeight   输出图片高度
 * @param {String} fileType     输出图片类型 png | jpg
 * @param {Number} scale        是否缩放输出图片比例
 * @param {Number} quality      生成图片质量
 * @param {String} backgroundColor  生成图片背景色
 * @returns void
 */
export function canvasDrawBase64Images({
  canvasId,
  base64List,
  canvasWidth,
  canvasHeight,
  destWidth = null,
  destHeight = null,
  fileType = "jpg",
  scale = 1,
  quality = 0.8,
  backgroundColor = null,
}) {
  return new Promise((resolve, reject) => {
    const that = this;
    const ctx = uni.createCanvasContext(canvasId, that);
    if (backgroundColor) {
      ctx.setFillStyle(backgroundColor);
      ctx.fillRect(0, 0, canvasWidth, canvasHeight);
    }
    if (base64List.length === 0) return resolve(null);
    const drawImage = (count = 0, drawWidth = 0, drawHeight = 0) => {
      const imgInfo = base64List[count];
      // const base64Image = `data:image/png;base64,${imgInfo.base64}`;
      ctx.drawImage(
        imgInfo.path, // base64Image //要用临时路径、临时路径、临时路径,千万不要用base64真机无法显示 ,巨坑!!!
        drawWidth + 1,
        drawHeight + 1,
        imgInfo.width,
        imgInfo.height
      ); // 参数分别是图片地址,x坐标,y坐标,宽度,高度

      if (count >= base64List.length - 1) {
        ctx.draw(true, () => {
          let tempDestWidth = destWidth,
            tempDestHeight = destHeight;
          if (!destWidth) tempDestWidth = canvasWidth * scale;
          if (!destHeight) tempDestHeight = canvasHeight * scale;
          uni.canvasToTempFilePath(
            {
              canvasId,
              quality,
              fileType,
              x: 0,
              y: 0,
              width: canvasWidth,
              height: canvasHeight,
              destWidth: tempDestWidth,
              destHeight: tempDestHeight,
              success: function (res) {
                // 获取临时文件路径
                let tempFilePath = res.tempFilePath;
                // 将临时文件路径转换为base64
                uni.getFileSystemManager().readFile({
                  filePath: tempFilePath,
                  encoding: "base64",
                  success: function (data) {
                    // data.data就是base64字符串
                    let base64Image = data.data;
                    // 可以在这里做其他操作,例如保存base64到数据库等
                    let size = calculateBase64Size(base64Image);
                    if (size > 950) {
                      return reject({
                        code: 501,
                        msg: "图片过大,请重新选择图片!",
                      });
                    }
                    return resolve(base64Image);
                  },
                  fail: function (error) {
                    return reject({
                      code: 502,
                      msg: "图片转换失败!",
                      error: error,
                    });
                  },
                });
              },
              fail: function (error) {
                return reject({
                  code: 500,
                  msg: "合成图片失败!",
                  error: error,
                });
              },
            },
            that
          );
        });
      } else {
        ctx.draw(true, () => {
          // 别问为什么这里是true,莫名奇妙的bug,false时,合并两张以上图片 会消失一张
          // 继续绘制下一张图片
          drawImage(count + 1, 0, drawHeight + imgInfo.height + 1);
        });
      }
    };
    drawImage();
  });
}

夜雨入心
42 声望0 粉丝