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)
}
})

}
相关推荐
孟陬18 分钟前
Foobar 技术周刊#160:大模型让大规模形式化软件验证成为现实丨AI写C++代码之后会发生什么?丨我们真的需要alpha() 函数吗丨重试,有时会让故障更
前端·后端·typescript
flash俊杰1 小时前
屏幕感知双通道:截图之外,为什么还要一份 UIA 控件清单
前端
熟的生菜1 小时前
从零造一个腱绳驱动灵巧手——仿真器篇3:VTK 渲染与 3D 交互——看得见、点得着、转得动
前端
码间留白2 小时前
鸿蒙端对接 BLE 血压计:从一次握手到读数入库(二)设备篇
物联网·uni-app·鸿蒙·蓝牙ble·血压计
Henry-SAP2 小时前
SAP PP中的核心业务流程——离散制造、重复制造、流程制造三大模式解析
前端·数据库·人工智能·制造
徐小夕2 小时前
下载量超 30 万的开源智能体 Prime Agent:它把自己从 TypeScript 重写成了 Rust
前端·vue.js·github
Zhao-Jichao2 小时前
AI Prompting for Everyone 课程笔记 - P20 实验与期末项目 Lab and Final Project
前端·人工智能·笔记
Moment3 小时前
为什么这么多 Agent Harness 都选择 TypeScript
前端·后端·面试
toooooop83 小时前
CRMEB 故障排查笔记:安全网关只放行 GET/POST 怎么办
前端·javascript·vue.js·thinkphp6·crmeb
软件技术NINI3 小时前
基于SpringBoot和Vue的项目评审系统
javascript·vue.js·spring boot·后端·spring·毕业设计·毕设