uni-app 拍照图片添加水印
获取图片信息
uni.chooseImage({count: 6, //默认9sizeType: ["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]);},});
添加水印
- 由于使用canvas添加水印后图片很大,所以压缩一下图片大小
- 使用
compressImg1方法压缩图片大小
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);// 转换为 Base64watermarkedImage.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;
};
压缩图片的方法
export const compressImg1 = (base64, multiple)=> {return new Promise((resolve, reject) => {try {// 第一个参数就是需要加密的base65,// 第二个是压缩系数 0-1,// 第三个压缩后的回调 用来获取处理后的 base64if (!base64) {return}const length = base64.length / 1024// 压缩方法let newImage = new Image()let quality = 0.6 // 压缩系数0-1之间newImage.src = base64newImage.setAttribute('crossOrigin', 'Anonymous') // url为外域时需要let imgWidth,imgHeightlet w = undefinednewImage.onload = function () {// 这里面的 this 指向 newImage// 通过改变图片宽高来实现压缩w = this.width * multipleimgWidth = this.widthimgHeight = this.heightlet 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 = imgWidthcanvas.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 指向 newImagelet 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)
}
})}相关文章:
uni-app 拍照图片添加水印
获取图片信息 uni.chooseImage({count: 6, //默认9sizeType: ["original", "compressed"], //可以指定是原图还是压缩图,默认二者都有sourceType: ["camera"], //从相册选择success: async function (result: any) {if (!props.isMar…...
Docker-registry私有镜像仓库的安装
Docker-registry私有镜像仓库的安装 我在这里的镜像仓库搭建在ip为192.168.3.23的虚机中。 安装docker-registry 1.拉取镜像 # docker pull registry 2.查看镜像 # docker images REPOSITORY TAG IMAGE ID CREATE…...
在vue3中实现祖组件给后代组件传参,可以跨域几层。
使用provide和inject就可以 下面是祖组件代码: //这是祖组件// 引入provide import { provide } from "vue";//定义数据 const projectId ref("");// 给后代组件传参 provide("projectId", projectId); 下面是后代组件代码&#…...
【优选算法】——双指针(上篇)!
🌈个人主页:秋风起,再归来~🔥系列专栏:C刷题算法总结🔖克心守己,律己则安 目录 前言:双指针 1. 移动零(easy) 2. 复写零(easy) 3…...
【C语言】数据输出格式控制
数据的输出格式修饰 常用两种: 整型中,输出数据左对齐、右对齐、占m位、不足m位前补0。浮点型中,默认通过四舍五入保留小数点后6位,通过参数设置保留小数点后n位。 #include <stdio.h> #define PI 3.14159 /* 功能&#x…...
Qt-界面优化选择器的用法(70)
目录 描述 使用 类型选择器 ID 选择器 并集选择器 子控件选择器 伪控制器 描述 QSS 的选择器⽀持以下⼏种 选择器⽰例说明全局选择器*选择所有的 widget.类型选择器 (type selector)QPushButton选择所有的 QPushButton 和其⼦类的控件.类选择器 (class selector).QPus…...
全国职业技能大赛——信息安全管理与评估第一阶段BC、FW、WAF题目详细解析过程
💗需要职业技能大赛环境+WP,请联系我!🍬 博主介绍 👨🎓 博主介绍:大家好,我是 一个想当文人的黑客 ,很高兴认识大家~ ✨主攻领域:【渗透领域】【应急响应】 【edusrc漏洞挖掘】 【VulnHub靶场复现】【面试分析】 🎉欢迎关注💗一起学习👍一起讨论⭐️一起…...
基于Vite创建项目
vite 是新一代前端构建工具,官网地址:https://vitejs.cn,vite的优势如下: 轻量快速的热重载(HMR),能实现极速的服务启动。对 TypeScript、JSX、CSS 等支持开箱即用。真正的按需编译,…...
面试题:在 React 中如何绑定事件
在 React 中绑定事件处理器(event handlers)是一个常见的任务,通常涉及以下几个步骤: 定义一个事件处理器函数:在组件的类或者函数组件内部定义一个处理事件的函数。 在 JSX 中绑定事件处理器:在渲染 JSX 时,使用 on 前缀加上事件名称(如 onClick, onChange, onSubmit …...
前端将JSON或者table直接导出为excel
一、引入Sheetjs或者npm直接下载 <script lang"javascript" src"https://cdn.sheetjs.com/xlsx-0.20.3/package/dist/xlsx.full.min.js"></script> 二、页面中使用 //json导出为excel <button onclick"exportExcel()">导出…...
算法之排序
概述 记录排序算法。 1 选择排序 *** 选择排序* 思路:遍历数组,找出(选择)最小的元素,然后和最左边的元素交换。接下来,再从第二个元素开始遍历整个数组。再找到最小的元素,再和第二个元素交换…...
深度学习:LSTM循环神经网络实现评论情感分析
目录 一、任务介绍 1.任务要求 2.信息内容 3.待思考问题 二、问题解决 1.将评论内容转换成语料库 2.获取每条评论的词向量、标签和长度 3.数据打包 4.建立LSTM循环神经网络模型 1.主程序代码 2.模型代码 5.建立训练集函数和测试集函数 一、任务介绍 1.任务要求 项…...
基于Arduino的环境监测装置
基于Arduino的环境监测装置 引言痛点功能前期准备软件硬件 项目开发硬件开发软件开发 功能演示更多精彩,欢迎关注 引言 本项目使用机智云Gokit2.0开发板,实现基于Arduino的环境监测装置,解决目前大多数人对环境数据要求逐渐增高的痛点。 痛…...
深度学习:模型攻击(Model Attack)详解
模型攻击(Model Attack)详解 模型攻击通常指在机器学习和人工智能领域中,故意设计的行为或方法,旨在操纵或欺骗机器学习模型的输出。这类攻击可能导致模型做出错误的决策或泄露敏感信息,对于安全性至关重要的应用&…...
CesiumLab介绍
软考鸭小程序 学软考,来软考鸭! 提供软考免费软考讲解视频、题库、软考试题、软考模考、软考查分、软考咨询等服务 CesiumLab是一个围绕Cesium平台设计的完整易用的数据预处理工具集,它旨在最大化提升三维数据可视化效率。本文将详细介绍CesiumLab的安装、主要功能…...
PyQt 入门教程(3)基础知识 | 3.2、加载资源文件
文章目录 一、加载资源文件1、PyQt5加载资源文件2、PyQt6加载资源文件 一、加载资源文件 常见的资源文件有图像与图标,下面分别介绍下加载资源文件的常用方法 1、PyQt5加载资源文件 2、PyQt6加载资源文件 PyQt6版本暂时没有提供pyrcc工具,下面介绍下在不…...
老照片修复工作流教程:用 ComfyUI 轻松还原历史记忆
你是否有过这样的遗憾? 那些珍贵的老照片因为时间的流逝,早已失去了当年的色彩,变得模糊、褪色,甚至破损? 今天带你了解如何使用 ComfyUI 的老照片修复工作流,通过简单的几步操作,在短短十几秒…...
ESP-IDF Blink实例学习
文章目录 一、引言二、工程创建1、打开vscode点击ESP-IDF资源管理器2、选择ESP-IDF框架3、选择Show Examples4、选择blink5、点击Create project using example blink ,选择创建目录6、创建完成 三、硬件电路LED管脚分配四、修改menuconfig五、编译和下载运行 一、引言 Blink实…...
QT QML 练习8-Simple Transformations
简单的转换(Simple Transformations) 转换操作改变了一个对象的几何状态。QML元素对象通常能够被平移,旋转,缩放。下面我们将讲解这些简单的操作和一些更高级的用法。 我们先从一个简单的转换开始。用下面的场景作为我们学习的开始…...
低空产业园搭建技术详解
低空产业园的搭建技术是一个复杂而系统的工程,涉及多个方面的技术和策略。以下是对低空产业园搭建技术的详细解析: 一、规划与设计 1. 总体规划:低空产业园的规划需要结合地方经济发展、产业基础、政策导向等因素,制定科学合理的…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...
苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会
在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...
