This repository was archived by the owner on Jun 22, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathimageOptimizer.js
106 lines (103 loc) · 3.4 KB
/
imageOptimizer.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
"use strict";
const AWS = require("aws-sdk");
const util = require("util");
const gm = require("gm").subClass({ imageMagick: true });
const imagemin = require("imagemin");
const imageminPngquant = require("imagemin-pngquant");
const s3 = new AWS.S3();
/*
This regexes helps identify the size patterns:
WxHxXparamxYparam
Or
700x700xOxO
700x700_1800x1800
700x700-1800x1800
500x500_700x700-1800x1800
*/
const cropRegex = /(\d+x\d+x\d+x\d+(-|_)?)+/;
const resizeRegex = /(\d+x\d+(-|_)?)+/;
const IMG_EXTENSION = "PNG";
const SRC_FOLDER = "originals/";
const DEST_FOLDER = "processed/";
const DEST_BUCKET = process.env.BUCKET || 'mediumphotosresizer';
const DEFAULT_SIZES = process.env.SIZES || '1500x1500-500x500';
module.exports.handler = async event => {
console.log('h)');
log("Reading options from event:\n", util.inspect(event, { depth: 5 }));
const { s3: s3Obj } = event.Records[0];
const srcBucket = s3Obj.bucket.name;
const originalKey = decodeURIComponent(s3Obj.object.key.replace(/\+/g, " "));
let srcKey = originalKey.replace('/', `/${DEFAULT_SIZES}/`);
const absoluteImagePath = `${srcBucket}/${srcKey}`;
// Get the sizes encoded in the path of the image
const cropMatch = srcKey.match(cropRegex);
const resizeMatch = srcKey.match(resizeRegex);
if (!cropMatch && !resizeMatch) throw Error(`Size not specified for file: ${absoluteImagePath}`);
log(`Getting image from S3: ${absoluteImagePath}`);
const response = await s3.getObject({ Bucket: srcBucket, Key: originalKey }).promise();
let sizes;
if (!cropMatch) {
sizes = resizeMatch[0].split(/-|_/);
} else {
srcKey = originalKey.replace(`/${DEFAULT_SIZES}/`, '/crop/');
sizes = cropMatch[0].split(/-|_/);
}
for (const size of sizes) {
log(`Resizing image to size: ${size}`);
const [width, height, xParam = 0, yParam = 0] = getWidthAndHeightFromSize(size);
const resizedImage = await resizeImage({
content: response.Body,
IMG_EXTENSION,
width,
height,
xParam,
yParam
});
log("Compressing image. Quality: 65-80");
const compressedImage = await imagemin.buffer(resizedImage, {
plugins: [imageminPngquant({ quality: [0.65, 0.8] })]
});
let dstKey;
log(`crop match ${cropMatch} and resize match ${resizeMatch}`)
if (!cropMatch) {
dstKey = srcKey.split(SRC_FOLDER)[1].replace(resizeRegex, size);
} else {
dstKey = srcKey.split(SRC_FOLDER)[1].replace(cropRegex, `crop/${size}`);
}
log(`Uploading processed image to: ${dstKey}`);
await s3
.putObject({
Bucket: DEST_BUCKET,
Key: `${DEST_FOLDER}${dstKey}`,
Body: compressedImage,
ContentType: response.ContentType
})
.promise();
}
log(`Successfully processed ${srcBucket}/${srcKey}`);
};
function log(...args) {
console.log(...args);
}
function getWidthAndHeightFromSize(size) {
return size.split("x");
}
function resizeImage({ width, height, imgExtension, content, xParam, yParam }) {
return new Promise((resolve, reject) => {
if (!xParam && !yParam) {
gm(content)
.resize(width, height)
.toBuffer(imgExtension, function(err, buffer) {
if (err) reject(err);
else resolve(buffer);
});
} else {
gm(content)
.crop(width, height, xParam, yParam)
.toBuffer(imgExtension, function(err, buffer) {
if (err) reject(err);
else resolve(buffer);
});
}
});
}