更新记录

1.0.1(2026-06-22)

  • 更新文档

1.0.0(2026-06-22)

  • 新版发布

平台兼容性

uni-app(4.82)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
× ×
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
× × × × × × × × × × × ×

uni-app x(4.82)

Chrome Safari Android iOS 鸿蒙 微信小程序
× × ×

yt-watermark

uni-app / uni-app x 图片水印 UTS 插件。支持在图片上叠加四角文案水印全图斜铺旋转水印,输出 JPEG 并自动压缩。

平台 uni-app(Vue) uni-app x
Android
iOS
HarmonyOS(纯血鸿蒙)

特别提醒

  • 购买本插件前,请先试用,请先试用,请先试用,确认满足需求之后再行购买。虚拟物品一旦购买之后无法退款。
  • 如有使用上的疑问、bug,可以进交流群联系作者;
  • 请在合法范围内使用,若使用本插件做非法开发,本方概不负责;
  • 可扫描右侧二维码安装Android示例demo,体验插件功能。示例demo中的自定义相机插件。传送带:自定义相机
  • iOS使用示例demo测试时,要先修改manifest中项目名称后再打包(名称长度尽量短一点),不然会因为名称过长,导致App启动不了。
  • 插件需先引入再打自定义基座后使用

功能概览

  • 四角文案水印:在图片四角之一绘制多行文字,支持圆点前缀、左侧图标
  • 斜铺旋转水印:全图 30° 平铺半透明重复文字,可自定义内容与颜色
  • 图片压缩
  • 多种输入:本地路径、Base64、网络 URL
  • 文件管理:提供删除水印输出文件的 API

安装与配置

1. 导入插件

uni_modules/yt-watermark 放入项目的 uni_modules 目录。

2. manifest.json 配置

若业务中使用 uni.chooseImage 选图/拍照,需启用相机/相册相关模块。

uni-app x 项目manifest.json 中使用 app-android / app-ios / app-harmony):

{
  "app-android": {
    "distribute": {
      "modules": { "uni-media": {} }
    }
  },
  "app-ios": {
    "distribute": {
      "modules": { "uni-media": {} }
    }
  },
  "app-harmony": {
    "distribute": {
      "modules": { "uni-media": {} }
    }
  }
}

uni-app 项目(Vue,app-plus)

{
  "app-plus": {
    "modules": {
      "Camera": {}
    },
    "distribute": {
      "android": {
        "permissions": [
          "<uses-permission android:name=\"android.permission.CAMERA\"/>",
          "<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"/>",
          "<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>"
        ]
      },
      "ios": {}
    }
  }
}

相机、相册权限由系统模块统一管理,本插件无需额外声明 UTS 层权限。

3. 重新打包基座(重要)

本插件为 UTS 原生插件,修改插件代码或首次集成后,必须:

  • uni-app x:重新运行到真机 / 重新云打包
  • uni-app(Vue):重新制作自定义调试基座,或用新基座运行;正式版需重新云打包

热更新不会生效 UTS 原生层改动。


快速开始

引入

import * as WaterManager from '@/uni_modules/yt-watermark'

uni-app x 中可使用 TypeScript 类型断言(as WaterManager.AddWaterPara),uni-app Vue 项目可省略。

相册选图并加水印

uni.chooseImage({
  count: 1,
  sizeType: ['compressed'],
  sourceType: ['album'], // 相机改为 ['camera']
  success: (res) => {
    const imagePath = res.tempFilePaths[0]

    const contents = [
      { text: '2026-06-21 14:20:45' },
      { text: '巡视员1001号' },
      { text: '浙江省杭州市西湖区西湖景区' }
    ]

    WaterManager.pictureWatermark({
      waterType: 'leftBottom',
      rotateWater: true,
      rotateCustomText: '内部资料',
      rotateFontSize: 38,       // iOS 建议 16
      rotateTextColor: '#00ffff',
      compressSize: 1,
      configStyle: {
        fontSize: 40,           // iOS 建议 18
        textColor: '#ffffff',
        decorate: 'point',      // none | point | icon
        bottomY: 20
      },
      datas: {
        path: imagePath,
        contents: JSON.stringify(contents)
      },
      resultHandler: (result) => {
        if (result === '') {
          uni.showToast({ title: '加水印失败', icon: 'none' })
          return
        }
        // uni-app x:直接绑定
        // this.imagePath = result

        // uni-app(Vue):需 convertLocalFileSystemURL
        // #ifdef APP-PLUS
        this.imagePath = plus.io.convertLocalFileSystemURL(result)
        // #endif
      }
    })
  }
})

