node实现图片压缩
一、内容简介
效果预览:
二、node压缩图片
一开始是打算用TinyPNG
的API实现图片压缩,但是尝试过后发现压缩速度特别慢,而且好像还要花钱,果断就放弃了。改为使用imagemin。
这里是有一个坑的: 由于imagemin
不可以直接压缩图片,而是需要依赖imagemin-jpegtran
和imagemin-pngquant
,但是在安装imagemin-pngquant
时会安装不了,找到了一个原因是说这个库是基于一些底层语言实现,所以不能直接安装,需要在电脑上安装另一个依赖libpng
。
安装libpng
直接贴一个安装brew的地址:zhuanlan.zhihu.com/p/90508170,只要对着他说的敲命令基本上就可以安装brew啦。最后我们再执行brew install libpng
,等到libpng
安装成功后,到项目中安装imagemin-pngquant
就可以安装上了。
代码实现压缩图片
根据需求我们肯定不希望他将图片压缩后放在文件夹里,而是需要在代码中直接获取到压缩后的内容,直接上传到七牛。那么就要用imagemin.buffer
,这个方法通过接收一个buffer
对象,经过压缩后再返回一个buffer
,我们只要用压缩后的buffer直接上传到七牛,思路就是这样,下面是代码实现:
// 获取buffer
export const getBufferFromFile = (filePath: string): Promise<Buffer> => {
return new Promise((resolve, reject) => {
fs.readFile(filePath, function (err: any, res: any) {
if (!err) {
resolve(res)
}
})
})
}
// 压缩图片,传入图片文件路径,通过getBufferFromFile方法转为buffer 后进行压缩
const imageGzip = async (loaclFile: string): Promise<any> => {
const bufferFile = await getBufferFromFile(loaclFile)
let res
try {
res = await imagemin.buffer(bufferFile, {
plugins: [
imageminJpegtran(),
imageminPngquant({
quality: [0.6, 0.8],
}),
],
})
} catch (err) {
console.log('error', err)
res = null
}
return res
}
这样我们就可以很容易的实现了,图片压缩,现在我们再改写一下上传到七牛:因为之前没有压缩我们可以直接传文件路径上传七牛,压缩后我们只有buffer了,需要上传buffer到七牛: gzipImage ? 'putStream' : 'putFile',如果我们是获取到buffer就使用formUploader.putStream,否则只需要formUploader.putFile上传
export const upImageToQiniu = async (
loaclFile: string,
cb: { (res: any): void; (arg0: any): void },
upConfig: QiNiuUpConfig
) => {
const config = new qiniu.conf.Config()
const formUploader = new qiniu.form_up.FormUploader(config)
const putExtra = new qiniu.form_up.PutExtra()
const token = getToken(upConfig.accessKey, upConfig.secretKey, upConfig.scope)
let gzipImage
if (upConfig.gzip) {
gzipImage = await imageGzip(loaclFile)
}
// 获取当前时间戳
var key = new Date().getTime()
// 上传调用方法
const uploadFnName = gzipImage ? 'putStream' : 'putFile'
// 上传内容
const uploadItem = gzipImage ? bufferToStream(gzipImage) : loaclFile
// 七牛上传
formUploader[uploadFnName](
token,
key,
uploadItem,
putExtra,
function (respErr: any, respBody: any, respInfo: any) {
if (respErr) {
throw respErr
}
if (respInfo.statusCode === 200) {
const url = upConfig.domain + '/' + respBody.key
cb(url)
}
}
)
}
现在我们可以实验一下效果:
在电脑中选择一张png图片:
用我们的插件上传后,打开链接看看:
图片压缩成功啦~~
三、解决遗留bug
在使用时发现了一个问题就是有时候编辑器会突然变卡,后来找到原因是在链接中有空格时会一直卡住,之后hover其他内容也都没有响应。于是就将hover的字符串空格去掉再执行后面的获取链接方法可以了:
// 当前行的文本内容
const currentLineText = document.lineAt(position).text.replace(/\s+/g, "")
四、结束
因为在hover预览图片时为防止有些图片过大加载慢,加了七牛的裁剪参数,所以可能其他类型的图片链接会不能预览,后面会慢慢解决哒^ ^。我已经将插件源码上传至github,欢迎大家点个start^ ^。如果对插件还有更好的想法也可以互相交流。 感谢阅读🙏
转载自:https://juejin.cn/post/6902624049940135950