Skip to content

Commit 374584c

Browse files
Using ImageMagick to optimize and resize
0 parents  commit 374584c

File tree

8 files changed

+979
-0
lines changed

8 files changed

+979
-0
lines changed

.gitignore

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
*/node_modules
5+
*/.pnp
6+
*.pnp.js
7+
8+
# testing
9+
*/coverage
10+
11+
# production
12+
*/build
13+
14+
# misc
15+
.DS_Store
16+
.env.local
17+
.env.development.local
18+
.env.test.local
19+
.env.production.local
20+
21+
npm-debug.log*
22+
yarn-debug.log*
23+
yarn-error.log*
24+
25+
# Bundle
26+
*.zip

function/event.json

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"Records": [
3+
{
4+
"eventVersion": "2.1",
5+
"eventSource": "aws:s3",
6+
"awsRegion": "us-east-1",
7+
"eventTime": "2019-08-07T20:02:00.791Z",
8+
"eventName": "ObjectCreated:Put",
9+
"userIdentity": {
10+
"principalId": "AWS:SOMEID"
11+
},
12+
"requestParameters": {
13+
"sourceIPAddress": "192.168.0.1"
14+
},
15+
"responseElements": {
16+
"x-amz-request-id": "REQUESTID",
17+
"x-amz-id-2": "AMAZONID2="
18+
},
19+
"s3": {
20+
"s3SchemaVersion": "1.0",
21+
"configurationId": "a34d5c09-019b-4a6a-ba09-2fca03412e81",
22+
"bucket": {
23+
"name": "rtalexk-gallery",
24+
"ownerIdentity": {
25+
"principalId": "SOMEID"
26+
},
27+
"arn": "arn:aws:s3:::rtalexk-gallery"
28+
},
29+
"object": {
30+
"key": "original/cat.jpg",
31+
"size": 3513370,
32+
"eTag": "TAGID",
33+
"sequencer": "SEQUENCERID"
34+
}
35+
}
36+
}
37+
]
38+
}

function/index.js

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
const gm = require('gm').subClass({ imageMagick: false });
2+
const AWS = require('aws-sdk');
3+
4+
const s3 = new AWS.S3();
5+
6+
exports.handler = async (event, context, cb) => {
7+
const validExtensions = ['jpg', 'jpeg', 'png'];
8+
9+
const { bucket, object } = event.Records[0].s3;
10+
11+
// Where images are uploaded
12+
const origin = 'original/';
13+
14+
// Where optimized images will be saved
15+
const dest = 'thumbs/';
16+
17+
// Object key may have spaces or unicode non-ASCII characters. Remove prefix
18+
const fullFileName = decodeURIComponent(object.key.replace(/\+/g, ' '))
19+
.split('/').pop();
20+
21+
const [fileName, fileExt] = fullFileName.split('.');
22+
23+
if (!validExtensions.includes(fileExt)) {
24+
return cb(null, `Image not processed due to .${fileExt} file extension`);
25+
}
26+
27+
// Download image from S3
28+
const s3Image = await s3.
29+
getObject({
30+
Bucket: bucket.name,
31+
Key: `${origin}${fullFileName}`
32+
})
33+
.promise();
34+
35+
function gmToBuffer(data) {
36+
return new Promise((resolve, reject) => {
37+
data.stream((err, stdout, stderr) => {
38+
if (err) { return reject(err) }
39+
const chunks = []
40+
stdout.on('data', (chunk) => { chunks.push(chunk) })
41+
stdout.once('end', () => { resolve(Buffer.concat(chunks)) })
42+
stderr.once('data', (data) => { reject(String(data)) })
43+
})
44+
})
45+
}
46+
47+
function getBuffer(body, size, quality) {
48+
const data = gm(body)
49+
.resize(size)
50+
.quality(quality);
51+
52+
return gmToBuffer(data);
53+
}
54+
55+
// use null to optimize image without resizing
56+
const sizes = [null, 1200, 640, 420];
57+
58+
// Uploades all images to S3
59+
const uploadPromises = sizes.map(async size => {
60+
// Optimize image with current size
61+
const imgBuffer = await getBuffer(s3Image.Body, size, 60);
62+
const key = size
63+
? `${dest}${fileName}_thumb_${size}.${fileExt}`
64+
: `${dest}${fileName}_original.${fileExt}`;
65+
66+
return s3.putObject({
67+
Bucket: bucket.name,
68+
Key: key,
69+
Body: imgBuffer,
70+
}).promise();
71+
});
72+
73+
await Promise.all(uploadPromises);
74+
75+
cb(null, 'finished');
76+
};
77+
78+
if (process.env.LOCAL === 'true') {
79+
exports.handler(require('./event.json'), null, (err, res) => {
80+
console.log(res);
81+
});
82+
}

function/libs/optimize.js

Whitespace-only changes.

function/libs/resize.js

Whitespace-only changes.

0 commit comments

Comments
 (0)