uni-app 拍照图片添加水印

发布于:2024-10-13 ⋅ 阅读:(50) ⋅ 点赞:(0)

获取图片信息

 uni.chooseImage({
    count: 6, //默认9
    sizeType: ["original", "compressed"], //可以指定是原图还是压缩图,默认二者都有
    sourceType: ["camera"], //从相册选择
    success: async function (result: any) {
      if (!props.isMark) {
        const res: any = await uploadFilePromise(result.tempFilePaths[0]);
        if (res) {
          show.value = false;
        }
        emit("handleFileList", res);
        return;
      }
      show.value = true;
      const reader = new FileReader();
      reader.onload = async (e: any) => {
        originalImage.value = e.target.result;
        await addWatermark();
      };
      reader.readAsDataURL(result.tempFiles[0]);
    },
  });

添加水印

  1. 由于使用canvas添加水印后图片很大,所以压缩一下图片大小
  2. 使用compressImg1方法压缩图片大小
const addWatermark = () => {
  const img = new Image();
  img.onload = async () => {
    const canvas = document.createElement("canvas");
    const ctx: any = canvas.getContext("2d");

    // 设置画布大小与图片相同
    canvas.width = img.width;
    canvas.height = img.height;

    // 绘制原图
    ctx.drawImage(img, 0, 0);

    // 添加水印
    // 设置字体大小,假设图片宽度大于600px,字体大小为24px,否则为图片宽度的10%
    var fontSize = canvas.width > 600 ? canvas.width / 20 : 16;
    // 设置字体大小,并将其转换为像素值
    console.log(fontSize, "fontSizefontSize字体大小---");
    ctx.font = fontSize + "px Arial";
    // 设置字体样式

    let time = moment().format("YYYY-MM-DD HH:MM:SS");
    let height = canvas.height - 50;
    let height1 = canvas.height - 20;
    if (canvas.width > 600) {
      height = canvas.height - 290;
      height1 = canvas.height - 50;
    }
    //获取图片指定位置的像素颜色
    const pixel = ctx.getImageData(10, height, 1, 1).data;
    // 计算相对于背景的亮度
    const luminance = 0.2126 * pixel[0] + 0.7152 * pixel[1] + 0.0722 * pixel[2];
    // 根据亮度选择水印字体颜色
    const fontColor = luminance > 128 ? "black" : "#fff";
    ctx.fillStyle = fontColor ; // 半透明白色
    ctx.fillText("时间:" + time, 15, height);
    ctx.fillText(latLng.value, 15, height1);
    // 转换为 Base64
    watermarkedImage.value = await canvas.toDataURL("image/png", 0.8);
    let imgURL = await compressImg1(watermarkedImage.value, 0.8); // 压缩图片
    console.log(getBase64ImageSize(imgURL), "图片大小11111111111111");
    const result: any = await uploadFilePromise(imgURL);
    if (result) {
      show.value = false;
    }
    emit("handleFileList", result);
  };
  img.src = originalImage.value;
};

压缩图片的方法

export const   compressImg1 =  (base64, multiple)=> {
  return new Promise((resolve, reject) => {
    try {
  // 第一个参数就是需要加密的base65,
  // 第二个是压缩系数 0-1,
  // 第三个压缩后的回调 用来获取处理后的 base64
  if (!base64) {
    return
  }
  const length = base64.length / 1024
  // 压缩方法
  let newImage = new Image()
  let quality = 0.6    // 压缩系数0-1之间
  newImage.src = base64
  newImage.setAttribute('crossOrigin', 'Anonymous') // url为外域时需要
  let imgWidth,
      imgHeight
  let w = undefined
  newImage.onload = function () {
    // 这里面的 this 指向 newImage
    // 通过改变图片宽高来实现压缩
    w = this.width * multiple
    imgWidth = this.width
    imgHeight = this.height
    let canvas = document.createElement('canvas')
    let ctx = canvas.getContext('2d')
    if (Math.max(imgWidth, imgHeight) > w) {
      if (imgWidth > imgHeight) {
        canvas.width = w
        // 等比例缩小
        canvas.height = w * (imgHeight / imgWidth)
      } else {
        canvas.height = w
        // 等比例缩小
        canvas.width = w * (imgWidth / imgHeight)
      }
    } else {
      canvas.width = imgWidth
      canvas.height = imgHeight
      // quality 设置转换为base64编码后图片的质量,取值范围为0-1  没什么压缩效果
      // 还是得通过设置 canvas 的宽高来压缩
      quality = 0.6
    }
    ctx.clearRect(0, 0, canvas.width, canvas.height)
    ctx.drawImage(this, 0, 0, canvas.width, canvas.height) //  // 这里面的 this 指向 newImage
    let smallBase64 = canvas.toDataURL('image/jpeg', quality) // 压缩语句
    // 必须通过回调函数返回,否则无法及时拿到该值,回调函数异步执行
    console.log(`压缩前:${length}KB`)
    console.log(`压缩后:${smallBase64.length / 1024} KB`)
    resolve(smallBase64) 
  }
}
catch (error) {
  reject(error)
  throw new Error(error)
}
})

}