element-ui 自定义上传图片添加水印并上传至oss

随手笔记,这里我仅仅只是满足需求而封装的,如需使用还需要改进,这里只记一下方法。

  1. utils.js里封装打文字水印的方法
/**
 * 图片路径转成canvas
 * @param {图片url} url
 */
async function imgToCanvas(url) {
  // 创建img元素
  const img = document.createElement('img');
  img.src = url;
  img.setAttribute('crossOrigin', 'anonymous'); // 防止跨域引起的 Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
  await new Promise(resolve => {
    img.onload = resolve;
  });
  // 创建canvas DOM元素,并设置其宽高和图片一样
  const canvas = document.createElement('canvas');
  canvas.width = img.width;
  canvas.height = img.height;
  // 坐标(0,0) 表示从此处开始绘制,相当于偏移。
  canvas.getContext('2d').drawImage(img, 0, 0);
  return canvas;
}

/**
 * canvas添加水印
 * @param {canvas对象} canvas
 * @param {水印文字} text
 */
function addWatermark(canvas, texts) {
  const [text1, text2, text3] = texts;
  const ctx = canvas.getContext('2d');
  const x = canvas.width - 20;
  const y = canvas.height - 20;
  ctx.fillStyle = 'red';
  ctx.textBaseline = 'middle';
  ctx.font = '30px';
  ctx.textAlign = 'end';
  ctx.fillText(text1, x, y);
  ctx.fillText(text2, x, y - 20);
  ctx.fillText(text3, x, y - 40);
  return canvas;
}

/**
 * canvas转成img
 * @param {canvas对象} canvas
 */
function convasToImg(canvas) {
  // 新建Image对象,可以理解为DOM
  const image = new Image();
  // canvas.toDataURL 返回的是一串Base64编码的URL
  // 指定格式 PNG
  image.src = canvas.toDataURL('image/png');
  return image;
}

// 封装方法
export async function watermark(imgUrl, texts) {
  // 1.图片路径转成canvas
  const tempCanvas = await imgToCanvas(imgUrl);
  // 2.canvas添加水印
  const canvas = addWatermark(tempCanvas, texts);
  // 3.canvas转成img
  const img = convasToImg(canvas);
  return img;
}
  1. 上传组件封装
    在我的项目中用到了
    高德地图定位 amap-js
    阿里云存储 ali-oss
    oss我进行了封装,这里就直接引入使用





组件中使用,需要注意点的是

  • 将upload设为不自动上传 :auto-upload="false"
  • 自定义上传 :http-request="httpRequest"
  • 在change事件回调中处理图片信息,此时去调用封装的打水印方法
  • 水印打完之后返回一个base64的图片,需要转成blob或者file对象
  • 我这里转为blob,因为转为file对象之后图片有问题,所有我就转成了blob
 // 将base64转换为blob对象
    dataURLtoBlob(dataurl) {
      const arr = dataurl.split(',');
      const mime = arr[0].match(/:(.*?);/)[1];
      const bstr = window.atob(arr[1]);
      let n = bstr.length;
      const u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new Blob([u8arr], { type: mime });
    },
  • 最后再调用手动上传
// 转为blob对象
 this.fileUrl = this.dataURLtoBlob(cres.src);
// 手动上传
 this.$refs.upload.submit();

你可能感兴趣的:(element-ui 自定义上传图片添加水印并上传至oss)