上传图片增加水印

<template>
  <div class="upload-watermark">
    <van-uploader
      v-model="fileList"
      :after-read="handleUpload"
      :max-size="10 * 1024 * 1024"
      :max-count="5"
      :multiple="true"
      accept="image/*"
      :file-list="fileList"
    />
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue";
import { UploaderFileListItem } from "vant";
import dayjs from "dayjs";

const fileList = ref<UploaderFileListItem[]>([]); // 用于展示加水印后的文件列表

const handleUpload = (file: UploaderFileListItem | UploaderFileListItem[]) => {
  const files = Array.isArray(file) ? file : [file]; // 确保无论是单文件还是多文件,`files` 都是数组

  files.forEach((fileItem, index) => {
    if (!fileItem.file) return; // 确保 fileItem.file 存在

    const reader = new FileReader();

    reader.onload = (e: ProgressEvent<FileReader>) => {
      const image = new Image();
      image.src = e.target?.result as string;

      image.onload = () => {
        const canvas = document.createElement("canvas");
        const ctx = canvas.getContext("2d");

        if (ctx) {
          // 设置画布大小为图片大小
          canvas.width = image.width;
          canvas.height = image.height;

          // 绘制上传的图片到画布
          ctx.drawImage(image, 0, 0, image.width, image.height);

          // 设置水印文本样式
          const text = "水印文本";
          const date = dayjs().format("YYYY-MM-DD HH:mm:ss");
          ctx.font = "40px Arial";
          ctx.fillStyle = "rgba(255, 255, 255, 0.3)";
          ctx.textAlign = "center";
          ctx.textBaseline = "middle";

          // 旋转角度和水印间隔设置
          const angle = (30 * Math.PI) / 180; // 转换为弧度
          const xOffset = 400; // 增大水平方向间隔
          const yOffset = 300; // 增大垂直方向间隔

          // 循环绘制水印,直到铺满整个画布
          for (let x = -canvas.width; x < canvas.width * 2; x += xOffset) {
            for (let y = -canvas.height; y < canvas.height * 2; y += yOffset) {
              ctx.save();
              ctx.translate(x, y);
              ctx.rotate(angle);

              // 绘制文本在上
              ctx.fillText(text, 0, -20);
              // 绘制时间在下
              ctx.fillText(date, 0, 20);

              ctx.restore();
            }
          }

          // 将处理后的图片导出为 base64 字符串,并替换 fileList 中对应的文件
          const watermarkedImage = canvas.toDataURL("image/jpeg");
          // 将水印后的图片添加到 fileList,并移除原始文件
          fileList.value = fileList.value.filter((item) => item !== fileItem); // 移除原始文件
          fileList.value.push({
            ...fileItem,
            url: watermarkedImage, // 使用加水印后的图片
          });
        }
      };
    };

    reader.readAsDataURL(fileItem.file);
  });
};
</script>

<style scoped lang="scss">
.upload-watermark {
  margin-top: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
}
</style>

效果图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值