uni-app为图片添加自定义水印(升级版)

devtools/2024/11/22 17:21:37/

前置内容

uni-app为图片添加自定义水印(解决生成图片不全问题)

UI 升级

现在水印样式变成这样了:
在这里插入图片描述
在这里插入图片描述

代码

<template><canvas v-if="waterMarkParams.display" canvas-id="waterMarkCanvas" :style="canvasStyle"/>
</template><script>javascript">export default {data() {return {waterMarkParams: {display: false, // 控制 canvas 创建与销毁canvasWidth: 300, // 默认宽度canvasHeight: 225, // 默认高度}}},computed: {canvasStyle() {return {position: 'fixed', // 移除到屏幕外left: '9999px',width: this.waterMarkParams.canvasWidth + 'px',height: this.waterMarkParams.canvasHeight + 'px'}}},methods: {chooseImage() {uni.chooseImage({sourceType: ['all'],success: async ({ tempFilePaths, tempFiles }) => {// 这里就得到了带水印的图片路径列表const imgFileArr = await this.callAddWaterMark(tempFilePaths)}})},// 因为有可能在相册中选择多个图片,所以这里要依次生成水印async callAddWaterMark(imgPathArr) {let results = []if(imgPathArr.length > 0) {let addIndex = 0while(addIndex < imgPathArr.length) {const tempFilePath = await this.addWaterMark(imgPathArr[addIndex])results.push(tempFilePath)addIndex = addIndex + 1}}return results},addWaterMark(src) {return new Promise((resolve, reject) => {// 获取图片信息,配置 canvas 尺寸uni.getImageInfo({src,success: res => {// 修复部分手机(如红米9)手机屏幕比较窄拍摄出来的图片水印压缩着覆盖的问题this.waterMarkParams.canvasWidth = Math.max(res.width, 886);this.waterMarkParams.canvasHeight = res.height;this.waterMarkParams.display = trueconsole.log('当前图片信息waterMarkParams:', this.waterMarkParams);// 等待 canvas 元素创建this.$nextTick(() => {let context = uni.createCanvasContext("waterMarkCanvas", this);/* 绘制 */const { canvasWidth, canvasHeight } = this.waterMarkParams// 绘制前清空画布context.clearRect(0, 0, canvasWidth, canvasHeight);// 将图片src放到cancas内,宽高必须为图片大小context.drawImage(src, 0, 0, canvasWidth, canvasHeight, canvasWidth, canvasHeight);// 防伪码的位置const fangweiY = 320;// 保证水印能完整显示出来const [x, y] = [canvasWidth / 2, canvasHeight - (fangweiY + 100)];context.translate(x, y);// 标记一下坐标系,更容易理解/* context.beginPath();context.lineWidth = 2;context.strokeStyle = 'white';context.moveTo(- x, 0);context.lineTo(x, 0);context.moveTo(0, -y);context.lineTo(0, canvasHeight - y);context.stroke();context.closePath(); */fillText(context, 0, 70, '上海市·金山区', 'bold 56px "Microsoft YaHei"', 'white', 'center');fillText(context, -20, 220, '16:08', 'bold 150px "Microsoft YaHei"', 'white', 'right');fillRect(context, -4, 100, 8, 120, '#346DFF');fillText(context, 20, 140, '2024.04.18', 'bold 40px "Microsoft YaHei"', 'white', 'left');fillText(context, 20, 210, '星期四  晴 21℃', 'bold 40px "Microsoft YaHei"', 'white', 'left');fillText(context, 0, fangweiY, `防伪:JY20240418160748XIAOMI`, 'bold 40px "Microsoft YaHei"', 'white', 'center');/* 绘制marker图标 */// 蓝色外圆fillCircle(context, -260, 30, 30, '#346DFF');// 白色内圆fillCircle(context, -260, 30, 12, 'white');// 蓝色三角fillTriangle(context, -260, 78, -235, 48, -285, 48, '#346DFF');// 坐标原点移动到画布右上角context.translate(canvasWidth / 2, -y);const [rectWidth, rectHeight, rectX, rectY, lineWidth, lineHeight] = [200, 90, -550, 60, 300, 6];// 右上角矩形fillRect(context, rectX, 60, rectWidth, rectHeight, '#346DFF');// 右上角下划线fillRect(context, rectX + rectWidth, rectY + rectHeight - lineHeight, lineWidth, lineHeight, '#346DFF');// 右上角姓名fillText(context, rectX + rectWidth / 2, 120, '鹏北海', 'bold 40px "Microsoft YaHei"', 'white', 'center');// 右上角手机号码fillText(context, rectX + rectWidth + lineWidth / 2, 120, '15888888888', 'bold 34px "Microsoft YaHei"', 'white', 'center');// 一定要加上一个定时器否则进入到页面第一次可能会无法正常拍照,后几次才正常setTimeout(() => {// 本次绘画完重开开始绘画,并且在绘画完毕之后再保存图片,不然页面可能会出现白屏等情况context.draw(false, () => {console.log('!!!!!开始绘画', canvasWidth, canvasHeight);uni.canvasToTempFilePath({canvasId: "waterMarkCanvas",fileType: "jpg",width: canvasWidth,height: canvasHeight,destWidth: canvasWidth,destHeight: canvasHeight,success: ({ tempFilePath }) => {console.log('绘制成功', tempFilePath);this.waterMarkParams.display = falseresolve(tempFilePath)},fail: err => {reject(err)console.log(err);}}, this)})}, 1000);})}})})// 绘制文字function fillText(context, x, y, content, font, fontStyle, textAlign) {// 保存当前绘图状态context.save();// 设置字体样式context.font = font// 设置文字颜色为白色context.fillStyle = fontStyle// 设置文字水平居中对齐context.textAlign = textAligncontext.fillText(content, x, y)// 恢复到之前保存的绘图状态,清除样式设置context.restore();}// 绘制圆function fillCircle(context, x, y, r, fillStyle) {// 保存当前绘图状态context.save();context.beginPath();context.arc(x, y, r, 0, 2 * Math.PI);context.fillStyle = fillStyle;context.fill();context.closePath();// 恢复到之前保存的绘图状态,清除样式设置context.restore();}// 绘制三角形function fillTriangle(context, x1, y1, x2, y2, x3, y3, fillStyle) {// 保存当前绘图状态context.save();context.beginPath();context.moveTo(x1, y1);context.lineTo(x2, y2);context.lineTo(x3, y3);context.fillStyle = fillStyle;context.fill();context.closePath();// 恢复到之前保存的绘图状态,清除样式设置context.restore();}// 绘制矩形function fillRect(context, x, y, width, height, fillStyle) {// 保存当前绘图状态context.save();context.fillStyle = fillStyle;context.fillRect(x, y, width, height);// 恢复到之前保存的绘图状态,清除样式设置context.restore();}},}}
</script>

