canvas压缩图片并且添加水印

72 阅读1分钟

原理

canvas可以把图片画到画布上,然后进行质量的压缩,用算法合并相似像素,牺牲质量换空间,输出base64格式。


function generateWatermarkImage (originalImageUrl) {
  // 创建一个Image对象用于加载原始图片和水印图片
  const originalImage = new Image();
  originalImage.setAttribute("crossOrigin", "anonymous"); //关键,防止canvas跨域污染
  const watermarkImage = new Image();
  watermarkImage.setAttribute("crossOrigin", "anonymous"); //关键
  // 监听原始图片加载完成事件
  originalImage.onload = () => {
    // 创建一个canvas元素用于绘制图片
    const canvas = document.createElement("canvas");
    const context = canvas.getContext("2d");

    // 设置canvas的大小为原始图片的大小
    canvas.width = originalImage.width;
    canvas.height = originalImage.height;

    // 绘制原始图片
    context.drawImage(originalImage, 0, 0);

    // 绘制水印图片在左下角
    context.drawImage(
      watermarkImage,
      30,
      canvas.height - watermarkImage.height - 30
    );

    // 将canvas转换为DataURL
    const watermarkImageUrl = canvas.toDataURL("image/png");

    // 生成新的图片链接
    const newImageUrl = URL.createObjectURL(
      this.dataURLtoBlob(watermarkImageUrl)
    );
    // 在控制台打印新的图片链接
    console.log("newImageUrl", newImageUrl);
  };
  // 加载原始图片和水印图片
  originalImage.src = originalImageUrl;
  // watermarkImage.src = watermarkImageUrl;
}

// 将DataURL转换为Blob对象
function dataURLtoBlob (dataURL) {
  const arr = dataURL.split(",");
  const mime = arr[0].match(/:(.*?);/)[1];
  const bstr = 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 });
}
generateWatermarkImage('https://cdn2.thecatapi.com/images/3sf.jpg')