图片添加水印上传

585 阅读1分钟

本文采用Vue+elementUI上传组件进行举例

在上传之前,把水印加上,再继续传

async handleBeforeUpload(file) {
    this.loading = true;

    const { name, type } = file;
    this.oldFile = file;
    // 生成水印图片继续上传
    let newFile = await this.watermark(file)

    return new Promise(resolve => {
        newFile = new File([newFile], name, {
          type: type,
          lastModified: Date.now()
        })
        resolve(newFile);
    })
},

点击选择图片,图片文件 -> Image -> Canvas,在生成的图片占满的Canvas上插入水印文字,最后将合成的Canvas转化为Blob对象

async watermark(file) {
    const img = await this.blobToImg(file);
    let canvas = this.imgToCanvas(img);

    return new Promise((resolve) => {
        let ctx = canvas.getContext('2d');
        let waterHeight = canvas.height * 0.5;
        let waterWidth = (waterHeight * 180) / 160;
        ctx.fillText('水印', waterHeight/1.5, waterWidth/6);

        canvas.toBlob(async function(blob) {
          resolve(blob)
        });
    })
},

工具函数如下:

Blob转化为图片

blobToImg (blob) {
    return new Promise(resolve => {
        let reader = new FileReader()
        reader.addEventListener("load", () => {
          let img = new Image()
          img.src = reader.result
          img.addEventListener("load", () => {
            resolve(img)
          })
        })
        reader.readAsDataURL(blob)
    })
}

图片转换为Canvas

imgToCanvas (img) {
    let canvas = document.createElement("canvas")
    canvas.width = img.width
    canvas.height = img.height
    let ctx = canvas.getContext("2d")
    ctx.drawImage(img, 0, 0)

    ctx.rect(0, 0, canvas.width, canvas.height)
    ctx.fillStyle = "rgba(0, 0, 0, 0.2)"
    ctx.fill()
    return canvas
}