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

Nodejs实现图片加水印 【使用jimp】

Nodejs实现图片加水印 【使用jimp】

先看效果

我们将使用jimp实现图片加上水印,可以结合路由进行用户上传后处理该图片生成带水印的图片返回个用户
在这里插入图片描述在这里插入图片描述

const path = require("path");
const jimp = require("jimp");/*** 给一张图片加水印* @param {string} waterFile - 水印图片的文件路径* @param {string} originFile - 原始图片的文件路径* @param {string} targetFile - 输出的带水印图片的文件路径* @param {number} [proportion=5] - 水印相对于原始图片的比例* @param {number} [marginProportion=0.01] - 水印相对于原始图片边距的比例* @param {number} [opacity=0.3] - 水印图片的透明度*/
async function mark(waterFile,originFile,targetFile,proportion = 5,marginProportion = 0.01,opacity = 0.5
) {// 并行读取水印图片和原始图片const [water, origin] = await Promise.all([jimp.read(waterFile),jimp.read(originFile),]);// 计算水印图片需要缩放的比例const curProportion = origin.bitmap.width / water.bitmap.width;// 按照比例缩放水印图片water.scale(curProportion / proportion);// 设置水印图片的透明度water.opacity(opacity);// 计算水印图片的旋转角度water.rotate(-45);// 水印平铺const watermarkWidth = water.bitmap.width;const watermarkHeight = water.bitmap.height;for (let y = -watermarkHeight; y < origin.bitmap.height + watermarkHeight; y += watermarkHeight) {for (let x = -watermarkWidth; x < origin.bitmap.width + watermarkWidth; x += watermarkWidth) {origin.composite(water, x, y, {mode: jimp.BLEND_SOURCE_OVER,opacitySource: opacity,});}}// 将带水印的图片写入到目标文件await origin.write(targetFile);
}// 测试函数,用于演示给图片加水印
async function test() {// 定义水印图片、原始图片和目标图片的路径const waterPath = path.resolve(__dirname, "./IMG.jpg");const originPath = path.resolve(__dirname, "./vuelogo.png");const targetPath = path.resolve(__dirname, "./new.jpg");// 给图片加水印await mark(waterPath, originPath, targetPath);
}// 调用测试函数
test();

还可以对其进行改造生成不同尺寸的水印图片

const path = require("path");
const jimp = require("jimp");/*** 给一张图片加水印* @param {string} waterFile - 水印图片的文件路径* @param {string} originFile - 原始图片的文件路径* @param {string} targetFile - 输出的带水印图片的文件路径* @param {number} [proportion=5] - 水印相对于原始图片的比例* @param {number} [marginProportion=0.01] - 水印相对于原始图片边距的比例* @param {number} [opacity=0.5] - 水印图片的透明度*/
async function mark(waterFile,originFile,targetFile,proportion = 5,marginProportion = 0.01,opacity = 0.5
) {// 并行读取水印图片和原始图片const [water, origin] = await Promise.all([jimp.read(waterFile),jimp.read(originFile),]);// 计算水印图片需要缩放的比例const curProportion = origin.bitmap.width / water.bitmap.width;// 按照比例缩放水印图片water.scale(curProportion / proportion);// 设置水印图片的透明度water.opacity(opacity);// 计算水印图片的旋转角度water.rotate(-45);// 水印平铺const watermarkWidth = water.bitmap.width;const watermarkHeight = water.bitmap.height;for (let y = -watermarkHeight; y < origin.bitmap.height + watermarkHeight; y += watermarkHeight) {for (let x = -watermarkWidth; x < origin.bitmap.width + watermarkWidth; x += watermarkWidth) {origin.composite(water, x, y, {mode: jimp.BLEND_SOURCE_OVER,opacitySource: opacity,});}}// 将带水印的图片写入到目标文件await origin.write(targetFile);
}// 测试函数,用于演示给图片加水印
async function test() {// 定义水印图片、原始图片和目标图片的路径const waterPath = path.resolve(__dirname, "./IMG.jpg");const originPath = path.resolve(__dirname, "./vuelogo.png");// 生成三种不同尺寸的水印图片const targetPathSmall = path.resolve(__dirname, "./new_small.jpg");const targetPathMedium = path.resolve(__dirname, "./new_medium.jpg");const targetPathLarge = path.resolve(__dirname, "./new_large.jpg");// 给图片加小尺寸水印await mark(waterPath, originPath, targetPathSmall, 10, 0.01, 0.5);// 给图片加中等尺寸水印await mark(waterPath, originPath, targetPathMedium, 5, 0.01, 0.5);// 给图片加大尺寸水印await mark(waterPath, originPath, targetPathLarge, 2.5, 0.01, 0.5);
}// 调用测试函数
test();

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • win7开机提示‘windows引导配置数据文件包含的os项目无效’解决方法
  • pnpm的使用
  • 课程设计/毕业设计Spring boot+vue仓库管理系统(文档、源码、数据库、远程部署、LW)
  • Python——爬虫
  • pve虚拟机使用
  • Vue的事件处理、事件修饰符、键盘事件
  • WordPress个性化站点
  • 学习日志8.10--防火墙ASPF
  • Java毕业设计 基于SSM和Vue的酒店管理系统小程序
  • [Java]面向对象-static继承
  • Java设计模式(命令模式)
  • 今日Java练习:选择题挑战
  • 用OpenCV与MFC写一个简单易用的图像处理程序
  • 9.C基础_指针与数组
  • 【vue3|第21期】Vue3中Vue Router的push和replace方法详解
  • 「译」Node.js Streams 基础
  • 【Linux系统编程】快速查找errno错误码信息
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • 【跃迁之路】【699天】程序员高效学习方法论探索系列(实验阶段456-2019.1.19)...
  • Apache的80端口被占用以及访问时报错403
  • JavaScript 基础知识 - 入门篇(一)
  • js写一个简单的选项卡
  • maven工程打包jar以及java jar命令的classpath使用
  • Mybatis初体验
  • node-glob通配符
  • SegmentFault 技术周刊 Vol.27 - Git 学习宝典:程序员走江湖必备
  • socket.io+express实现聊天室的思考(三)
  • vuex 学习笔记 01
  • XForms - 更强大的Form
  • 高度不固定时垂直居中
  • 嵌入式文件系统
  • 微信公众号开发小记——5.python微信红包
  • 小程序、APP Store 需要的 SSL 证书是个什么东西?
  • 写代码的正确姿势
  • 异步
  • ​软考-高级-系统架构设计师教程(清华第2版)【第1章-绪论-思维导图】​
  • ​用户画像从0到100的构建思路
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (6) 深入探索Python-Pandas库的核心数据结构:DataFrame全面解析
  • (C语言)输入一个序列,判断是否为奇偶交叉数
  • (Demo分享)利用原生JavaScript-随机数-实现做一个烟花案例
  • (vue)el-cascader级联选择器按勾选的顺序传值,摆脱层级约束
  • (第8天)保姆级 PL/SQL Developer 安装与配置
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (蓝桥杯每日一题)love
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转)ObjectiveC 深浅拷贝学习
  • (转)大道至简,职场上做人做事做管理
  • (转)机器学习的数学基础(1)--Dirichlet分布
  • (自适应手机端)响应式服装服饰外贸企业网站模板
  • .Net core 6.0 升8.0
  • .Net IE10 _doPostBack 未定义
  • .Net MVC4 上传大文件,并保存表单
  • .Net(C#)常用转换byte转uint32、byte转float等
  • .NET6 开发一个检查某些状态持续多长时间的类