uniapp图片加水印

1、uniapp加水印

1.1、创建画布容器

<canvas class="watermark-canvas" id="watermark-canvas" canvas-id="watermark-canvas":style="{ width: canvasWidth, height: canvasHeight }" />

1.2、获取水印内容

async getLocation() {const zero = (item) => item < 10 ? "0" + item : itemconst time = new Date();const yy = time.getFullYear();const mm = time.getMonth() + 1;const dd = time.getDate();const hh = time.getHours();const MM = time.getMinutes();const ww = time.getDay()const hm = zero(hh) + ':' + zero(MM)const ymd = yy + '-' + zero(mm) + '-' + zero(dd)const {name: location} = await this.$store.dispatch('location/juGetLocation')return {hm,ymd,address: location}},

1.3、添加水印上传图片

async chooseImage(e) {// #ifdef APP-PLUSlet status = await this.checkPermission()if (status !== 1) {return}// }// #endifuni.chooseImage({sourceType: sourceType[this.sourceTypeIndex],sizeType: ['compressed'],count: this.limit,success: async (res) => {let filePath = res.tempFilePaths[0]const watermark = await this.getLocation()
//压缩图片设置宽度,不然画不全uni.compressImage({src: filePath,quality: 80,success: async comres => {//绘制图片加水印let img = await this.fillTextToImg(comres.tempFilePath, watermark)uni.showLoading({title: '上传中...',mask: true})const arr = [img]// 上传图片const key = await this.$store.dispatch('upload/uploadFileList', arr)this.$emit('handleChangeKeys', {src: key,create_time: watermark.hm,sign_date: watermark.ymd,sign_local: watermark.address})uni.hideLoading()}})},fail: (err) => {}})},sleep(millisecond) {return new Promise((resolve) => {setTimeout(resolve, millisecond)})},fillTextToImg(file, watermark) {return new Promise((resolve, reject) => {uni.getImageInfo({src: file,success: async res => {
//设置画布大小,然后再画,不然会只画一部分this.canvasWidth = `${res.width}px`this.canvasHeight = `${res.height}px`await this.sleep(200)const ctx = uni.createCanvasContext('watermark-canvas', this)ctx.clearRect(0, 0, res.width, res.height)ctx.beginPath()ctx.drawImage(res.path, 0, 0, res.width, res.height)// 水印 字体大小,颜色,内容,位置ctx.beginPath()ctx.setFillStyle('#ffffff')const fontSize = res.width / 10ctx.setFontSize(fontSize)ctx.fillText(watermark.hm, res.width / 2 - res.width / 8, res.height / 2 - 50)ctx.setFontSize(res.width / 15)ctx.fillText(watermark.ymd, res.width / 2 - res.width / 6, res.height / 2 + 100)ctx.setFontSize(res.width / 17)ctx.fillText(watermark.address, res.width / 5 - 15, res.height / 1.5 + 50)// 开始绘制 (canvas -> 临时文件路径)ctx.draw(false, async () => {await this.sleep(500) // 某些平台 canvas 渲染慢,需要等待uni.canvasToTempFilePath({canvasId: 'watermark-canvas',destWidth: res.width,destHeight: res.height,fileType: 'jpg',quality: 0.8,success: (fileRes) => {resolve(fileRes.tempFilePath)},fail: (err) => {uni.showToast({title: err.errMsg,icon: 'none'})reject()},},this,)})},fail: (err) => {console.log('[Error getImageInfo]', err)uni.showToast({title: err.errMsg,icon: 'none'})reject()},})});},

1.4、设置画布位置,不让其显示

.watermark-canvas {transform: scale(1);transform-origin: 0 0;position: absolute;top: -999px;left: -999px;}

2、web端加水印(Image,FileReaderweb端才能使用)

// 获取本地图片的base64编码
// 使用在线图片链接的时候需要注意给图片设置crossOrigin属性
function fileToBase64Async(file) {return new Promise((resolve, reject) => {let reader = new FileReader();reader.readAsDataURL(file);reader.onload = (e) => {resolve(e.target.result);};});
}// fillText绘制的是默认的普通实线文本,strokeText绘制的是描边文本
function fillTextToImg(base64) {const img = new Image();img.src = base64;img.setAttribute("crossOrigin", "Anonymous");return new Promise((resolve, reject) => {img.onload = () => {// 生成一个 canvas 画布;const canvas = document.createElement("canvas");canvas.width = img.width;canvas.height = img.height;// 将现有需要添加水印的图片绘制到画布上;const ctx = canvas.getContext("2d");ctx.fillRect(0, 0, canvas.width, canvas.height);ctx.drawImage(img, 0, 0, canvas.width, canvas.height);const remFontSize = canvas.width / 35;ctx.font = "bolder " + remFontSize + "px Verdana";ctx.textAlign = "center";/**ctx.textAlign = "center|end|left|right|start";start:默认,文本在指定的位置开始。end:文本在指定的位置结束。center:文本的中心在指定的位置。left:文本左对齐。right:文本右对齐。**/ctx.strokeStyle = "#fff";const name = "@AAAAAAAAAAAAA";const spaceH = remFontSize * 0.3;ctx.fillText(name,canvas.width / 2,canvas.height - remFontSize - spaceH);resolve(canvas.toDataURL("image/jpeg"));};});
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/112838.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

防水款无源NFC卡片

产品参数&#xff1a; PN29_T 产品参数 产品型号 PN29_T 尺寸(mm) 85.8*41*2.9mm 显示技术 电子墨水屏 显示区域(mm) 29(H) * 66.9(V) 分辨率(像素) 296*128 像素尺寸(mm) 0.227*0.226 显示颜色 黑/白 视觉角度 180 工作温度 0-50℃ 电池 无需电池 工作…

flutter与原生 相互通信实战

一、原生和flutter 通信 ios 通信类 CommonUtil.swift import Foundation import Flutterpublic class CommonUtil {public static func emitEvent(channel: FlutterMethodChannel, method: String, type: String, errCode: Int32?, errMsg: String?, data: Any?){safeMa…

Stable Diffusion原理

一、Diffusion扩散理论 1.1、 Diffusion Model&#xff08;扩散模型&#xff09; Diffusion扩散模型分为两个阶段&#xff1a;前向过程 反向过程 前向过程&#xff1a;不断往输入图片中添加高斯噪声来破坏图像反向过程&#xff1a;使用一系列马尔可夫链逐步将噪声还原为原始…

“智能+”时代,深维智信如何借助阿里云打造AI内容生成系统

云布道师 前言&#xff1a; 随着数字经济的发展&#xff0c;线上数字化远程销售模式越来越成为一种主流&#xff0c;销售流程也演变为线上视频会议、线下拜访等多种方式的结合。根据 Gartner 报告&#xff0c;到 2025 年 60% 的 B2B 销售组织将从基于经验和直觉的销售转变为数…

stable diffusion如何解决gradio外链无法开启的问题

问题确认 为了确认gradio开启不了是gradio库的问题还是stable diffusion的问题&#xff0c;可以先执行这样一段demo代码 import gradio as grdef greet(name):return "Hello " name "!"demo gr.Interface(fngreet, inputs"text", outputs&q…

QT获取USB相机具体属性信息

代码获取 #include <QCameraInfo>foreach (const QCameraInfo& cameraInfo, cameras) {QString device_name cameraInfo.deviceName();qDebug() << "Device Name: " << device_name;qDebug() << "Description: " << …

Unity之ShaderGraph如何实现飘动的红旗

前言 今天我们来实现一个飘动的红旗 如图所示&#xff1a; 关键节点 SimpleNoise&#xff1a;根据输入UV生成简单噪声或Value噪声。生成的噪声的大小由输入Scale控制。 Split&#xff1a;将输入向量In拆分为四个Float输出R、G、B和A。这些输出向量由输入In的各个通道定义&…

边缘检测算法

边缘检测算法是在数字图像处理中常用的一种技术&#xff0c;用于检测图像中物体边缘的位置。以下是几种常见的边缘检测算法&#xff1a; Sobel算子&#xff1a;Sobel算子是一种基于梯度的算法&#xff0c;通过计算图像的水平和垂直方向的梯度值&#xff0c;并将其组合起来得到边…

UiPath:一家由生成式AI驱动的流程自动化软件公司

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 总结&#xff1a; &#xff08;1&#xff09;UiPath(PATH)的股价并没有因为生成式AI的炒作而上涨&#xff0c;但很可能会成为主要受益者。 &#xff08;2&#xff09;即使在严峻的宏观环境下&#xff0c;UiPath的收入还在不…

Flink学习之旅:(四)Flink转换算子(Transformation)

1.基本转换算子 基本转换算子说明映射&#xff08;map&#xff09;将数据流中的数据进行转换&#xff0c;形成新的数据流过滤&#xff08;filter&#xff09;将数据流中的数据根据条件过滤扁平映射&#xff08;flatMap&#xff09;将数据流中的整体&#xff08;如&#xff1a;集…

Stable Diffusion WebUI几种解决手崩溃的方法

1. 添加与手相关负面提示词 如何提价提示词呢? 首先有一个embeddings模型文件bad-hands-5,我们可以去各个大模型网站去搜,我是在C站上面下载的。 附上C站地址:https://civitai.com/ 下载好之后,你需要将文件放入stable-diffusion-webui\embeddings目录中。位置如下所示…

物联网_00_物理网介绍

1.物联网为什么会出现? 一句话-----追求更高品质的生活, 随着科技大爆炸, 人类当然会越来越追求衣来伸手饭来张口的懒惰高品质生活, 最早的物联网设备可以追溯到19世纪末的"在线可乐售卖机"和"特洛伊咖啡壶"(懒惰的技术人员为了能够实时看到物品的情况而设…

通过核密度分析工具建模,基于arcgis js api 4.27 加载gp服务

一、通过arcmap10.2建模&#xff0c;其中包含三个参数 注意input属性&#xff0c;选择数据类型为要素类&#xff1a; 二、建模之后&#xff0c;加载数据&#xff0c;执行模型&#xff0c;无错误的话&#xff0c;找到执行结果&#xff0c;进行发布gp服务 注意&#xff0c;发布g…

微信小程序数据交互------WXS的使用

&#x1f3ac; 艳艳耶✌️&#xff1a;个人主页 &#x1f525; 个人专栏 &#xff1a;《Spring与Mybatis集成整合》《Vue.js使用》 ⛺️ 越努力 &#xff0c;越幸运。 1.数据库连接 数据表结构&#xff1a; 数据测式&#xff1a; 2.后台配置 pom.xml <?xml version&quo…

【音视频流媒体】 3、ffmpeg、ffplay、ffprobe 超详细介绍

文章目录 一、ffmpeg1.1 安装1.2 基本参数 二、ffprobe2.1 查编码格式2.2 查视频时长 五、视频转流5.1 MP4转H2645.2 H264转MP45.3 AVI转MP45.4 MP4转H265 六、视频文件6.1 播放6.2 filter 过滤器6.2.1 crop 6.3 视频截取6.4 视频拼接6.5 获取分辨率 七、视频和图7.1 视频抽帧7…

R语言中fread怎么使用?

R语言中 fread 怎么用&#xff1f; 今天分享的笔记内容是数据读取神器fread&#xff0c;速度嘎嘎快。在R语言中&#xff0c;fread函数是data.table包中的一个功能强大的数据读取函数&#xff0c;可以用于快速读取大型数据文件&#xff0c;它比基本的read.table和read.csv函数更…

【LeetCode】《LeetCode 101》第十三章:链表

文章目录 13.1 数据结构介绍13.2 链表的基本操作206. 反转链表&#xff08;简单&#xff09;21. 合并两个有序链表&#xff08;简单&#xff09;24.两两交换链表中的节点&#xff08;中等&#xff09; 13.3 其它链表技巧160. 相交链表&#xff08;简单&#xff09;234. 回文链表…

基于Pytorch的CNN手写数字识别

作为深度学习小白&#xff0c;我想把自己学习的过程记录下来&#xff0c;作为实践部分&#xff0c;我会写一个通用框架&#xff0c;并会不断完善这个框架&#xff0c;作为自己的入门学习。因此略过环境搭建和基础知识的步骤&#xff0c;直接从代码实战开始。 一.下载数据集并加…

【算法与数据结构】--高级算法和数据结构--高级数据结构

一、堆和优先队列 堆&#xff08;Heap&#xff09;是一种特殊的树状数据结构&#xff0c;通常用于实现优先队列。堆有两种主要类型&#xff1a;最大堆和最小堆。最大堆是一棵树&#xff0c;其中每个父节点的值都大于或等于其子节点的值&#xff0c;而最小堆是一棵树&#xff0…

关于使用 vxe-table 时设置了 show-overflow tooltip 不展示的问题(Dialog 组件和 table 同时使用)

众所周知&#xff0c;vxe-table 是可以支撑万级数据渲染的表格组件&#xff0c;本质上还是用了虚拟滚动的实现。之前一直知道vxe-table, 但是基本没有机会用的上这个组件&#xff0c;最近在开发埋点数据的统计&#xff0c;后端一次性返回了上千条数据&#xff0c;elementui 的 …