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

}
相关推荐
mldong7 小时前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排7 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60618 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角9 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!9 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰9 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
mayaairi11 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen11 小时前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能
风骏时光牛马12 小时前
AI源码分析:拆解模型底层实现逻辑
前端
BillKu12 小时前
全局样式变量:CSS 自定义属性(--border-color)和SCSS 变量($border-color)的说明
javascript·css·scss