Gulp图片压缩

标签: Gulp 分类: Nodejs 创建时间:2020-12-17 05:26:34 更新时间:2023-10-20 11:23:25

1.smushit

我尝试了smushit

1
2
3
4
5
6
7
// 使用smushit压缩图片
gulp.task('minify-png', function () {
return gulp.src('./source/_posts/**/*.jpg')
.pipe(smushit())
.pipe(gulp.dest('./dist'));
});

问题

(1) 使用smushit进行图片压缩的时候,出现了403错误

1
2
3
4
5
6
7
8
// 压缩图片
gulp.task('smushit', function () {
return gulp.src('./public/**')
.pipe(smushit({
verbose: true
}))
.pipe(gulp.dest('smushit-dist'));
});

后来我换成了这个

1
2
3
4
5
gulp.task('smushit', function () {
return gulp.src('./public/**/*.{jpg,png}')
.pipe(smushit())
.pipe(gulp.dest('dist'));
});

换成这个之后,还是出现了问题,就是会出现总是卡住某一个图片上。

参考文章:
1.heldr/gulp-smushit

(2) 2.Did you forget to signal async completion?
出现了: Did you forget to signal async completion?错误

2.gulp-imagemin

smushit压缩效果不是很好,而且有时候总是会出现无法压缩的情况。所以我换成了gulp-imagemin加上imagemin-pngquant、imagemin-jpegtran插件。

1
2
3
4
5
6
7
8
9
10
11
12
const gulp = require('gulp');
const imagemin = require('gulp-imagemin');
const imageminPngquant = require('imagemin-pngquant');
const imageminJpegtran = require('imagemin-jpegtran');

gulp.task('default', () =>
gulp.src('src/images/*')
.pipe(imagemin({
use:[imageminPngquant(),imageminJpegtran()]
}))
.pipe(gulp.dest('dist/images'))
);
参考文章:
1.gulp压缩图片进阶 (第一个工具就是gulp-imagemin,还有一个工具就是gulp-smushit,这个对于png的压缩率比较高,这里的smushit代码好像有些问题,需要使用下面的内容进行调整)
2.如何使用Gulp裁剪和压缩图片 (这里介绍了Gulp-Imagemin这个插件)
3.gulp压缩图片组件对比,gulp-imagemin,gulp-tinypng-nokey和gulp-smushit使用方式以及图片优化 (各种压缩情况的对比,还介绍了pngquant深度压缩png图片的imagemin插件)
4.gulp的基本使用 (这里也有说gulp-smushit的压缩率较高)

3.gulp-imagemin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var imagemin = require('gulp-imagemin');

// 使用imagemin压缩图片
gulp.task('minify-img', function () {
return gulp.src('./source/**/**/*.{jpg,png}')
.pipe(imagemin({
progressive: true, //类型:Boolean 默认:false 无损压缩jpg图片
use: [pngquant(),jpegtran()], //使用pngquant深度压缩png图片的imagemin插件
plugins: [
pngquant(),
jpegtran()
]
}))
.pipe(gulp.dest('./source'));
});

压缩时出现乱码
就像下面的图片所示,使用gulp-imagemin进行图片压缩的时候,出现了乱码。

我觉得可能是这张图片有问题,所以最后把这张图片删除了。

4.改变图像分辨率

参考文章:
1.利用gulp-imagemin压缩jpg格式图片变化不大
2.gulp图片压缩 (这里提到了一个gulp-image-resize),可以对图片的大小进行重采样)
3.gulp - gulp-image-resize生成多个输出大小
4.图片压缩

5.压缩工具

除了使用gulp进行压缩,是不是还有其他的压缩工具呢,反正我不是实时压缩,只需要压缩一次就够了。在谷歌上搜,图片压缩工具,有很多,比如压缩图iLoveIMGOnline Image Tool,图好快,tinypng我尝试了几个,其实压缩率都挺高的,使用gulp进行压缩,也没有50%的压缩率,但是使用网站上的可以达到50%的压缩率,这样看起来还是可观的。但是既然都是网站了,肯定有很多的限制,第一个就是大多不支持批量压缩,支持的化,也是支持20几张,还有就是看样子是不能压缩文件夹中的图片了,让我一张一张的复制,然后进行压缩,压缩之后再保存回去,还是有些麻烦的。还有完全免费的RECOMPRESSOR

后来在检查tinypng的时候,其实还是有些收获的,就是他提供了各种各样的工具,包括nodejs版本的。Developer API 根据售价显示,每个月的前五百张图片是免费的,接下来的9500张,是0.009美元一张,折合人民币五毛钱一张。超过一万张,每张0.002美元。其实还是可以的,先使用五百张免费的,然后再注册另外一个账号,继续使用啊,多少个手机号,就有多少个500了,简直为我的积值深深的折服了。

