Commit a9eaa71e authored by rockyl's avatar rockyl

改为tinypng压缩

parent a8c99525
/** /**
* Created by rockyl on 2020-02-13. * Created by rockyl on 2020/11/30.
*/ */
export declare function compressBuffer(buffer: any): Promise<unknown>; /// <reference types="node" />
export declare function compressFile(file: any): Promise<unknown>; /**
* 压缩图片
* @param {Buffer|string} bufferOrFile
* @return Promise<Buffer>
*/
export declare function compress(bufferOrFile: Buffer | string): Promise<unknown>;
"use strict"; "use strict";
/** /**
* Created by rockyl on 2020-02-13. * Created by rockyl on 2020/11/30.
*/ */
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.compressFile = exports.compressBuffer = void 0; exports.compress = void 0;
const FormData = require('form-data');
const fs = require('fs-extra'); const fs = require('fs-extra');
const isPng = require("is-png"); const https = require('https');
const isJpg = require("is-jpg"); const { URL } = require('url');
const tinifyUrl = 'http://tinify.duiba.com.cn/tinify'; const options = {
async function compressBuffer(buffer) { method: 'POST',
hostname: 'tinypng.com',
path: '/web/shrink',
headers: {
rejectUnauthorized: false,
'Postman-Token': Date.now(),
'Cache-Control': 'no-cache',
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'
}
};
/**
* 压缩图片
* @param {Buffer|string} bufferOrFile
* @return Promise<Buffer>
*/
async function compress(bufferOrFile) {
let buffer = bufferOrFile;
if (typeof bufferOrFile === 'string') {
buffer = await fs.readFile(bufferOrFile);
}
const result = await uploadImg(buffer);
return result;
}
exports.compress = compress;
function uploadImg(buffer) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (buffer && buffer.length > 0) { options.headers['X-Forwarded-For'] = Array.from(Array(4)).map(() => Math.floor(Math.random() * 255)).join('.');
let extname = isPng(buffer) ? 'png' : 'jpeg'; var req = https.request(options, function (res) {
let form = new FormData(); res.on('data', buf => {
form.append('file', buffer, { let obj = JSON.parse(buf.toString());
filename: 'image.' + extname, if (obj.error) {
contentType: 'image/' + extname, console.log(`[压缩失败:${obj.message}`);
});
form.submit(tinifyUrl, function (err, res) {
if (err) {
reject(err);
} }
else { else {
res.resume(); resolve(downloadImg(obj));
let resBuffer = Buffer.alloc(0);
res.on('data', (d) => {
resBuffer = Buffer.concat([resBuffer, d], resBuffer.length + d.length);
});
res.on('end', () => {
if (resBuffer.length > 256 || isPng(resBuffer) || isJpg(resBuffer)) {
resolve(resBuffer);
}
else {
let str = resBuffer.toString();
let json;
try {
json = JSON.parse(str);
}
catch (e) {
console.log(e);
}
reject(json.msg);
}
});
res.on('abort', () => {
reject('abort');
});
} }
}); });
} });
else { req.write(buffer);
reject('empty buffer'); req.on('error', e => {
} reject(e);
});
req.end();
}); });
} }
exports.compressBuffer = compressBuffer; function downloadImg(obj) {
async function compressFile(file) { return new Promise((resolve, reject) => {
let buffer = await fs.readFile(file); let options = new URL(obj.output.url);
return compressBuffer(buffer); let req = https.request(options, res => {
let body = Buffer.alloc(0);
res.on('data', function (data) {
body = Buffer.concat([body, data], body.length + data.length);
});
res.on('end', function () {
resolve(body);
});
});
req.on('error', e => {
reject(e);
});
req.end();
});
} }
exports.compressFile = compressFile;
//# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map
\ No newline at end of file
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;AACtC,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AAChC,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEhC,MAAM,SAAS,GAAG,mCAAmC,CAAC;AAE/C,KAAK,UAAU,cAAc,CAAC,MAAM;IAC1C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACtC,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;YAChC,IAAI,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;YAC7C,IAAI,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC1B,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE;gBAC3B,QAAQ,EAAE,QAAQ,GAAG,OAAO;gBAC5B,WAAW,EAAE,QAAQ,GAAG,OAAO;aAC/B,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,UAAU,GAAG,EAAE,GAAG;gBACxC,IAAI,GAAG,EAAE;oBACR,MAAM,CAAC,GAAG,CAAC,CAAC;iBACZ;qBAAM;oBACN,GAAG,CAAC,MAAM,EAAE,CAAC;oBACb,IAAI,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;oBAChC,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE;wBACpB,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;oBACxE,CAAC,CAAC,CAAC;oBACH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;wBAClB,IAAG,SAAS,CAAC,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,EAAC;4BACjE,OAAO,CAAC,SAAS,CAAC,CAAC;yBACnB;6BAAM;4BACN,IAAI,GAAG,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC;4BAC/B,IAAI,IAAI,CAAC;4BACT,IAAI;gCACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;6BACvB;4BAAA,OAAO,CAAC,EAAC;gCACT,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;6BACf;4BACD,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;yBACjB;oBACF,CAAC,CAAC,CAAC;oBACH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;wBACpB,MAAM,CAAC,OAAO,CAAC,CAAA;oBAChB,CAAC,CAAC,CAAC;iBACH;YACF,CAAC,CAAC,CAAC;SACH;aAAM;YACN,MAAM,CAAC,cAAc,CAAC,CAAA;SACtB;IACF,CAAC,CAAC,CAAA;AACH,CAAC;AA1CD,wCA0CC;AAEM,KAAK,UAAU,YAAY,CAAC,IAAI;IACtC,IAAI,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACrC,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC;AAHD,oCAGC"} {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
\ No newline at end of file \ No newline at end of file
{ {
"name": "tiny-image", "name": "tiny-image",
"version": "1.0.1", "version": "1.0.2",
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"form-data": "^3.0.0", "fs-extra": "^8.1.0"
"fs-extra": "^8.1.0",
"node-fetch": "^2.6.0",
"is-jpg": "^2.0.0",
"is-png": "^2.0.0"
}, },
"scripts": { "scripts": {
"dev": "tsc -w", "dev": "tsc -w",
......
/** /**
* Created by rockyl on 2020-02-13. * Created by rockyl on 2020/11/30.
*/ */
const FormData = require('form-data');
const fs = require('fs-extra'); const fs = require('fs-extra');
const isPng = require("is-png"); const https = require('https');
const isJpg = require("is-jpg"); const {URL} = require('url');
const tinifyUrl = 'http://tinify.duiba.com.cn/tinify'; const options = {
method: 'POST',
hostname: 'tinypng.com',
path: '/web/shrink',
headers: {
rejectUnauthorized: false,
'Postman-Token': Date.now(),
'Cache-Control': 'no-cache',
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent':
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'
}
};
export async function compressBuffer(buffer) { /**
* 压缩图片
* @param {Buffer|string} bufferOrFile
* @return Promise<Buffer>
*/
export async function compress(bufferOrFile: Buffer | string) {
let buffer = bufferOrFile;
if (typeof bufferOrFile === 'string') {
buffer = await fs.readFile(bufferOrFile);
}
const result = await uploadImg(buffer);
return result;
}
function uploadImg(buffer) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (buffer && buffer.length > 0) { options.headers['X-Forwarded-For'] = Array.from(Array(4)).map(() => Math.floor(Math.random() * 255)).join('.')
let extname = isPng(buffer) ? 'png' : 'jpeg';
let form = new FormData();
form.append('file', buffer, {
filename: 'image.' + extname,
contentType: 'image/' + extname,
});
form.submit(tinifyUrl, function (err, res) { var req = https.request(options, function (res) {
if (err) { res.on('data', buf => {
reject(err); let obj = JSON.parse(buf.toString());
if (obj.error) {
console.log(`[压缩失败:${obj.message}`);
} else { } else {
res.resume(); resolve(downloadImg(obj));
let resBuffer = Buffer.alloc(0);
res.on('data', (d) => {
resBuffer = Buffer.concat([resBuffer, d], resBuffer.length + d.length);
});
res.on('end', () => {
if(resBuffer.length > 256 || isPng(resBuffer) || isJpg(resBuffer)){
resolve(resBuffer);
} else {
let str = resBuffer.toString();
let json;
try {
json = JSON.parse(str);
}catch (e){
console.log(e);
}
reject(json.msg);
}
});
res.on('abort', () => {
reject('abort')
});
} }
}); });
} else { });
reject('empty buffer')
} req.write(buffer);
req.on('error', e => {
reject(e);
});
req.end();
}) })
} }
export async function compressFile(file) { function downloadImg(obj) {
let buffer = await fs.readFile(file); return new Promise((resolve, reject) => {
return compressBuffer(buffer); let options = new URL(obj.output.url);
let req = https.request(options, res => {
let body = Buffer.alloc(0);
res.on('data', function (data) {
body = Buffer.concat([body, data], body.length + data.length);
});
res.on('end', function () {
resolve(body);
});
});
req.on('error', e => {
reject(e);
});
req.end();
})
} }
...@@ -6,7 +6,10 @@ const {compressFile} = require('.'); ...@@ -6,7 +6,10 @@ const {compressFile} = require('.');
(async function(){ (async function(){
console.time('cost'); console.time('cost');
let buffer = await compressFile('/Users/rockyl/Pictures/一个亿.png'); //await compressFile('/Users/rockyl/Downloads/购买弹窗.png');
//await compressFile('/Users/rockyl/Downloads/38575da45f7bfbc49de26bafe6f40f2363926eee.png');
//await compressFile('/Users/rockyl/Downloads/已领完.png');
//await compressFile('/Users/rockyl/Downloads/最新集合页.jpg');
await compressFile('/Users/rockyl/Downloads/长图.jpg');
console.timeEnd('cost'); console.timeEnd('cost');
console.log(buffer.length);
})(); })();
...@@ -14,32 +14,6 @@ ...@@ -14,32 +14,6 @@
resolved "http://npm.dui88.com:80/@types%2fnode/-/node-14.14.5.tgz#e92d3b8f76583efa26c1a63a21c9d3c1143daa29" resolved "http://npm.dui88.com:80/@types%2fnode/-/node-14.14.5.tgz#e92d3b8f76583efa26c1a63a21c9d3c1143daa29"
integrity sha1-6S07j3ZYPvomwaY6IcnTwRQ9qik= integrity sha1-6S07j3ZYPvomwaY6IcnTwRQ9qik=
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.npm.taobao.org/asynckit/download/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
combined-stream@^1.0.8:
version "1.0.8"
resolved "https://registry.npm.taobao.org/combined-stream/download/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
integrity sha1-w9RaizT9cwYxoRCoolIGgrMdWn8=
dependencies:
delayed-stream "~1.0.0"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.npm.taobao.org/delayed-stream/download/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
form-data@^3.0.0:
version "3.0.0"
resolved "https://registry.npm.taobao.org/form-data/download/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682"
integrity sha1-MbfjnIXxNVtxOe4MZHzw3n+DxoI=
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.8"
mime-types "^2.1.12"
fs-extra@^8.1.0: fs-extra@^8.1.0:
version "8.1.0" version "8.1.0"
resolved "https://registry.npm.taobao.org/fs-extra/download/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" resolved "https://registry.npm.taobao.org/fs-extra/download/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
...@@ -54,16 +28,6 @@ graceful-fs@^4.1.6, graceful-fs@^4.2.0: ...@@ -54,16 +28,6 @@ graceful-fs@^4.1.6, graceful-fs@^4.2.0:
resolved "https://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" resolved "https://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423"
integrity sha1-ShL/G2A3bvCYYsIJPt2Qgyi+hCM= integrity sha1-ShL/G2A3bvCYYsIJPt2Qgyi+hCM=
is-jpg@^2.0.0:
version "2.0.0"
resolved "http://npm.dui88.com:80/is-jpg/-/is-jpg-2.0.0.tgz#2e1997fa6e9166eaac0242daae443403e4ef1d97"
integrity sha1-LhmX+m6RZuqsAkLarkQ0A+TvHZc=
is-png@^2.0.0:
version "2.0.0"
resolved "http://npm.dui88.com:80/is-png/-/is-png-2.0.0.tgz#ee8cbc9e9b050425cedeeb4a6fb74a649b0a4a8d"
integrity sha1-7oy8npsFBCXO3utKb7dKZJsKSo0=
jsonfile@^4.0.0: jsonfile@^4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.npm.taobao.org/jsonfile/download/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" resolved "https://registry.npm.taobao.org/jsonfile/download/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
...@@ -71,23 +35,6 @@ jsonfile@^4.0.0: ...@@ -71,23 +35,6 @@ jsonfile@^4.0.0:
optionalDependencies: optionalDependencies:
graceful-fs "^4.1.6" graceful-fs "^4.1.6"
mime-db@1.43.0:
version "1.43.0"
resolved "https://registry.npm.taobao.org/mime-db/download/mime-db-1.43.0.tgz?cache=0&sync_timestamp=1578281193492&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime-db%2Fdownload%2Fmime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58"
integrity sha1-ChLgUCZQ5HPXNVNQUOfI9OtPrlg=
mime-types@^2.1.12:
version "2.1.26"
resolved "https://registry.npm.taobao.org/mime-types/download/mime-types-2.1.26.tgz?cache=0&sync_timestamp=1578282566609&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime-types%2Fdownload%2Fmime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06"
integrity sha1-nJIfwJt+FJpl39wNpNIJlyALCgY=
dependencies:
mime-db "1.43.0"
node-fetch@^2.6.0:
version "2.6.0"
resolved "https://registry.npm.taobao.org/node-fetch/download/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
integrity sha1-5jNFY4bUqlWGP2dqerDaqP3ssP0=
universalify@^0.1.0: universalify@^0.1.0:
version "0.1.2" version "0.1.2"
resolved "https://registry.npm.taobao.org/universalify/download/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" resolved "https://registry.npm.taobao.org/universalify/download/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment