1- const gm = require ( 'gm' ) . subClass ( { imageMagick : true } ) ;
2- const AWS = require ( 'aws-sdk' ) ;
1+ const S3 = require ( './libs/s3' ) ;
2+ const Optimizer = require ( './libs/optimize' ) ;
3+ const Utils = require ( './libs/utils' ) ;
34
4- const s3 = new AWS . S3 ( ) ;
5+ // Quality from 0 to 100
6+ const QUALITY = 60 ;
57
6- exports . handler = async ( event , context , cb ) => {
7- const validExtensions = [ 'jpg' , 'jpeg' , 'png' ] ;
8+ // Where images are uploaded
9+ const ORIGIN = 'original/' ;
810
9- const { bucket, object } = event . Records [ 0 ] . s3 ;
11+ // Where optimized images will be saved
12+ const DESTINATION = 'thumbs/' ;
1013
11- // Where images are uploaded
12- const origin = 'original/' ;
14+ exports . handler = async ( event , ctx , cb ) => {
15+ const validExtensions = [ 'jpg' , 'jpeg' , 'png' ] ;
1316
14- // Where optimized images will be saved
15- const dest = 'thumbs/' ;
17+ const { bucket, object } = event . Records [ 0 ] . s3 ;
1618
17- // Object key may have spaces or unicode non-ASCII characters. Remove prefix
18- const fullFileName = decodeURIComponent ( object . key . replace ( / \+ / g, ' ' ) )
19- . split ( '/' ) . pop ( ) ;
19+ const fullFileName = Utils . getFileName ( object . key ) ;
2020
2121 const [ fileName , fileExt ] = fullFileName . split ( '.' ) ;
2222
@@ -25,56 +25,24 @@ exports.handler = async (event, context, cb) => {
2525 }
2626
2727 // 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- }
28+ const s3Image = await S3 . download ( bucket . name , `${ ORIGIN } ${ fullFileName } ` ) ;
5429
5530 // use null to optimize image without resizing
5631 const sizes = [ null , 1200 , 640 , 420 ] ;
5732
58- // Uploades all images to S3
33+ // Uploades optimized images to S3
5934 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 ( ) ;
35+ const optimizedImage = await Optimizer . optimize ( s3Image . Body , s3Image . ContentType , size , QUALITY ) ;
36+ const objectKey = Utils . genKey ( DESTINATION , fileName , size , fileExt ) ;
37+ return S3 . upload ( bucket . name , objectKey , optimizedImage ) ;
7138 } ) ;
7239
7340 await Promise . all ( uploadPromises ) ;
7441
7542 cb ( null , 'finished' ) ;
7643} ;
7744
45+ // Execute function if running in local
7846if ( process . env . LOCAL === 'true' ) {
7947 exports . handler ( require ( './event.json' ) , null , ( err , res ) => {
8048 console . log ( res ) ;
0 commit comments