uni-app 拍照图片添加水印

获取图片信息

javascript 复制代码
 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方法压缩图片大小
javascript 复制代码
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;
};

压缩图片的方法

javascript 复制代码
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)
}
})

}
相关推荐
糕冷小美n2 小时前
elementuivue2表格不覆盖整个表格添加固定属性
前端·javascript·elementui
小哥不太逍遥2 小时前
Technical Report 2024
java·服务器·前端
沐墨染2 小时前
黑词分析与可疑对话挖掘组件的设计与实现
前端·elementui·数据挖掘·数据分析·vue·visual studio code
anOnion2 小时前
构建无障碍组件之Disclosure Pattern
前端·html·交互设计
threerocks2 小时前
前端将死,Agent 永生
前端·人工智能·ai编程
问道飞鱼3 小时前
【前端知识】Vite用法从入门到实战
前端·vite·项目构建
爱上妖精的尾巴3 小时前
8-10 WPS JSA 正则表达式:贪婪匹配
服务器·前端·javascript·正则表达式·wps·jsa
shadow fish4 小时前
react学习记录(三)
javascript·学习·react.js
小疙瘩5 小时前
element-ui 中 el-upload 多文件一次性上传的实现
javascript·vue.js·ui
Aliex_git5 小时前
浏览器 API 兼容性解决方案
前端·笔记·学习