当前位置: 首页 > news >正文

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]);},});

添加水印

  1. 由于使用canvas添加水印后图片很大,所以压缩一下图片大小
  2. 使用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语言】数据输出格式控制

数据的输出格式修饰 常用两种&#xff1a; 整型中&#xff0c;输出数据左对齐、右对齐、占m位、不足m位前补0。浮点型中&#xff0c;默认通过四舍五入保留小数点后6位&#xff0c;通过参数设置保留小数点后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 是新一代前端构建工具&#xff0c;官网地址&#xff1a;https://vitejs.cn&#xff0c;vite的优势如下&#xff1a; 轻量快速的热重载&#xff08;HMR&#xff09;&#xff0c;能实现极速的服务启动。对 TypeScript、JSX、CSS 等支持开箱即用。真正的按需编译&#xff0c…...

面试题:在 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 选择排序 *** 选择排序* 思路&#xff1a;遍历数组&#xff0c;找出&#xff08;选择&#xff09;最小的元素&#xff0c;然后和最左边的元素交换。接下来&#xff0c;再从第二个元素开始遍历整个数组。再找到最小的元素&#xff0c;再和第二个元素交换…...

深度学习:LSTM循环神经网络实现评论情感分析

目录 一、任务介绍 1.任务要求 2.信息内容 3.待思考问题 二、问题解决 1.将评论内容转换成语料库 2.获取每条评论的词向量、标签和长度 3.数据打包 4.建立LSTM循环神经网络模型 1.主程序代码 2.模型代码 5.建立训练集函数和测试集函数 一、任务介绍 1.任务要求 项…...

基于Arduino的环境监测装置

基于Arduino的环境监测装置 引言痛点功能前期准备软件硬件 项目开发硬件开发软件开发 功能演示更多精彩&#xff0c;欢迎关注 引言 本项目使用机智云Gokit2.0开发板&#xff0c;实现基于Arduino的环境监测装置&#xff0c;解决目前大多数人对环境数据要求逐渐增高的痛点。 痛…...

深度学习:模型攻击(Model Attack)详解

模型攻击&#xff08;Model Attack&#xff09;详解 模型攻击通常指在机器学习和人工智能领域中&#xff0c;故意设计的行为或方法&#xff0c;旨在操纵或欺骗机器学习模型的输出。这类攻击可能导致模型做出错误的决策或泄露敏感信息&#xff0c;对于安全性至关重要的应用&…...

CesiumLab介绍

软考鸭小程序 学软考,来软考鸭! 提供软考免费软考讲解视频、题库、软考试题、软考模考、软考查分、软考咨询等服务 CesiumLab是一个围绕Cesium平台设计的完整易用的数据预处理工具集&#xff0c;它旨在最大化提升三维数据可视化效率。本文将详细介绍CesiumLab的安装、主要功能…...

PyQt 入门教程(3)基础知识 | 3.2、加载资源文件

文章目录 一、加载资源文件1、PyQt5加载资源文件2、PyQt6加载资源文件 一、加载资源文件 常见的资源文件有图像与图标&#xff0c;下面分别介绍下加载资源文件的常用方法 1、PyQt5加载资源文件 2、PyQt6加载资源文件 PyQt6版本暂时没有提供pyrcc工具&#xff0c;下面介绍下在不…...

老照片修复工作流教程:用 ComfyUI 轻松还原历史记忆

你是否有过这样的遗憾&#xff1f; 那些珍贵的老照片因为时间的流逝&#xff0c;早已失去了当年的色彩&#xff0c;变得模糊、褪色&#xff0c;甚至破损&#xff1f; 今天带你了解如何使用 ComfyUI 的老照片修复工作流&#xff0c;通过简单的几步操作&#xff0c;在短短十几秒…...

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

简单的转换&#xff08;Simple Transformations&#xff09; 转换操作改变了一个对象的几何状态。QML元素对象通常能够被平移&#xff0c;旋转&#xff0c;缩放。下面我们将讲解这些简单的操作和一些更高级的用法。 我们先从一个简单的转换开始。用下面的场景作为我们学习的开始…...

低空产业园搭建技术详解

低空产业园的搭建技术是一个复杂而系统的工程&#xff0c;涉及多个方面的技术和策略。以下是对低空产业园搭建技术的详细解析&#xff1a; 一、规划与设计 1. 总体规划&#xff1a;低空产业园的规划需要结合地方经济发展、产业基础、政策导向等因素&#xff0c;制定科学合理的…...

