写一个可以批量修改图片分辨率的工具

说在前面

🎈在视觉内容至关重要的今天,图片尺寸的调整对于网站加载速度和用户体验有着直接影响。本文介绍的Node.js工具,通过简单的命令行操作,允许用户批量调整图片尺寸,支持单张图片和整个目录的操作,提供了按比例缩放和自定义宽高的灵活选项。这不仅提高了工作效率,也使得图片管理变得更加简单。

代码实现

1.依赖引入

(1)@jyeontu/j-inquirer

@jyeontu/j-inquirer 是一个 Node.js 的命令行交互模块,它可以方便地创建一个交互式命令行界面,用于与用户进行交互。它提供了多种常见的输入方式,如单选、多选、输入框、文件选择、目录选择等等,并且可以自定义提示信息、选项等。

(2)@jyeontu/progress-bar

@jyeontu/progress-bar 是一个 Node.js 的进度条模块,它可以在命令行中展示一个进度条,用于显示正在进行的操作的进度。它支持多种样式和配置选项,可以根据需要调整进度条的样式、长度、颜色等等。

(3)fs-extra

扩展了Node.js的fs模块,它提供了多种操作文件和目录的方法,如读取文件、写入文件、创建目录、删除文件等等。在 Node.js 中,我们可以使用 fs-extra 模块来读取和处理本地的文件。

(4)jimp

jimp 是一个纯 JavaScript 的图像处理库,它可以用于处理各种类型的图片,如 PNG、JPEG、BMP 等等。它提供了多种图像处理方法,如调整大小、裁剪、旋转、添加水印等等,可以轻松地实现各种图像处理需求。在 Node.js 中,我们可以使用 jimp 来读取和处理本地的图片文件。

2.命令行交互获取处理参数

(1)单张图片或批量

询问用户是要处理单个图片还是一个图片文件夹

async function askForSingleOrBatch() {const options = [{type: "list",message: "选择文件夹还是单张图片",name: "imgType",default: "单张图片",choices: ["文件夹", "单张图片"],},];const answers = await new inquirer(options).prompt();const { imgType } = answers;return imgType;
}
(2)获取图片路径

根据用户选择的类型(单个图片或文件夹),询问用户选择图片或文件夹的路径,并询问调整尺寸的方式。

async function askForParams(imgType) {const options = [];if (imgType === "文件夹") {options.push({type: "folder",message: "请选择图片目录",name: "imgFolder",default: "",dirname: baseDir,});} else {options.push({type: "file",message: "请选择图片",name: "img",default: "",dirname: baseDir,});}options.push({type: "list",message: "调整类型",name: "adjustType",default: "按比例",choices: ["按比例", "自定义宽高"],});const answers = await new inquirer(options).prompt();return answers;
}
(3)获取具体调整参数

根据用户选择的调整方式,询问用户具体的调整参数。

