Skip to content

Commit 6416891

Browse files
authored
Merge pull request #12 from skyNet2017/master
移植Android里的luban算法,最大程度省流量
2 parents 89a4fb8 + 638a3a5 commit 6416891

File tree

8 files changed

+191
-11
lines changed

8 files changed

+191
-11
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pids
1414
*.pid
1515
*.seed
1616
*.pid.lock
17+
.idea
1718

1819
# Directory for instrumented libs generated by jscoverage/JSCover
1920
lib-cov
@@ -103,4 +104,4 @@ dist
103104
# TernJS port file
104105
.tern-port
105106

106-
./dist
107+
./dist

README.md

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,33 @@
2020
compress 选择压缩工具
2121

2222
- [imagemin](https://github.com/imagemin/imagemin) 压缩过程不需要经过网络,速度快,但是图片会有损耗,默认选项
23+
2324
- [tinypng](https://tinypng.com/) 无损压缩,需要上传到 tinypng
24-
- [upng](https://github.com/photopea/UPNG.js) upng 无损压缩
25-
- none 不压缩
25+
26+
- [upng](https://github.com/photopea/UPNG.js) upng 无损压缩
27+
28+
- none 不压缩
29+
30+
- luban [imagemin](https://github.com/imagemin/imagemin) +luban算法,最大程度节省流量,效果如下:
2631

27-
nameType 是否重命名
32+
![image-20200922212916280](https://cdn.jsdelivr.net/gh/hss01248/picbed@master/pic/1600781356315.jpeg)
2833

34+
![image-20200922213104719](https://cdn.jsdelivr.net/gh/hss01248/picbed@master/pic/1600781464747.jpeg)
35+
36+
nameType 是否重命名
37+
2938
- timestamp 重命名成时间戳
3039
- none 不重名,默认选项
31-
40+
3241
key 可选
33-
42+
3443
-[developers](https://tinypng.com/developers) 中申请
3544
- 逗号`,`隔开,可使用多个 Key 叠加使用次数
3645

3746
### [PicGo-Gui](https://github.com/Molunerfinn/PicGo) 在线安装
3847

3948
- 打开详细窗口 > 插件设置 > 搜索 `compress` 即可安装,配置同上
4049
- 离线安装参考[这里](https://picgo.github.io/PicGo-Core-Doc/zh/dev-guide/deploy.html#gui%E6%8F%92%E4%BB%B6)
50+
51+
52+

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "picgo-plugin-compress",
3-
"version": "1.2.2",
3+
"version": "1.2.4",
44
"description": "Image compression plugin for PicGo",
55
"main": "dist/index.js",
66
"publishConfig": {
@@ -46,9 +46,11 @@
4646
"fs-extra": "^9.0.0",
4747
"image-size": "^0.8.3",
4848
"imagemin": "^7.0.1",
49+
"imagemin-jpegtran": "^7.0.0",
4950
"imagemin-mozjpeg": "^8.0.0",
5051
"imagemin-optipng": "^7.1.0",
5152
"imagemin-upng": "^2.0.2",
53+
"images": "^3.2.3",
5254
"request": "^2.88.2"
5355
}
5456
}

src/compress/luban.ts

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import imagemin from 'imagemin'
2+
import mozjpeg from 'imagemin-mozjpeg'
3+
import optipng from 'imagemin-optipng'
4+
import { CompressOptions, ImgInfo } from '../utils/interfaces'
5+
import { getImageBuffer } from '../utils/getImage'
6+
var images = require("images");
7+
8+
9+
10+
export function lubanCompress({ ctx, info }: CompressOptions): Promise<ImgInfo> {
11+
/*function getSample(info: ImgInfo) {
12+
return ['1x1']
13+
}*/
14+
15+
16+
function computeInSampleSize(srcWidth :number, srcHeight:number) {
17+
srcWidth = srcWidth % 2 == 1 ? srcWidth + 1 : srcWidth;
18+
srcHeight = srcHeight % 2 == 1 ? srcHeight + 1 : srcHeight;
19+
20+
var longSide = Math.max(srcWidth, srcHeight);
21+
var shortSide = Math.min(srcWidth, srcHeight);
22+
23+
var scale = ( shortSide / longSide);
24+
if (scale <= 1 && scale > 0.5625) {
25+
if (longSide < 1664) {
26+
return 1;
27+
} else if (longSide < 4990) {
28+
return 2;
29+
} else if (longSide > 4990 && longSide < 10240) {
30+
return 4;
31+
} else {
32+
return longSide / 1280 == 0 ? 1 : longSide / 1280;
33+
}
34+
} else if (scale <= 0.5625 && scale > 0.5) {
35+
return longSide / 1280 == 0 ? 1 : longSide / 1280;
36+
} else {
37+
return Math.ceil(longSide / (1280.0 / scale));
38+
}
39+
}
40+
41+
function isJpg(buffer: Buffer) {
42+
return buffer[0] === 255 &&
43+
buffer[1] === 216 &&
44+
buffer[2] === 255
45+
}
46+
47+
return getImageBuffer(ctx, info.url)
48+
.then((buffer)=>{
49+
ctx.log.warn('原始文件大小:'+Math.round(buffer.length/1024)+"k")
50+
if(isJpg(buffer)){
51+
ctx.log.warn('本身就是jpg,不用转换:'+info.url)
52+
return buffer
53+
}
54+
ctx.log.warn('luban 格式转换为jpg:'+info.url)
55+
return images(buffer).encode("jpg")//, {operation:90}
56+
})
57+
/*.then((buffer)=>{
58+
var image2 = images(buffer)
59+
ctx.log.warn('图片尺寸:'+image2.width()+"x"+image2.height())
60+
//todo 关键在于获取图片本身的宽高
61+
var samplesize = computeInSampleSize(image2.width(),image2.height())
62+
if(samplesize <=1){
63+
return buffer
64+
}
65+
var size2 = Math.round(buffer.length/1024)
66+
if(size2 <150){
67+
//150k以下,不压缩
68+
return buffer
69+
}
70+
var longsize = image2.width() > image2.height() ? image2.width() :image2.height()
71+
//长边大于2500,且文件大小小于1024k,就不压缩
72+
if(size2 < 1024 && longsize> 2500){
73+
return buffer
74+
}
75+
var conpressWidth = image2.width()/samplesize
76+
ctx.log.warn('转换成jpg后文件大小:'+Math.round(buffer.length/1024)+"k")
77+
ctx.log.warn('准备用luban算法压缩:宽度变化:'+image2.width()+"-->"+conpressWidth)
78+
79+
return image2.resize(conpressWidth).encode("jpg")//, {operation:90}
80+
})*/
81+
.then((buffer) => {
82+
ctx.log.warn('文件大小:'+Math.round(buffer.length/1024)+"k")
83+
84+
var image2 = images(buffer)
85+
ctx.log.warn('图片尺寸:'+image2.width()+"x"+image2.height())
86+
//todo 关键在于获取图片本身的宽高
87+
var sample = Math.round(computeInSampleSize(image2.width(),image2.height()))
88+
var filesize = Math.round(buffer.length/1024)
89+
var longsize = image2.width() > image2.height() ? image2.width() :image2.height()
90+
var sampleSize = ['1x1'];
91+
if(filesize > 100 && sample >1){
92+
if(longsize >3000 && filesize< 700){
93+
94+
}else {
95+
sampleSize = [sample+'x'+sample]
96+
}
97+
98+
}
99+
ctx.log.warn('sampleSize:'+sampleSize[0])
100+
101+
return imagemin.buffer(buffer, {
102+
plugins: [mozjpeg({ quality: 75,sample:sampleSize})],//, optipng({ optimizationLevel: 5 })//, sample:sampleSize
103+
})
104+
})
105+
.then((buffer) => {
106+
ctx.log.warn('最后mozjpeg compress in success,最终文件大小:'+Math.round(buffer.length/1024)+"k")
107+
return {
108+
...info,
109+
buffer,
110+
}
111+
})
112+
}

src/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ export enum CompressType {
1111
tinypng = 'tinypng',
1212
imagemin = 'imagemin',
1313
upng = 'upng',
14+
luban = 'luban',
1415
none = 'none',
1516
}

src/index.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import { imageminCompress } from './compress/imagemin'
99
import { NameType, CompressType } from './config'
1010
import { reName } from './utils/reName'
1111
import { upngCompress } from './compress/upng'
12+
import { lubanCompress } from './compress/luban'
1213

14+
//npm install /Users/hss/github/picgo-plugin-compress
1315
function handle(ctx: PicGo) {
1416
const config = ctx.getConfig('transformer.compress') || ctx.getConfig('picgo-plugin-compress')
1517
const compress = config?.compress
@@ -26,18 +28,21 @@ function handle(ctx: PicGo) {
2628
})
2729
.map((info) => {
2830
const options = { ctx, info }
31+
ctx.log.warn("compress type:"+compress)
2932
return Promise.resolve()
3033
.then(() => {
3134
switch (compress) {
3235
case CompressType.tinypng:
3336
return key ? tinypngKeyCompress({ ...options, key }) : tinypngCompress(options)
3437
case CompressType.imagemin:
3538
return imageminCompress(options)
39+
case CompressType.luban:
40+
return lubanCompress(options)
3641
case CompressType.upng:
3742
return upngCompress(options)
3843
case CompressType.none:
3944
default:
40-
return defaultCompress(options)
45+
return lubanCompress(options)
4146
}
4247
})
4348
.then((info) => {
@@ -78,7 +83,7 @@ module.exports = function (ctx: PicGo): any {
7883
type: 'list',
7984
message: '选择压缩库',
8085
choices: Object.keys(CompressType),
81-
default: config.compress || CompressType.imagemin,
86+
default: config.compress || CompressType.luban,
8287
required: true,
8388
},
8489
{

tsconfig.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"es2017",
1818
"es2015",
1919
"es6"
20-
],
20+
]
2121
},
2222
"include": [
2323
"./src/**/*",
@@ -26,4 +26,4 @@
2626
"exclude": [
2727
"node_modules"
2828
]
29-
}
29+
}

yarn.lock

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2142,6 +2142,15 @@ image-size@^0.8.3:
21422142
dependencies:
21432143
queue "6.0.1"
21442144

2145+
imagemin-jpegtran@^7.0.0:
2146+
version "7.0.0"
2147+
resolved "https://registry.yarnpkg.com/imagemin-jpegtran/-/imagemin-jpegtran-7.0.0.tgz#7728f84876362d489b9a1656e0cc8e2009406e6f"
2148+
integrity sha512-MJoyTCW8YjMJf56NorFE41SR/WkaGA3IYk4JgvMlRwguJEEd3PnP9UxA8Y2UWjquz8d+On3Ds/03ZfiiLS8xTQ==
2149+
dependencies:
2150+
exec-buffer "^3.0.0"
2151+
is-jpg "^2.0.0"
2152+
jpegtran-bin "^5.0.0"
2153+
21452154
imagemin-mozjpeg@^8.0.0:
21462155
version "8.0.0"
21472156
resolved "https://registry.npm.taobao.org/imagemin-mozjpeg/download/imagemin-mozjpeg-8.0.0.tgz#d2ca4e8c982c7c6eda55069af89dee4c1cebcdfd"
@@ -2496,6 +2505,25 @@ isurl@^1.0.0-alpha5:
24962505
has-to-string-tag-x "^1.2.0"
24972506
is-object "^1.0.1"
24982507

2508+
jpeg-js@^0.1.2:
2509+
version "0.1.2"
2510+
resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.1.2.tgz#135b992c0575c985cfa0f494a3227ed238583ece"
2511+
integrity sha1-E1uZLAV1yYXPoPSUoyJ+0jhYPs4=
2512+
2513+
jpeg-js@^0.4.2:
2514+
version "0.4.2"
2515+
resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.2.tgz#8b345b1ae4abde64c2da2fe67ea216a114ac279d"
2516+
integrity sha512-+az2gi/hvex7eLTMTlbRLOhH6P6WFdk2ITI8HJsaH2VqYO0I594zXSYEP+tf4FW+8Cy68ScDXoAsQdyQanv3sw==
2517+
2518+
jpegtran-bin@^5.0.0:
2519+
version "5.0.2"
2520+
resolved "https://registry.yarnpkg.com/jpegtran-bin/-/jpegtran-bin-5.0.2.tgz#5870fd7e68317bd203a1c94572bd06ae7732cac3"
2521+
integrity sha512-4FSmgIcr8d5+V6T1+dHbPZjaFH0ogVyP4UVsE+zri7S9YLO4qAT2our4IN3sW3STVgNTbqPermdIgt2XuAJ4EA==
2522+
dependencies:
2523+
bin-build "^3.0.0"
2524+
bin-wrapper "^4.0.0"
2525+
logalot "^2.0.0"
2526+
24992527
js-tokens@^4.0.0:
25002528
version "4.0.0"
25012529
resolved "https://registry.npm.taobao.org/js-tokens/download/js-tokens-4.0.0.tgz?cache=0&sync_timestamp=1586796260005&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjs-tokens%2Fdownload%2Fjs-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
@@ -3304,6 +3332,25 @@ pinkie@^2.0.0:
33043332
resolved "https://registry.npm.taobao.org/pinkie/download/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
33053333
integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
33063334

3335+
png-js@^0.1.1:
3336+
version "0.1.1"
3337+
resolved "https://registry.yarnpkg.com/png-js/-/png-js-0.1.1.tgz#1cc7c212303acabe74263ec3ac78009580242d93"
3338+
integrity sha1-HMfCEjA6yr50Jj7DrHgAlYAkLZM=
3339+
3340+
png-js@^1.0.0:
3341+
version "1.0.0"
3342+
resolved "https://registry.yarnpkg.com/png-js/-/png-js-1.0.0.tgz#e5484f1e8156996e383aceebb3789fd75df1874d"
3343+
integrity sha512-k+YsbhpA9e+EFfKjTCH3VW6aoKlyNYI6NYdTfDL4CIvFnvsuO84ttonmZE7rc+v23SLTH8XX+5w/Ak9v0xGY4g==
3344+
3345+
png-to-jpeg@^1.0.1:
3346+
version "1.0.1"
3347+
resolved "https://registry.yarnpkg.com/png-to-jpeg/-/png-to-jpeg-1.0.1.tgz#14362c6aaaec5ea6b52fa3504f5ecc760b4e7424"
3348+
integrity sha1-FDYsaqrsXqa1L6NQT17MdgtOdCQ=
3349+
dependencies:
3350+
jpeg-js "^0.1.2"
3351+
pify "^2.3.0"
3352+
png-js "^0.1.1"
3353+
33073354
posix-character-classes@^0.1.0:
33083355
version "0.1.1"
33093356
resolved "https://registry.npm.taobao.org/posix-character-classes/download/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"

0 commit comments

Comments
 (0)