怎样快速掌握mGBA测试套件:5个专业技巧确保模拟器稳定性

怎样快速掌握mGBA测试套件&#xff1a;5个专业技巧确保模拟器稳定性 【免费下载链接】mgba mGBA Game Boy Advance Emulator 项目地址: https://gitcode.com/gh_mirrors/mg/mgba mGBA作为一款开源的高精度Game Boy Advance模拟器&#xff0c;其测试套件是确保模拟器稳定…...

NitroShare高效使用指南:从安装到定制的全流程解析

NitroShare高效使用指南&#xff1a;从安装到定制的全流程解析 【免费下载链接】nitroshare-desktop Network file transfer application for Windows, OS X, & Linux 项目地址: https://gitcode.com/gh_mirrors/ni/nitroshare-desktop NitroShare是一款跨Windows、…...

STM32摇杆驱动设计:裸机与FreeRTOS下的轻量级Joystick模块实现

1. 项目概述“Joystick”并非一个通用型开源驱动库或标准化外设抽象层&#xff0c;而是一个面向特定毕业设计&#xff08;Tesis&#xff09;场景的嵌入式人机交互模块实现。其核心目标是为基于STM32系列微控制器&#xff08;如STM32F407VG、STM32F103C8T6等常见开发板&#xff…...

UE后期处理材质实战:从黑白蒙版到卡通渲染的进阶应用

1. 黑白蒙版遮罩的底层原理与应用 在UE4后期处理材质中&#xff0c;黑白蒙版遮罩是最基础也最实用的功能之一。我第一次接触这个功能时&#xff0c;被它强大的选择性处理能力惊艳到了——它能像手术刀一样精准地分离出场景中的特定物体。 核心原理其实很简单&#xff1a;通过Sc…...

终极Mailtrain故障排除指南:10个常见问题与快速解决方案

终极Mailtrain故障排除指南&#xff1a;10个常见问题与快速解决方案 【免费下载链接】mailtrain Self hosted newsletter app 项目地址: https://gitcode.com/gh_mirrors/ma/mailtrain Mailtrain作为一款自托管的 newsletter 应用&#xff0c;为用户提供了强大的邮件营销…...

FlowState Lab跨周期波动模式提取效果:从秒级到年度的规律发现

FlowState Lab跨周期波动模式提取效果&#xff1a;从秒级到年度的规律发现 1. 时间序列分析的革命性突破 时间序列分析领域最近迎来了一项重要突破。传统方法往往只能聚焦单一时间尺度&#xff0c;要么分析高频交易数据&#xff0c;要么研究季节性规律&#xff0c;很难同时捕…...

lite-avatar形象库部署教程:GPU共享模式下多租户数字人服务隔离方案

lite-avatar形象库部署教程&#xff1a;GPU共享模式下多租户数字人服务隔离方案 1. 项目概述 lite-avatar形象库是一个专业的数字人形象资产管理平台&#xff0c;基于HumanAIGC-Engineering/LiteAvatarGallery构建。这个库提供了150经过预训练的2D数字人形象&#xff0c;专门…...

RCE漏洞小结

RCE漏洞简介 所谓RCE漏洞&#xff0c;即Remote Code/Command Execution&#xff0c;远程代码执行和远程命令执行漏洞。在很多Web应⽤中&#xff0c;开发⼈员会使⽤⼀些函数&#xff0c;这些函数以⼀些字符串作为输⼊&#xff0c;功能是将输⼊的字符串当作代码或者命令来进⾏执…...

MOOTDX终极指南:Python通达信数据接口让量化分析变得简单高效

MOOTDX终极指南&#xff1a;Python通达信数据接口让量化分析变得简单高效 【免费下载链接】mootdx 通达信数据读取的一个简便使用封装 项目地址: https://gitcode.com/GitHub_Trending/mo/mootdx 你是否曾为获取股票数据而烦恼&#xff1f;面对复杂的API接口和繁琐的数据…...

ROS路径规划实战:用move_base让机器狗在Gazebo中自主导航(避坑指南)

ROS路径规划实战&#xff1a;用move_base让机器狗在Gazebo中自主导航&#xff08;避坑指南&#xff09; 当机器狗在仿真环境中流畅地绕过障碍物走向目标点时&#xff0c;那种成就感就像看着自家宠物第一次成功接住飞盘。作为ROS开发者&#xff0c;掌握move_base实现自主导航的能…...