参考文章:
1.2019 年最好用的免费在线图片压缩工具,就它了! (免费工具Recompressor)
2.图片无损压缩工具都有哪些? (这个知乎上的答案非常的有参考价值,大家纷纷介绍了各种压缩工具,有自己写的,有在线的,有免费的,有收费的,有桌面的,有在线的,有好用的,有不好用的,总之有很多,如何找到适合自己的,好用的,还是需要自己亲自动手去尝试一下,才能找到适合自己的。我想起了一句话,就是没有最好的方案,只有最适合自己的方案。因为每个人的情况不尽相同,时间点也不一样,我主要用来压缩hexo图片,所以最好能有借助于gulp等工具执行自动压缩的步骤,也有人时间点不一样,比如我现在时间点主要是2020年12月22日,现在tinypng还是有部分图片可以免费的,说不定以后就不免费了呢?)

6.Tinfiy

既然有免费的500张,那我只能先薅羊毛了,其实官网API Reference 对于如何使用,已经说的很明确了。如果仔细的搜,还有很多的gulp插件可以使用:

  • gulp-tinypng-nokey(使用模拟上传下载的方式,图片官网500M限制的npm)
  • gulp-tinypng-compress(使用文件的md5进行比较,避免同一文件多次上传)
  • gulp-tinypng-plugin(这个插件增加了缓存的功能,并且支持多个key)
  • gulp-tinypng-extended (在gulp-tinypng-compress基础上,增加了两个可选的元数据参数,增加了空图片和错误图片的跳过,以及网关错误时自动重试)
  • gulp-tinypng-free (这个插件结合了gulp-tinypng-compress和gulp-tinypng-nokey,既能进行无限上传,又能写入sign签名信息)
  • gulp-imageisux (智图,据说是腾讯的某一个团队创建的,可以将图片转为webp格式,大大缩小图片大小的同时还保留了原有图片的质量。WebP是Google在2010年发布的一种新型图片格式,支持无损和有损压缩。在无损压缩方面,同质量的WebP图片比PNG的体积小26%,而在有损压缩方面,同质量的WebP图片比JPEG小25-34%。WebP在不降低图片质量的同时,减少了约三分之一的体积)

这样看起来,其实最好的选择还是gulp-tinypng-free,但是这个还是有缺点,就是不支持gulp-tinypng-extended的功能,比如错误重传,空图片以及错误图片跳过等。

(1) 安装

1
npm install --save tinfy

(2) 使用

1
2
const source = tinify.fromFile("unoptimized.jpg");
source.toFile("optimized.jpg");
参考文章:
1.gulp-tinypng-compress (这是一个tinypng的gulp的封装,如果不想自己写的话,我觉得可以尝试一下这个方法)
2.Third-Party Solutions (这里第三方的解决方法,其实也有关于gulp的,除此之外,还有桌面的,Idea插件的,python的,等等,很多。gulp的,其实就是gulp-tinypng)
3.一键改图

7.gulp-tinypng-free

使用gulp-tinypng-free,可以看到压缩效果还是不错的。显示了压缩率和sign.json文件。使用起来也非常的简单。

注意
但是源码是有问题的,无论你源文件有没有改变,它都会去请求tinypng网站,然后进行压缩请求,没有跳过已经压缩的文件的操作,需要修改源码的部分内容,将源码的191存储压缩后的文件的md5,改为存储压缩前的文件的md5,这样就好了。当然,这也是当原始文件,以及压缩文件不在同一个目录下当时候,需要这么修改,如果两者在同一个目录下,就不一定要这么改了,所以在gulp-tinypng-compress和gulp-tinypng-extended这个插件中添加了一个same

1
2
3
4
5
6
7
8
9
10
11
//将源码的191行
if (data) {
tinyFile.contents = data;
hasher.update(file, hasher.calc(tinyFile));
}

// 改为
if (data) {
tinyFile.contents = data;
hasher.update(file, hasher.calc(file));
}

(1) Too many files uploaded at once

还有一些其他的问题,比如下面这个,还有不支持并行等内容,所以压缩多个张图片,可能需要很多次的尝试才可以。我的压缩了2000多张图片,就基本上用了十几次执行。

解决方式就是添加X-Forwarded-For,在源码的101行,添加:’X-Forwarded-For’:getRandomIP(),其中getRandomIP():