API 说明

pictureWatermark(para: AddWaterPara)

为图片添加水印,处理完成后通过 resultHandler 异步回调。

项目 说明
入参 AddWaterPara,见下方类型说明
回调 resultHandler(result: string)
成功 result_doc/watermark/water_{timestamp}.jpg 相对路径
失败 result 为空字符串 ''
线程 Android 在 IO 线程处理,回调切回主线程;iOS / HarmonyOS 在各自异步流程完成后回调

注意: datas.pathdatas.base64Str 至少传一个,否则插件不会执行并打印错误日志。

deleteResource(filePath: string): boolean

删除指定路径的水印图片文件。

项目 说明
入参 文件路径(支持 _doc/...file://、绝对路径、plus.io.convertLocalFileSystemURL 转换后的路径)
返回值 删除成功 true,文件不存在或删除失败 false
// 建议传入插件回调的原始 _doc 路径,或去掉 ?t= 缓存参数后的展示路径
const ok = WaterManager.deleteResource('_doc/watermark/water_xxx.jpg')

参数类型

完整字段注释见 utssdk/interface.uts

AddWaterPara

字段 类型 必填 默认值 说明
waterType string 四角锚点:leftBottom / rightBottom / leftTop / rightTop
rotateWater boolean true 是否叠加全图斜铺旋转水印
compressSize number 1 JPEG 压缩目标体积(MB)
rotateCustomText string 当前时间 斜铺水印文字
rotateFontSize number 24 斜铺水印字号
rotateTextColor string textColor 斜铺水印颜色,Hex 如 #ffffff
configStyle ConfigStyle 四角文案样式
datas PhotoInfo 图片与文案数据
resultHandler function 完成回调

ConfigStyle

字段 类型 必填 默认值 说明
fontSize number 14 四角文案字号
textColor string #ffffff 四角文案颜色(Hex)
decorate string none 修饰:none / point / icon(暂不支持icon)
topY number 50 顶部偏移,仅 leftTop / rightTop 有效
bottomY number 20 底部偏移,仅 leftBottom / rightBottom 有效

PhotoInfo

字段 类型 必填 说明
path string 二选一 原图路径(本地 / _doc / 网络 URL)
base64Str string 二选一 原图 Base64 或 Data URL
contents string 四角文案 JSON 字符串,JSON.stringify(PhotoContentInfo[])

PhotoContentInfo

字段 类型 必填 说明
text string 文案内容
icon string 图标路径,decorate = 'icon' 时使用(暂不支持icon)

使用示例

Base64 加水印

WaterManager.pictureWatermark({
  waterType: 'leftBottom',
  rotateWater: true,
  configStyle: { fontSize: 40, textColor: '#ffffff', decorate: 'point' },
  datas: {
    base64Str: 'data:image/jpeg;base64,/9j/4AAQ...',
    contents: JSON.stringify([{ text: 'Base64 水印测试' }])
  },
  resultHandler: (result) => {
    console.log(result) // _doc/watermark/water_xxx.jpg
  }
})

网络图片加水印

WaterManager.pictureWatermark({
  waterType: 'leftBottom',
  rotateWater: false,
  configStyle: { fontSize: 40, textColor: '#ffffff' },
  datas: {
    path: 'https://example.com/photo.jpg',
    contents: JSON.stringify([{ text: '网络图片水印' }])
  },
  resultHandler: (result) => {
    console.log(result)
  }
})

带图标的水印(decorate = 'icon')

const contents = [
  { text: '浙江省杭州市', icon: '/static/location.png' }
]

WaterManager.pictureWatermark({
  waterType: 'leftTop',
  rotateWater: true,
  configStyle: {
    fontSize: 40,
    textColor: '#ffffff',
    decorate: 'icon',
    topY: 50
  },
  datas: {
    path: imagePath,
    contents: JSON.stringify(contents)
  },
  resultHandler: (result) => { console.log(result) }
})

行为说明

文案排列顺序

contents 数组顺序决定堆叠方向:

waterType 排列规则
leftBottom / rightBottom 第 1 项最靠近底边,后续项向上
leftTop / rightTop 第 1 项最靠近顶边,后续项向下

示例(leftBottom):

[
  { text: '2026-06-21 14:20:45' },  // 最靠近底边
  { text: '巡视员1001号' },
  { text: '浙江省杭州市西湖区' }     // 最靠上
]

斜铺旋转水印

  • 旋转角度:30°
  • 透明度:约 40%
  • 平铺间距:水平约 100px、垂直约 180px(按图片与屏幕比例缩放)
  • rotateCustomText 为空时自动填充当前时间 yyyy-MM-dd HH:mm:ss

图片压缩

  1. 最长边超过 1280px 时,按仿微信规则等比缩放
  2. 使用 JPEG 格式输出,质量二分搜索,最多 6 轮,逼近 compressSize(MB)
  3. 若原图压缩后已小于目标体积,直接返回

输出路径

水印图默认保存到应用 _doc 目录下:

_doc/watermark/water_{timestamp}.jpg

各端 _doc 实际映射:

项目类型 Android iOS
uni-app x {filesDir}/watermark/ {Documents}/uni-app-x/apps/{appId}/.../watermark/
uni-app(Vue) /Android/data/{包名}/apps/{appId}/doc/watermark/ Documents/Pandora/apps/{appId}/doc/watermark/

回调 resultHandler 统一返回 _doc/... 相对路径,便于上传、持久化存储;展示时再按上文转换为 WebView 可访问地址。

支持的路径格式(输入 datas.path

格式 示例 说明
_doc _doc/uniapp_temp_xxx/camera/photo.jpg 相机拍照常见返回格式
绝对路径 /storage/.../xxx.jpg 相册压缩缓存路径
file:// file:///var/mobile/.../gallery/xxx.jpg iOS 相册常见返回格式
鸿蒙媒体 URI file://media/Photo/... 需保留 file://,勿手动去掉
网络 https://example.com/a.jpg 三端均支持下载后处理

字号建议

插件内部会按「图片尺寸 / 屏幕尺寸」比例缩放字号。Demo 中的参考值:

平台 rotateFontSize configStyle.fontSize
Android 38 ~ 40 40 ~ 50
HarmonyOS 38 ~ 40 40 ~ 50
iOS 16 ~ 18 18 ~ 20

实际项目请根据真机效果微调。


错误处理

失败时 resultHandler 收到空字符串 '',常见原因:

原因 排查建议
未传 pathbase64Str 至少传一种图片输入
图片路径无效 查看控制台 插件内部打印:原图路径 raw=... resolved=...
uni-app 相机 _doc 路径读失败 确认已重新制作自定义基座,插件版本包含最新路径解析逻辑
鸿蒙 file://media/ 读失败 勿手动去掉 file:// 前缀
加水印成功但图片不显示(uni-app Vue) 检查是否使用了 plus.io.convertLocalFileSystemURL,勿手动拼 file://
保存失败 确认 _doc 目录可写;查看控制台 插件内部打印: 日志

建议在回调中判断:

resultHandler: (result) => {
  if (result === '') {
    uni.showToast({ title: '加水印失败', icon: 'none' })
    return
  }
  this.setImagePath(result) // 见上文封装方法
}

项目 Demo

项目类型 示例文件
uni-app(Vue) pages/index/index.vue
uni-app x pages/index/water.uvue(如有)

Demo 包含:相册 / 相机选图加水印、Base64 加水印、网络图片加水印、删除水印文件。


uni-app(Vue)完整示例

适用于 vueVersion: 3 的 app-plus 项目

<template>
    <view class="content">
        <view class="group">
            <view class="item" @click="pictureAddWater(true)">
                <text class="title">相册选图片加水印</text>
            </view>
            <view class="item" @click="pictureAddWater(false)">
                <text class="title">相机拍摄加水印</text>
            </view>
            <view class="item" @click="Base64AddWater()">
                <text class="title">Base64加水印</text>
            </view>
        </view>
        <view class="group">
            <view class="item" @click="deleteResource">
                <text class="title">删除水印图片</text>
            </view>
            <navigator class="item" url="/pages/index/index">
                <text class="title">自定义相机</text>
            </navigator>
            <view class="item" @click="netWorkPictureWatermark(path)">
                <text class="title">网络图片添加水印</text>
            </view>
        </view>

        <image mode="widthFix" style="width: 600rpx;margin-top: 20rpx;" :src="path"></image>
    </view>
</template>

<script>
    import * as WaterManager from '@/uni_modules/yt-watermark'
    export default {
        data() {
            return {
                path: "https://bkimg.cdn.bcebos.com/pic/c2cec3fdfc039245d68842c299cdb3c27d1ed31b8fff", //
                base64Str: ""
            }
        },
        methods: {
            pictureAddWater(isAlbum) {
                uni.chooseImage({
                    count: 1,
                    sizeType: ["compressed"],
                    sourceType: isAlbum ? ["album"] : ['camera'],
                    success: (res) => {
                        const imagePath = res.tempFilePaths[0]
                        this.baseAddWater(imagePath);
                    },
                    fail: (err) => {
                        console.error('选择图片失败:', err)
                    }
                })
            },
            baseAddWater(imagePath) {
                console.log('选中图片:', imagePath)
                let rotateFontSize = 40;
                let fontSize = 50;
                if (uni.getSystemInfoSync().platform == "ios") {
                    rotateFontSize = 16;
                    fontSize = 18;
                }
                let androidList = [];
                let androidItem1 = {
                    text: "浙江省杭州市西湖区西湖景区之断桥残雪",
                    icon: null
                };

                let androidItem2 = {
                    text: "巡视员1001号",
                    icon: null
                };

                let androidItem3 = {
                    text: "2026-06-21 14:20:45",
                    icon: null
                };
                androidList.push(androidItem3);
                androidList.push(androidItem2);
                androidList.push(androidItem1);
                WaterManager.pictureWatermark({
                    waterType: 'leftBottom',
                    rotateWater: true,
                    rotateCustomText: '添加水印uts插件',
                    rotateFontSize: rotateFontSize,
                    rotateTextColor: "#00ffff",
                    configStyle: {
                        fontSize: fontSize,
                        decorate: 'point',
                        textColor: '#ffffff'
                    },
                    datas: {
                        path: imagePath,
                        contents: JSON.stringify(androidList)
                    },
                    resultHandler: (result) => {
                        if (uni.getSystemInfoSync().platform == "ios") {
                            this.path = "file://" + plus.io.convertLocalFileSystemURL(result)
                        } else {
                            this.path = result
                        }
                        console.log('水印完成:', this.path)
                    }
                })
            },
            deleteResource() {
                let value = WaterManager.deleteResource(this.path);
                uni.showToast({
                    title: value ? '删除成功' : '删除失败',
                    icon: 'none',
                    duration: 2000
                })
            },
            netWorkPictureWatermark(imagePath) {
                let rotateFontSize = 40;
                let fontSize = 50;
                if (uni.getSystemInfoSync().platform == "ios") {
                    rotateFontSize = 16;
                    fontSize = 18;
                }
                let androidList = [];
                let androidItem1 = {
                    text: "浙江省杭州市西湖区西湖景区之断桥残雪",
                    icon: null
                };

                let androidItem2 = {
                    text: "巡视员1001号",
                    icon: null
                };

                let androidItem3 = {
                    text: "2026-06-21 14:20:45",
                    icon: null
                };
                androidList.push(androidItem3);
                androidList.push(androidItem2);
                androidList.push(androidItem1);
                WaterManager.pictureWatermark({
                    waterType: 'leftBottom',
                    rotateWater: true,
                    rotateCustomText: '添加水印uts插件',
                    rotateFontSize: rotateFontSize,
                    rotateTextColor: "#00ffff",
                    configStyle: {
                        fontSize: fontSize,
                        decorate: 'point',
                        textColor: '#ffffff'
                    },
                    datas: {
                        path: imagePath,
                        contents: JSON.stringify(androidList)
                    },
                    resultHandler: (result) => {
                        if (uni.getSystemInfoSync().platform == "ios") {
                            this.path = "file://" + plus.io.convertLocalFileSystemURL(result)
                        } else {
                            this.path = result
                        }
                        console.log('水印完成:', this.path)
                    }
                })
            },
            Base64AddWater() {
                let rotateFontSize = 40;
                let fontSize = 50;
                if (uni.getSystemInfoSync().platform == "ios") {
                    rotateFontSize = 16;
                    fontSize = 18;
                }
                let androidList = [];
                let androidItem1 = {
                    text: "浙江省杭州市西湖区西湖景区之断桥残雪",
                    icon: null
                };

                let androidItem2 = {
                    text: "巡视员1001号",
                    icon: null
                };

                let androidItem3 = {
                    text: "2026-06-21 14:20:45",
                    icon: null
                };
                androidList.push(androidItem3);
                androidList.push(androidItem2);
                androidList.push(androidItem1);
                WaterManager.pictureWatermark({
                    waterType: 'leftBottom',
                    rotateWater: true,
                    rotateCustomText: '添加水印uts插件',
                    rotateFontSize: rotateFontSize,
                    rotateTextColor: "#00ffff",
                    configStyle: {
                        fontSize: fontSize,
                        decorate: 'point',
                        textColor: '#ffffff'
                    },
                    datas: {
                        base64Str: this.base64Str,
                        contents: JSON.stringify(androidList)
                    },
                    resultHandler: (result) => {
                        if (uni.getSystemInfoSync().platform == "ios") {
                            this.path = "file://" + plus.io.convertLocalFileSystemURL(result)
                        } else {
                            this.path = result
                        }
                        console.log('水印完成:', this.path)
                    }
                })
            }

        }
    }
</script>

<style>
    .content {
        width: 750rpx;
        height: 100%;
        flex: 1;
        background-color: antiquewhite;
        display: flex;
        flex-direction: column;
        padding-top: 20rpx;
        align-items: center;
    }

    .group {
        display: flex;
        align-items: center;
        flex-direction: row;
        width: 750rpx;
        padding-left: 20rpx;
        margin-top: 25rpx;
        justify-content: space-evenly;
    }

    .item {
        display: flex;
        align-items: center;
        justify-content: center;
        background-color: aquamarine;
        border-radius: 8rpx;
        height: 80rpx;
        /* width: 500rpx; */
        /* width: 300rpx; */
        margin-right: 20rpx;
        flex: 1;
    }

    .title {
        font-size: 26rpx;
    }
</style>

uni-app x 完整示例

适用于 .uvue 页面,可直接将回调路径绑定到 <image>

<template>
    <view class="content">
        <view class="group">
            <view class="item" @click="pictureAddWater(true)">
                <text class="title">相册选图片加水印</text>
            </view>
            <view class="item" @click="pictureAddWater(false)">
                <text class="title">相机拍摄加水印</text>
            </view>
            <view class="item" @click="Base64AddWater()">
                <text class="title">Base64加水印</text>
            </view>
        </view>
        <view class="group">
            <view class="item" @click="deleteResource">
                <text class="title">删除水印图片</text>
            </view>
            <navigator class="item" url="/pages/index/index">
                <text class="title">自定义相机</text>
            </navigator>
            <view class="item" @click="netWorkPictureWatermark(path)">
                <text class="title">网络图片添加水印</text>
            </view>
        </view>

        <image mode="widthFix" style="width: 600rpx;margin-top: 20rpx;" :src="path"></image>
    </view>
</template>

<script>
    import *as WaterManager from '@/uni_modules/yt-watermark'
    export default {
        data() {
            return {
                path: "https://bkimg.cdn.bcebos.com/pic/c2cec3fdfc039245d68842c299cdb3c27d1ed31b8fff",//
                base64Str: ""
            }
        },
        methods: {
            pictureAddWater(isAlbum : boolean) {
                uni.chooseImage({
                    count: 1,
                    sizeType: ["compressed"],
                    sourceType: isAlbum ? ["album"] : ['camera'],
                    success: (res) => {
                        const imagePath = res.tempFilePaths[0]
                        this.baseAddWater(imagePath);
                    },
                    fail: (err) => {
                        console.error('选择图片失败:', err)
                    }
                })
            },
            baseAddWater(imagePath : string) {
                console.log('选中图片:', imagePath)
                let rotateFontSize = 38;
                let fontSize = 40;
                // #ifdef APP-IOS
                rotateFontSize = 16;
                fontSize = 18;
                // #endif
                // #ifdef APP-ANDROID
                rotateFontSize = 38;
                fontSize = 40;
                // #endif
                let androidList : Array<WaterManager.PhotoContentInfo> = new Array();
                let androidItem1 = {
                    text: "浙江省杭州市西湖区西湖景区之断桥残雪",
                    icon: null
                } as WaterManager.PhotoContentInfo;

                let androidItem2 = {
                    text: "巡视员1001号",
                    icon: null
                } as WaterManager.PhotoContentInfo;

                let androidItem3 = {
                    text: "2026-06-21 14:20:45",
                    icon: null
                } as WaterManager.PhotoContentInfo;
                androidList.push(androidItem3);
                androidList.push(androidItem2);
                androidList.push(androidItem1);
                WaterManager.pictureWatermark({
                    waterType: 'leftBottom',
                    rotateWater: true,
                    rotateCustomText: '添加水印uts插件',
                    rotateFontSize: rotateFontSize,
                    rotateTextColor: "#00ffff",
                    configStyle: {
                        fontSize: fontSize,
                        decorate: 'point',
                        textColor: '#ffffff'
                    } as WaterManager.ConfigStyle,
                    datas: {
                        path: imagePath,
                        contents: JSON.stringify(androidList)
                    } as WaterManager.PhotoInfo,
                    resultHandler: (result) => {
                        console.log('水印完成:', result)
                        this.path = result
                    }
                } as WaterManager.AddWaterPara)
            },
            deleteResource() {
                let value = WaterManager.deleteResource(this.path);
                uni.showToast({
                    title: value ? '删除成功' : '删除失败',
                    icon: 'none',
                    duration: 2000
                })
            },
            netWorkPictureWatermark(imagePath : string) {
                let rotateFontSize = 38;
                let fontSize = 40;
                // #ifdef APP-IOS
                rotateFontSize = 16;
                fontSize = 18;
                // #endif
                // #ifdef APP-ANDROID
                rotateFontSize = 38;
                fontSize = 40;
                // #endif
                let androidList : Array<WaterManager.PhotoContentInfo> = new Array();
                let androidItem1 = {
                    text: "浙江省杭州市西湖区西湖景区之断桥残雪",
                    icon: null
                } as WaterManager.PhotoContentInfo;

                let androidItem2 = {
                    text: "巡视员1001号",
                    icon: null
                } as WaterManager.PhotoContentInfo;

                let androidItem3 = {
                    text: "2026-06-21 14:20:45",
                    icon: null
                } as WaterManager.PhotoContentInfo;
                androidList.push(androidItem3);
                androidList.push(androidItem2);
                androidList.push(androidItem1);
                WaterManager.pictureWatermark({
                    waterType: 'leftBottom',
                    rotateWater: true,
                    rotateCustomText: '添加水印uts插件',
                    rotateFontSize: rotateFontSize,
                    rotateTextColor: "#00ffff",
                    configStyle: {
                        fontSize: fontSize,
                        decorate: 'point',
                        textColor: '#ffffff'
                    } as WaterManager.ConfigStyle,
                    datas: {
                        path: imagePath,
                        contents: JSON.stringify(androidList)
                    } as WaterManager.PhotoInfo,
                    resultHandler: (result) => {
                        console.log('水印完成:', result)
                        this.path = result
                    }
                } as WaterManager.AddWaterPara)
            },
            Base64AddWater() {
                let rotateFontSize = 38;
                let fontSize = 40;
                // #ifdef APP-IOS
                rotateFontSize = 16;
                fontSize = 18;
                // #endif
                // #ifdef APP-ANDROID
                rotateFontSize = 38;
                fontSize = 40;
                // #endif
                let androidList : Array<WaterManager.PhotoContentInfo> = new Array();
                let androidItem1 = {
                    text: "浙江省杭州市西湖区西湖景区之断桥残雪",
                    icon: null
                } as WaterManager.PhotoContentInfo;

                let androidItem2 = {
                    text: "巡视员1001号",
                    icon: null
                } as WaterManager.PhotoContentInfo;

                let androidItem3 = {
                    text: "2026-06-21 14:20:45",
                    icon: null
                } as WaterManager.PhotoContentInfo;
                androidList.push(androidItem3);
                androidList.push(androidItem2);
                androidList.push(androidItem1);
                WaterManager.pictureWatermark({
                    waterType: 'leftBottom',
                    rotateWater: true,
                    rotateCustomText: '添加水印uts插件',
                    rotateFontSize: rotateFontSize,
                    rotateTextColor: "#00ffff",
                    configStyle: {
                        fontSize: fontSize,
                        decorate: 'point',
                        textColor: '#ffffff'
                    } as WaterManager.ConfigStyle,
                    datas: {
                        base64Str: this.base64Str,
                        contents: JSON.stringify(androidList)
                    } as WaterManager.PhotoInfo,
                    resultHandler: (result) => {
                        console.log('水印完成:', result)
                        this.path = result
                    }
                } as WaterManager.AddWaterPara)
            }

        }
    }
</script>

<style>
    .content {
        width: 750rpx;
        height: 100%;
        flex: 1;
        background-color: antiquewhite;
        display: flex;
        flex-direction: column;
        padding-top: 20rpx;
        align-items: center;
    }

    .group {
        display: flex;
        align-items: center;
        flex-direction: row;
        width: 750rpx;
        padding-left: 20rpx;
        margin-top: 25rpx;
        justify-content: space-evenly;
    }

    .item {
        display: flex;
        align-items: center;
        justify-content: center;
        background-color: aquamarine;
        border-radius: 8rpx;
        height: 80rpx;
        /* width: 500rpx; */
        /* width: 300rpx; */
        margin-right: 20rpx;
        flex: 1;
    }

    .title {
        font-size: 26rpx;
    }
</style>

常见问题(FAQ)

Q:uni-app 项目相机拍照后 resultHandler 返回空?

A:多为 _doc 路径未正确解析。请确认已重新制作自定义基座,并查看 Logcat / Xcode 控制台中 插件内部打印:uniDocumentPath=原图路径 resolved= 是否正确。

Q:uni-app x 正常、uni-app Vue 不正常?

A:两端 _doc 物理目录不同,插件已在 iOS/Android 原生层分别适配;业务层展示方式也不同(见上文差异表)。

Q:uniapp项目iOS端添加完水印加载不显示?

A:uniappo项目加水印完成回调的路径不显示可将返回的路径通过"file://" + plus.io.convertLocalFileSystemURL(result)转化一下再加载。

Q:修改插件后没效果?

A:UTS 插件必须重新制作自定义基座或云打包,不支持热更新。

更多好用实惠插件

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率: