node-canvas实现对图片的批量压缩

本文介绍了如何使用Node.js结合node-canvas库,通过遍历文件夹,读取图片并利用exif信息调整图片旋转,实现图片的批量压缩。涉及了文件操作、canvas处理、exif Orientation属性的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

node-canvas实现对图片的批量压缩

1.前置知识

1. node 的文件操作系统

  • node 的fs 文件操作系统可以对本地的文件进行增删改查等一些列操作
  • fs.readdir:读取指定文件夹下文件列表
  • fs.writeFileSync:写入指定文件,不存在则创建,存在则更新

2.node-canvas 库

  • node 版的canvas,使用方法略有差异同html
  • 包的引入:const {createCanvas, loadImage} = require('canvas');
  • let cvs =createCanvas(width,height):创建一个canvas的画布
  • let ctx =cvs.getContext(‘2d’): 获取这个画布
  • ctx.translate(0, height):设置这个画布起点,也就是旋转中心/起始点
  • ctx.rotate():根据起点去旋转指定角度,单位是角度
  • cvs.toBuffer(‘image/jpeg’):获得画布的buffer流,原理是获得base64,将用文件格式和base64进行转换成buffer
  • loadImage(path).then(image=>{}):读取指定路径下的文件,并创建一个new Image(),把路径绑定在src上,再把这个元素resolve出去
  • ctx.drawImage():将图片根据指定位置去绘制指定的长度与宽度

3.exif库与照片Orientation属性

  • 照片信息读取:var {ExifImage} = require('exif')
  • new ExifImage({image:path}):异步获取图片信息,里面包含图片的真实宽高,Orientation属性
  • Orientation属性:是一些相机及其手机等设备中,来标识相机拍摄时位置的参数
  • orientation的几种类型:
  • Orientation = 1(不翻转)
  • Orientation = 3 (180度翻转)
  • Orientation = 6 (顺时针翻转90度)
  • Orientation = 8 (逆时针翻转90度)

4.image-size库

  • 为了获取图片真实高度的库
  • 为了计算压缩比和图片比例

2.实现功能

1.读取指定文件夹,并循环读取文件

fs.readdir('./mt/', (err, files) => {
    if (err) {
        console.log(err);
    } else {
        // files 当前文件夹下文件名数组
        for (let i = 0; i < files?.length; i++) {  
	        if(files[i] ==='.DS_Store'){
                console.log('过滤无关文件名,后续可用正则');
            }else{
                readParame()
            }
        }
    }
})

2.获取图片尺寸和图片Orientation,并按照位置调整宽高

function readParame(filesPath){
    var dimensions = sizeOf('./mt/' + filesPath);
    let ratio = dimensions.width / dimensions.height; // 获取宽高比
    let width = 400,height; // 默认宽度,后续可做成配置项
    new ExifImage({ image : `./mt/${filesPath}` }, function (error, exifData) {
        if (error)
            console.log('Error: '+error.message);
        else{
            const Orientation = exifData ?.image ?.Orientation;
            console.log(Orientation,'Orientation');
            // 非正常拍摄位置则宽高互换
            if (!Orientation || Orientation === 1) {
                height = width / ratio;
            }else{
                height = width*ratio;
            }
            CreateCanvas(width, height,filesPath,Orientation)
        }
    });
}

3.利用canvas调整旋转处理图片压缩图片并写入到指定位置

const OrientationType ={
    1: 0, //(不翻转)
    3: 180, // 180度翻转
    6: 90, // 顺时针翻转90度
    8: -90 //  逆时针翻转90度
}
function CreateCanvas(width,height,path,Orientation,){
    let cvs = createCanvas(width,height)
    let ctx = cvs.getContext('2d');
    if([3,6,8 ].includes(Orientation)){
	    // 非正常位置则进行对应旋转
        console.log(OrientationType[Orientation]);
        ctx.translate(0, height);
        ctx.rotate((Number(OrientationType[Orientation]))*Math.PI/180)
    }
    loadImage('./mt/' + path).then(image => {
	    // 非正常位置则进行对应旋转
       if([3,6,8 ].includes(Orientation)){
        ctx.drawImage(image, 0,0 ,height,width)
       }else{
        ctx.drawImage(image, 0,0 ,width,height)
       }
       // 获得文件buffer,并将buffer写入指定路径
        const buffer = cvs.toBuffer('image/jpeg');
        fs.writeFileSync(`./cop/${path}`,buffer);
    })
}

3.完整代码

const fs = require('fs');
var sizeOf = require('image-size');
var {ExifImage} = require('exif')
const {createCanvas, loadImage} = require('canvas');
// Orientation = 1(不翻转)
// Orientation = 2 (左右翻转)
// Orientation = 3 (180度翻转)
// Orientation = 4 (上下翻转)
// Orientation = 5 (顺时针翻转90度后,左右翻转)
// Orientation = 6 (顺时针翻转90度)
// Orientation = 7 (逆时针翻转90度后,左右翻转)
// Orientation = 8 (逆时针翻转90度)

fs.readdir('./mt/', (err, files) => {
    if (err) {
        console.log(err);
    } else {
        let str=[]
        for (let i = 0; i < files?.length; i++) {
            if(files[i] ==='.DS_Store'){
                console.log(1);
            }else{
                readParame(files[i])
            }
            
        }
    }
})
function readParame(filesPath){
    var dimensions = sizeOf('./mt/' + filesPath);
    let ratio = dimensions.width / dimensions.height; // 获取宽高比
    let width = 400,height;
    new ExifImage({ image : `./mt/${filesPath}` }, function (error, exifData) {
        if (error)
            console.log('Error: '+error.message);
        else{
            const Orientation = exifData ?.image ?.Orientation;
            console.log(Orientation,'Orientation');
            if (!Orientation || Orientation === 1) {
                height = width / ratio;
            }else{
                height = width*ratio;
            }
            CreateCanvas(width, height,filesPath,Orientation)
        }
    });
}
const OrientationType ={
    1: 0, //(不翻转)
    3: 180, // 180度翻转
    6: 90, // 顺时针翻转90度
    8: -90 //  逆时针翻转90度
}
function CreateCanvas(width,height,path,Orientation,){
    let cvs = createCanvas(width,height)
    let ctx = cvs.getContext('2d');
    if([3,6,8 ].includes(Orientation)){
        console.log(OrientationType[Orientation]);
        ctx.translate(0, height);
        ctx.rotate((Number(OrientationType[Orientation]))*Math.PI/180)
    }
    loadImage('./mt/' + path).then(image => {
       if([3,6,8 ].includes(Orientation)){
        ctx.drawImage(image, 0,0 ,height,width)
       }else{
        ctx.drawImage(image, 0,0 ,width,height)
       }
        const buffer = cvs.toBuffer('image/jpeg');
        fs.writeFileSync(`./cop/${path}`,buffer);
    })
}
The complete Visual Behaviour Authoring framework for Unity, empowering you to create advanced AI Behaviours and Logic, including three separate, fully featured, yet seamlessly interchangeable modules for you to choose and easily add in your game: • Behaviour Trees • Hierarchical State Machines • Dialogue Trees NodeCanvas is a production ready framework used by many awesome games including Kim, Pamela, Hurtworld, Shroud of the Avatar, Kingdom and Ghost of a Tale. [Games Showcase] Feature Highlights ------------------------------------- • Choose the right tool for the task at hand. • Design reactive Behaviour Trees and Hierarchical State Machines within an intuitive, designer friendly visual node editor: (Full Undo/Redo, Zoom In/Out, Multi-selection, Duplication, Copy/Pasting, JSON Import/Export, Groups, Comments and more) • Use local & global variables of any type, visually or in code, for creating reusable and actor-oriented, parametric behaviours, optionally saving and loading those variables between gaming sessions. • Data Bind variables with any component property of any type directly. • Sync variables automatically over the network using UNET, for creating multiplayer games. • Visually Debug behaviours with realtime, colorful and informative runtime debugging. • Live Edit everything while in play mode to perfectly understand your design goals and how to achieve them. • Utilize any existing code directly with advanced and extremely fast Reflection Tasks, automatically integrating Unity's and 3rd Party asset APIs. • Work with Lists/Arrays, Enums, Interfaces and pretty much ANY Variable Type you need out-of-the-box. • React to world changes and transfer data using the built-in Event System. • Reuse and Bind made behaviours among any number of different agents. • Organize your designs using Behaviour Sub-Trees and Sub-State Machines. • Extend NodeCanvas Framework to create your own Actions, Conditions, Nodes or even completely new modules with the e
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

家雀安知鸿鹄志

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值