vue3批量将图片添加水印并导出压缩包

vue3批量将图片添加水印并导出压缩包

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import JSZip from 'jszip'

const img_list = ref([
  { img: 'https://img.keaitupian.cn/uploads/2020/07/20/zv2owzexj5i.jpg' },
  { img: 'https://img.keaitupian.cn/uploads/2020/12/08/273813a415dbe086179ec092b693e8bb.jpg' },
  { img: 'http://n.sinaimg.cn/sinacn10106/159/w1080h1479/20190703/4cf3-hzfekep2552738.jpg' },
  { img: 'http://pic.bizhi360.com/bbpic/23/323.jpg' },
])

/**
* 根据图片的url转换对应的base64值,并添加水印
* @param { String } imageUrl 如:http://xxxx/xxx.png
* @returns base64取值
*/
const urlToBase64WithWatermark = (imageUrl, watermarkText) => {
  return new Promise((resolve, reject) => {
    let canvas:any = document.createElement('canvas');
    const ctx:any = canvas.getContext('2d');
    let img:any = new Image();
    img.crossOrigin = 'Anonymous'; // 解决Canvas.toDataURL 图片跨域问题
    img.src = imageUrl;
    img.onload = function () {
      canvas.height = img.height;
      canvas.width = img.width;
      ctx.drawImage(img, 0, 0); // 将图片绘制到画布上

      // 添加水印
      ctx.font = '30px Arial'; // 设置字体大小和字体
      const gradient = ctx.createLinearGradient(0, 0, canvas.width, canvas.height); // 创建从左上角到右下角的线性渐变
      gradient.addColorStop(0, '#666');
      gradient.addColorStop(0.5, '#666');
      gradient.addColorStop(1, '#666');
      ctx.fillStyle = gradient; // 颜色

      const watermarkWidth = ctx.measureText(watermarkText).width; // 计算水印文本的宽度

      for (let x = 0; x < canvas.width; x += watermarkWidth * 1.5) { // 水平方向上以水印文本宽度的1.5倍间隔
        for (let y = 0; y < canvas.height; y += 200) { // 垂直方向上以200像素间隔
          ctx.save(); // 保存当前绘图状态
          ctx.translate(x, y); // 移动绘图原点到当前位置
          ctx.rotate(-0.9); // 旋转文字
          ctx.fillText(watermarkText, 0, 0); // 在当前位置绘制水印
          ctx.restore(); // 恢复之前保存的绘图状态
        }
      }

      const dataURL = canvas.toDataURL('image/jpeg', 1); // 获取Base64编码
      resolve(dataURL);
      canvas = null; // 清除canvas元素
      img = null; // 清除img元素
    };
    img.onerror = function () {
      reject(new Error('Could not load image at ' + imageUrl));
    };
  });
}

const downloadImagesWithWatermark = async () => {
  const zip = new JSZip();
  for (const image of img_list.value) {
    const data:any = await urlToBase64WithWatermark(image.img, '测试水印');
    // 添加到压缩包
    zip.file(`${image.img.split('/').pop()}.jpg`, data.split('base64,')[1], { base64: true });
  }
  // 生成压缩包
  const content = await zip.generateAsync({ type: 'blob' });
  // 下载压缩包
  const link = document.createElement('a');
  link.href = URL.createObjectURL(content);
  link.download = 'images_with_watermark.zip';
  link.click();
}

onMounted(async () => {
  await downloadImagesWithWatermark();
})
</script>


posted @ 2024-03-29 16:48  小万子呀  阅读(73)  评论(1编辑  收藏  举报