1
2
3
4
// 生成随机IP, 赋值给 X-Forwarded-For
function getRandomIP() {
return Array.from(Array(4)).map(() => parseInt(Math.random() * 255)).join('.')
}
参考文章:
1.原来 TinyPNG 可以这样玩! (使用X-Forwarded-For,当然也就是下面的原理性文章了)
2.super-tinypng (这个也是使用X-Forwarded-For 头绕过该20张的限制)
3.nodejs 全自动使用 Tinypng (免费版,无需任何配置)压缩图片 (这是另外的参考)
4.gulp-tinypng-nokey [error]: xxx Too many files uploaded at once
5.WebP使用方案 (webp一种新的图片压缩方案)

(2) This endpoint does not exist

2023年03月27日,这个代码突然无法使用了,出现了上面这个问题,我看了看,请求的地址 https://tinypng.com/web/shrink,后来我看了官网的上传图片的接口,改成了 https://tinypng.com/backend/opt/shrink,只需要把 request 的 url 改成这个就好了。

(3) Client network socket disconnected before secure TLS connection was established

改变上传图片地址之后,又出现了新的问题。

8.gulp-image-resize

使用gulp-image-resize进行图片尺寸的修改,需要安装ImageMagick或者是GraphicsMagick。

1
2
3
4
5
6
7
8
9
10
11
12
/**修改图片的大小 */
var imageResize = require('gulp-image-resize');

// 修改图片的大小
gulp.task('resize-img', function () {
return gulp.src('./source/**/**/*.{jpg,png}')
.pipe(imageResize({
imageMagick:true,
width : 800,
}))
.pipe(gulp.dest('./dist'));
});

(1) 刚开始我安装了ImageMagick,运行了magick logo: logo.gif,也没有报错。

但是运行gulp-image-resize,还是提示:Error: Could not execute GraphicsMagick/ImageMagick: identify “-ping” “-format” “%wx%h” “-“ this most likely means the gm/convert binaries can’t be found

(2) 我以为是要同时安装GraphicsMagick,于是我就安装了GraphicsMagick,但是还是不行。运行安装提示之后的内容,好像也不行,出现了 “Get-Member : 找不到接受实际参数“logo:”的位置形式参数。” 的错误。

You have now installed GraphicsMagick. To test the installation select "Command Prompt" from the Windows Start menu. Within the window that appears type:
gm convert logo: logo.jpg
gm convert logo.jpg win:
and the GraphicsMagick logo should be displayed in a window.
For your convenience, the full content of the GraphicsMagick web site has been installed on your computer. This is available from the Windows start menu via "GraphicsMagick 1.X" -> "GraphicsMagick Web Pages".
1
2
gm convert logo: logo.jpg
gm convert logo.jpg win:

解决方法,其实就是换一个命令,使用系统自带的cmd,而不是什么Powershell等,最后就可以看到logo了。

Install legacy utils,这里提到了一个在安装的时候出现的选项,这个安装的版本是在ImageMagick-7.0.10-52-Q16-x86-dll.exe而不是ImageMagick-7.0.10-52-Q16-x86-static.exe这个版本中才有的。

最后我还是没有运行成功gulp-image-resize,只能放弃了。
不知道是什么原因,第二天,我竟然执行成功了。但是你要问我如何成功的,我其实也不知道,因为我决定放弃之后,就没有在尝试了,只是今天早上打开电脑,在一个临时目录下使用命令行工具,执行了一下:convert -resize 200x200 err_1.png err_1.jpg,为了检验一下改变图片的分辨率之后,是否会保留原有的清晰度,但是失败了,经过重采样之后的图片变得模糊不清了。

参考文章:
1.安装 GraphicsMagick 和 ImageMagick (这里提示,一定要重启电脑。显然,这是不对的,即使我重启了电脑也无济于事)
2.GraphicsMagick笔记-基本使用 (这篇文章将了常用的graphicsmagick使用方法)
3.图片工具GraphicsMagick的安装配置与基本使用
4.关于ImageMagick出现无效参数(invalid parameter)的解决方法 (无效参数的问题)
5.Error: Could not execute GraphicsMagick/ImageMagick: gm “convert” “/GitHub-Trending/public/debug-politics.svg” “-resize” “96x” “/GitHub-Trending/public/debug-politics.png” this most likely means the gm/convert binaries can’t be found #5
6.The gm/convert binaries can’t be found (这里有很多的讨论和方法,有人说可以,有人说不可以,我尝试了多个办法,都没有实验成功。)

图片缩放

我尝试使用ImageMagick对图片进行缩放处理,安装完ImageMagick之后,一定要在Cmd下运行命令,不要在PowerShell下运行转换命令,否则就会有各种错误产生。

1
convert -resize 800x500 err_1.png err_1.jpg

经过实际的测试,图片经过重采样之后,在使用tinypng进行压缩,反而增大了文件的大小,很不值当的,而且重采样之后的文件,分辨率会出现问题。所以还是老老实实的使用tinypng进行压缩就好了。

小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。