http://www.ppmy.cn/devtools/15625.html

相关文章

Qt Android 无法加载 assets 目录下 lua 校准脚本

问题描述 C 语言使用 fopen 无法打开 assets 目录下的文件。 项目的校准脚本在打包的时候都放在 assets 资源目录下&#xff0c;但是 assets 是压缩包&#xff0c;Android 下虚拟目录&#xff0c;所以 Qt 可以加载 assets 目录下文件&#xff0c;但是 C 语言的 fropen 函数却…

0054__【Linux】 sed命令详解

【Linux】 sed命令详解_linux sed-CSDN博客

CentOS上如何自定义开机启动服务

一&#xff1a;简单的例子 在CentOS7之后自定义开机启动服务&#xff0c;可以通过创建一个systemd服务单元文件来实现。以下是创建自定义服务并设置其开机启动的步骤&#xff1a; 1&#xff0c;编辑服务文件&#xff0c;并添加以下内容&#xff1a; [Unit] DescriptionMy cu…

模拟LinkedList实现的链表(无哨兵)

1.前言 我们将LinkdList视作链表, 底层设计了内部类Node类, 我这里依然没有用到泛型, 其实加上泛型依然很简单, 即将Node节点的数据域的类型由Int转换为E(<E>), 我在此不做赘述.同时实现了增删查改, 遍历等操作. 2.链表(无哨兵)的代码实现 public class LinkListTest …

Springboot+Vue项目-基于Java+MySQL的网上购物商城系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

巧用断点设置查找bug【debug】

默认设置的断点&#xff0c;当代码运行到断点处MCU就会被挂起&#xff0c;从而停在断点处。 但在某些情况下&#xff0c;如调试FCCU时&#xff0c;如果设置断点&#xff0c;MCU停下后将会导致 FCCU 配置WDG超时。或在调试类似电机控制类的应用时&#xff0c;不适当的断点会导 致…

体验一下使用 ArkUI 进行 HarmonyOS 开发并与 Compose 简单对比

作者&#xff1a;equationl 前言 最近几年各个技术公众号和技术群都在唱衰原生安卓开发&#xff0c;疯狂贩卖焦虑。 搞得我也焦虑的不行&#xff0c;在谷歌的 Compose 推出后就赶紧去学&#xff0c;但是又觉得好像 Compose 的热度也不算太高&#xff0c;又去学 Flutter 。 转…

SQL获取最后一次的数据

问题 有个表格(id,machineName,value,updatetime)&#xff0c;里面比如有10个机台&#xff0c;里面记录了这10个机台的几十万条数据 如何获取每个机台的最后一笔数据&#xff1f; machines表 解决办法 1.首先获得每个机台最后的更新时间 select machineName,max(updatetim…