async function askForImgParams(adjustType) {const options = [];if (adjustType === "按比例") {options.push({type: "list",message: "请选择基准边",name: "referenceEdge",default: "宽",choices: ["宽", "高"],},{type: "input",message: "请输入基准边长度",name: "referenceEdgeLength",default: "800",validate: function (input) {const isNumber = !isNaN(input) && !isNaN(parseFloat(input));if (isNumber) {return true; // 输入有效} else {return "请输入一个有效的数字"; // 输入无效}},});} else {options.push({type: "input",message: "请输入宽度",name: "width",default: "1280",validate: function (input) {const isNumber = !isNaN(input) && !isNaN(parseFloat(input));if (isNumber) {return true; // 输入有效} else {return "请输入一个有效的数字"; // 输入无效}},},{type: "input",message: "请输入高度",name: "height",default: "720",validate: function (input) {const isNumber = !isNaN(input) && !isNaN(parseFloat(input));if (isNumber) {return true; // 输入有效} else {return "请输入一个有效的数字"; // 输入无效}},});}const answers = await new inquirer(options).prompt();return answers;
}

3.计算调整后图片分辨率

根据用户输入的参数,计算出调整后的图片宽度和高度。

function getWidthAndHeight(bitmap, params) {let { width, height } = bitmap;if (params.adjustType === "按比例") {if (params.referenceEdge === "宽") {const rate = params.referenceEdgeLength / width;width = params.referenceEdgeLength;height = height * rate;} else {const rate = params.referenceEdgeLength / height;height = params.referenceEdgeLength;width = width * rate;}} else {width = params.width;height = params.height;}width -= 0;height -= 0;return { width, height };
}
参数解释:
  • bitmap:这是一个Jimp对象,代表了加载的图片,包含了图片的原始宽度和高度信息。
  • params:这是一个对象,包含了用户通过命令行交互指定的调整参数,主要有:
    • adjustType:用户选择的调整类型,可以是"按比例"或"自定义宽高"。
    • referenceEdge:如果用户选择按比例调整,这个属性指定了参考边是"宽"还是"高"。
    • referenceEdgeLength:用户输入的基准边长度。
    • widthheight:如果用户选择自定义宽高,这两个属性会包含用户输入的宽度和高度值。
函数逻辑:
  1. 函数首先从bitmap对象中解构出原始的width(宽度)和height(高度)。

  2. 接下来,根据params.adjustType的值来判断用户选择的调整类型:

    • 如果是"按比例"("按比例"),则进一步检查params.referenceEdge的值:
      • 如果参考边是"宽"("宽"),则计算新的宽度为用户指定的基准边长度params.referenceEdgeLength,然后根据原始高度和新宽度的比例计算新的height
      • 如果参考边是"高"("高"),则计算新的height为用户指定的基准边长度,然后计算新的width
    • 如果用户选择的是"自定义宽高"(非"按比例"),则直接将用户指定的params.widthparams.height作为新的宽度和高度。
  3. 在计算出新的宽度和高度后,函数通过width -= 0;height -= 0;将数值转换为数字类型,以确保它们是数字而不是字符串。这是因为用户输入可能会被当作字符串处理,而在进行数学计算时需要确保它们是数字类型。

  4. 最后,函数返回一个包含新widthheight的对象。

注意:
  • 这个函数中的width -= 0;height -= 0;是一种类型转换的技巧,它利用了JavaScript的类型转换规则,将变量转换为数字类型。这种转换通常不是必须的,因为从bitmap对象中直接解构出来的widthheight应该已经是数字类型了。如果params.widthparams.height是从用户输入解析得到的,并且确定用户输入的是有效的数字,这两个转换语句可以省略。

4.获取修改后图片输出路径

根据用户选择的图片或文件夹路径,生成输出目录的路径,如果路径不存在则创建该目录。

async function getOutPutDir(img) {const pathName = img.split("\\");const name = pathName.pop();pathName.push("resizeImgOutPut");const outputPath = pathName.join("\\");if (!fs.existsSync(outputPath)) {fs.mkdirSync(outputPath);}pathName.push(name);return pathName.join("\\");
}

5.定义图片处理函数

(1)单张图片
async function resizeImg(params) {const outputPath = await getOutPutDir(params.img);const image = await Jimp.read(params.img);const { width, height } = getWidthAndHeight(image.bitmap, params);const newSizeImage = image.resize(width, height);newSizeImage.write(outputPath);
}
(2)图片目录
async function resizeDir(params) {const imgList = fs.readdirSync(params.imgFolder);for (let i = 0; i < imgList.length; i++) {if (imgList[i].match(/\.(jpg|jpeg|png|bmp|tiff|gif)$/i)) {await resizeImg({...params,img: params.imgFolder + "\\" + imgList[i],});}}
}

快速使用

安装

该工具已经发布到npm上,可以在命令行快速安装:

npm install -g jyeontu

功能选择

jyeontu img

选择调整图片尺寸,然后按提示输入或选择即可。

源码

Gitee

该工具的源码也已经开源,有兴趣的同学可以到Gitee上查看:

https://gitee.com/changkong1009/node-scripting-tool/tree/master/src/jyeontu/script/img/resize

欢迎star~

欢迎pr~

公众号

关注公众号『前端也能这么有趣』,获取更多有趣内容。

说在后面

🎉 这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打羽毛球 🏸 ,平时也喜欢写些东西,既为自己记录 📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解 🙇,写错的地方望指出,定会认真改进 😊,偶尔也会在自己的公众号『前端也能这么有趣』发一些比较有趣的文章,有兴趣的也可以关注下。在此谢谢大家的支持,我们下文再见 🙌。

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

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

相关文章

【机器学习】---无监督学习

引言 在机器学习的广阔领域中&#xff0c;无监督学习扮演着至关重要的角色。不同于有监督学习&#xff0c;无监督学习处理的是没有标签的数据集&#xff0c;即我们不知道每个数据点的正确答案或分类。然而&#xff0c;这并不意味着无监督学习无法为我们提供有价值的信息。相反…

AI音乐:创新引擎还是创意终结者?

✨作者主页&#xff1a; Mr.Zwq✔️个人简介&#xff1a;一个正在努力学技术的Python领域创作者&#xff0c;擅长爬虫&#xff0c;逆向&#xff0c;全栈方向&#xff0c;专注基础和实战分享&#xff0c;欢迎咨询&#xff01; 您的点赞、关注、收藏、评论&#xff0c;是对我最大…

学生管理系统更新(账号系统)

展示 头文件 #pragma once #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h>//输入输出函数 #include<stdlib.h>//动态分配函数和随机函数 #include<windows.h>//控制台程序&#xff0c;用来实现cmd指令&#xff0c;title指令&#xff0c;cls指令等等 …

Ollama深度探索:AI大模型本地部署的全面教程

目录 引言一、Ollama概述1、定义与定位2、核心功能3、技术优势4、应用场景 二、安装与配置1、系统要求2、安装方法3、配置指南4、启动Ollama服务 四、快速开始1、启动Ollama2、部署运行模型3、REEST API 五、自定义模型1、定制化的必要性2、使用Modelfile定制模型3、参数调整4、…

IPSEC VPN

IPSEC VPN IPSEC是为IP网络提供安全性的协议和服务的集合,是一种协议簇&#xff0c;一个基于网络层&#xff0c;应用密码学的安全信息协议组。一开始TCP/IP 没有考虑到信息的安全传输。IPSEC协议簇诞生的意义就是保证TCP/IP的安全传输。 伪头部校验&#xff1a;TCP再校验的时…

升级到tomcat10和Java 21后,idea控制台system.out.println输出中文乱码问题

最近一次性从tomcat 9升级到tomcat 10&#xff0c;同时Java sdk也从1.8升级到21。 升级过程中&#xff0c;当然会遇到很多问题&#xff0c;但是控制台输出中文乱码问题&#xff0c;着实折腾了很久。 1、尝试各种方法 网上说的很多通用方法都试过了&#xff0c;就是不生效。包…

前端:Element UI 与 Vuetify 的选择

vuetify优势 1、多端适配&#xff0c;Vuetify完全按照Material设计规范进行开发&#xff0c;每一个组件都经过精心设计&#xff0c;具有模块化、响应式和优秀的性能。 使用独特和动态的 布局 自定义您的应用程序&#xff0c;并使用 SASS 变量 自定义您的组件的样式。只需要做下…

【CT】LeetCode手撕—236. 二叉树的最近公共祖先

目录 题目1- 思路2- 实现⭐236. 二叉树的最近公共祖先——题解思路 3- ACM实现 题目 原题连接&#xff1a;236. 二叉树的最近公共祖先 1- 思路 模式识别 模式1&#xff1a;二叉树最近公共祖先 ——> 递归 判断 递归思路&#xff0c;分情况判断&#xff1a; 1.参数及返…

香港“试水”医疗多模态大模型

更好地引入及发掘行业数据有望为垂直领域内的多模态大模型开发提供新可能。中国香港特区传统科研优势要嫁接产业风口&#xff0c;国际化渠道如何与内地资源携手&#xff1f; 产业多模态大模型“风头”正盛&#xff0c;在积极寻找经济新动能的中国香港特区&#xff0c;相关产业…

SQL新手蜕变:掌握这20条常用SQL语句,让你也能成为高手!

序言 在现代软件开发中&#xff0c;SQL&#xff08;Structured Query Language&#xff0c;结构化查询语言&#xff09;作为与数据库交互的标准编程语言&#xff0c;是每个开发者必学的基础技能。掌握SQL并在数据库管理与数据分析中应用自如&#xff0c;能显著提升开发效率和数…

如何修复“AI的原罪”

如何修复“AI的原罪” 上个月&#xff0c;《纽约时报》声称&#xff0c;科技巨头OpenAI和谷歌不顾服务条款和版权法的禁止&#xff0c;将大量YouTube视频转录成文本&#xff0c;并将其用作人工智能模型的额外训练数据&#xff0c;从而进入了版权灰色地带。《纽约时报》还援引Me…

掌握JavaScript ES6精髓:探索函数和对象的高级扩展与实用技巧

序言 JavaScript&#xff0c;作为前端开发中不可或缺的语言&#xff0c;已经发展到了ECMAScript 2015&#xff08;简称ES6&#xff09;以及后续的版本。ES6带来了诸多语法上的改进和创新&#xff0c;使得代码更加简洁、优雅&#xff0c;同时也提供了更多的编程模式和实用技巧。…

【ONE·基础算法 || 记忆化搜索】

总言 主要内容&#xff1a;编程题举例&#xff0c;熟悉理解记忆化搜索类题型&#xff08;对比递归、动态规划理解运用&#xff09;。             文章目录 总言1、记忆化搜索1.1、基本介绍1.2、细节理解&#xff08;记忆搜索化、递归、动态规划……&#xff09; 2、斐…

idea插件开发之一起来开发个打印方法入参和返回值的插件吧!

写在前面 源码 。 在开发过程中为了调试代码我们就可能就需要知道某个方法入参的值是什么&#xff0c;或者是返回值是什么。此时&#xff0c;我们的解决办法一般都是debug&#xff0c;但是debug的效率说实话其实是不高的&#xff0c;特别是不断的调试&#xff0c;不断的debug。…

KT148A-SOP8语音芯片接收到一线串口指令到播放声音大概多长时间

一、问题简介 请问KT148A-SOP8语音芯片接收到一线串口指令&#xff0c;到播放出来声音&#xff0c;大概需要多长时间 我的需求是做按键提示音&#xff0c;初测了一下感觉有延时&#xff0c;这个要如何处理 详细说明 KT148A从接收到指令&#xff0c;到执行&#xff0c;到播放…

JavaScript基于时间的动画算法

前段时间无聊或有聊地做了几个移动端的HTML5游戏。放在不同的移动端平台上进行测试后有了诡异的发现&#xff0c;有些手机的动画会“快”一点&#xff0c;有些手机的动画会“慢”一点&#xff0c;有些慢得还不是一两点。 通过查找资料发现&#xff0c;基于帧的算法&#xff08…

多模态大模型时代下的文档图像智能分析与处理

0. 前言 随着人工智能技术的不断发展&#xff0c;尤其是深度学习技术的广泛应用&#xff0c;多模态数据处理和大模型训练已成为当下研究的热点之一&#xff0c;这些技术也为文档图像智能处理和分析领域带来了新的发展机遇。 多模态大模型时代下的文档图像智能分析与处理的研究…

Linux:用户账号和权限管理的命令

目录 一、Linux用户的分类和组的分类 1.1、用户账号和组账号 1.2、用户的分类 1.3、组账号 1.4、用户账号文件/etc/passwd 二、用户管理相关命令 2.1、chage命令&#xff1a;用来修改帐号和密码的有效期限&#xff0c;针对目前系统已经存在的用户 2.2、useradd&#xf…

【Numpy】一文向您详细介绍 np.abs()

【Numpy】一文向您详细介绍 np.abs() 下滑即可查看博客内容 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我静心耕耘深度学习领域、真诚分享知识与智慧的小天地&#xff01;&#x1f387; &#x1f393; 博主简介&#xff1a;985高校的普通本硕&#xff0c;曾…

数据结构-图的基本概念

图的定义 图时由非空的顶点集合和一个描述顶点之间关系的集合组成。可以定义为&#xff1a; ​​​​​​​ ​​​​​​​ ​​​​​​​ G表示一个图&#xff0c;V表示点集&#xff0c;E表示边集。集合E的每一个二元组都包含两个值和&#xff0c;表示…