-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathimage_processor.js
89 lines (75 loc) · 2.73 KB
/
image_processor.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
"use strict";
let gm = require("gm");
let os = require("os");
let fs = require("fs");
let promisify = require("es6-promisify");
let imageSize = promisify(require("image-size"));
let Gmsmith = require("gmsmith");
let concat = require("concat-stream");
let promiseLimit = require("promise-limit");
module.exports = class ImageProcessor{
constructor() {
this.gm = gm.subClass({ imageMagick: true });
}
getSize(path) {
return imageSize(path);
}
scale(input, output, scale) {
let resized = this.gm(input)
.resizeExact(scale.width, scale.height);
return promisify(resized.write.bind(resized))(output);
}
trim(input, output, fuzz) {
fuzz = fuzz || "0%";
let imageWithBorder = this.gm(input)
.borderColor("none")
.border(1, 1);
return promisify(imageWithBorder.toBuffer.bind(imageWithBorder))()
.then((data) => {
let image = this.gm(data).trim();
return promisify(image.identify.bind(image))("%@");
})
.then((data) => {
data = data.match(/^(\d+)x(\d+)\+(\d+)\+(\d+)$/);
var width = parseInt(data[1], 10);
var height = parseInt(data[2], 10);
var x = parseInt(data[3], 10) - 1;
var y = parseInt(data[4], 10) - 1;
if(width === 0 && height === 0) {
return false;
}
if (width === 0 || height === 0) {
width = 1;
height = 1;
x = 0;
y = 0;
}
var crop = this.gm(input)
.crop(width, height, x, y);
return promisify(crop.write.bind(crop))(output)
.then(() => { return {width, height, x, y}; });
});
};
combine(rects, width, height, outputFileName, jpeg, quality, compressor) {
let exportOptions = {format: jpeg ? "jpeg" : "png"};
if (jpeg && quality) {
exportOptions.quality = quality;
}
let gmsmith = new Gmsmith({});
let paths = rects.map(rect => rect.data.path);
return promisify(gmsmith.createImages.bind(gmsmith))(paths)
.then(images => {
let canvas = gmsmith.createCanvas(width, height);
images.forEach((image, i) => {
canvas.addImage(image, rects[i].x, rects[i].y);
});
let stream = canvas.export(exportOptions);
return new Promise((resolve, reject) => {
stream.on("error", reject);
stream.pipe(concat({encoding: "buffer"}, resolve))
})
})
.then(buffer => compressor ? compressor(buffer) : buffer)
.then(buffer => promisify(fs.writeFile)(outputFileName, buffer));
}
};