uniapp结合u-upload组件实现拍照加水印图片上传功能(详细)

前言

本文将介绍如何使用uniApp和u-upload组件封装一个自动添加水印并上传图片的功能。整个过程涵盖了图片上传、canvas画布操作、水印绘制等多个技术点。

主要技术点

  • u-upload组件:用于图片的上传与展示。
  • Canvas画布: 用于在图片上绘制水印信息。
  • 异步操作: 用来处理图片信息的获取与水印绘制,确保操作的正确顺序。
  • 图片信息的获取: 通过uni.getImageInfo()获取图片的宽高等信息。
  • 地理位置的获取: 使用uni.getLocation()结合腾讯地图API获取当前位置,并显示在水印中。

实现效果

用户在选择或拍摄图片后,图片不会立即上传,而是通过Canvas在图片上绘制时间、地址、用户名称等水印信息。处理完毕后,带水印的图片将被替换原图并上传。(以下是运行到微信小程序的测试效果)

 

实现步骤

1. 使用u-upload组件

使用u-upload组件来处理图片选择和上传。同时准备了一个隐藏的 canvas 元素,用于绘制图片水印

<template>
  <view style="width: 100%">
    <u-upload
      ref="uUpload"
      :action="action"
      :source-type="sourceType"
      :file-list="defaultValue"
      :auto-upload="!isWatermark"
      @on-choose-complete="onChooseComplete"
    />
    <!--  Canvas画布,用于添加水印 -->
    <canvas
      canvas-id="watermarkCanvas"
      v-if="isCanvasShow"
      :style="{
        position: 'absolute',
        top: '-9999px',
        left: '-9999px',
        width: canvasWidth + 'px',
        height: canvasHeight + 'px',
      }"
    ></canvas>
    <!-- 模拟提示 -->
    <u-toast ref="uToast" />
  </view>
</template>

2. 处理选择图片后的逻辑

当用户选择图片后,触发 onChooseComplete 方法,开始处理图片水印。

由于这里是使用uView1.X版本所以在on-choose-complete事件中处理图片,如果是使用uView2.X版本,则在afterRead事件中处理图片

methods: {
  // 当选择图片后触发的事件
  async onChooseComplete(list, name) {
    if (this.isWatermark) {
      try {
        const index = list.length - 1;
        await this.drawWatermark(list, index); // 添加水印
      } catch (error) {
        console.error("水印处理失败", error);
      }
    }
  },

  // 处理水印并手动上传
  async drawWatermark(list, index) {
    try {
      const url = list[index].url;
      const size = list[index].file.size;

      // 获取当前时间:年-月-日 时:分:秒 星期
      this.currentTime = parseTime(new Date(), "{y}-{m}-{d} {h}:{i}:{s} {a}");
      // 设置mask: true,避免水印加载过程中用户执行其他操作
      uni.showLoading({ title: "加载水印中", mask: true });

      await this.getCurrentAddress(); // 获取当前地址

      const { width, height, path } = await this.getImageInfo(url); // 获取图片信息

      // 设置画布宽高
      this.canvasWidth = width;
      this.canvasHeight = height;
      this.isCanvasShow = true;

      // 等待 canvas 元素创建
      this.$nextTick(() => {
        let ctx = uni.createCanvasContext("watermarkCanvas", this);

        // 清除画布
        ctx.clearRect(0, 0, width, height);
        // 绘制图片
        ctx.drawImage(path, 0, 0, width, height);

        // 绘制地址水印
        this.drawAddressWatermark(ctx, width, height);

        // 绘制竖线水印、时间、创建人等
        this.drawOtherWatermarks(ctx, width, height);

        // 绘制结束后生成临时文件并上传
        ctx.draw(false, () => {
          uni.canvasToTempFilePath({
            canvasId: "watermarkCanvas",
            quality: 0.6, // 图片质量,范围0-1,1为最高质量
            width: width, // 画布宽度
            height: height, // 画布高度
            destWidth: width, // 输出图片宽度
            destHei
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值