我正在使用以下代码调整多张图片的大小:
样品请求1:/images/0/products/1/10x10$20x20$30x30/test.jpg
示例请求2:/images/0/banners/10x10$20x20$30x30/test.jpg
在这里,我正在尝试处理两种图像的图像调整大小。产品之一和横幅之一。我用于请求的示例json:
{
"Records": [
{
"cf": {
"config": {
"distributionDomainName": "d30ctzvvm0c9tj.cloudfront.net",
"distributionId": "E7L07HTI8617C",
"eventType": "origin-response"
},
"request": {
"clientIp": "103.217.247.2",
"headers": {
"user-agent": [
{
"key": "User-Agent",
"value": "Amazon CloudFront"
}
],
"via": [
{
"key": "Via",
"value": "1.1 126c88e8d3434fec67dab0faaa786e61.cloudfront.net (CloudFront)"
}
],
"upgrade-insecure-requests": [
{
"key": "Upgrade-Insecure-Requests",
"value": "1"
}
],
"accept-encoding": [
{
"key": "Accept-Encoding",
"value": "gzip"
}
],
"x-forwarded-for": [
{
"key": "X-Forwarded-For",
"value": "103.217.247.2"
}
],
"host": [
{
"key": "Host",
"value": "test-cloudfront-shirsh.s3.amazonaws.com"
}
]
},
"method": "GET",
"origin": {
"s3": {
"authMethod": "origin-access-identity",
"customHeaders": {},
"domainName": "test-cloudfront-shirsh.s3.amazonaws.com",
"path": "",
"region": "ap-south-1"
}
},
"querystring": "d=10x10$20x20$30x30",
"uri": "/images/0/banners/10x10$20x20$30x30/test.jpg"
},
"response": {
"headers": {
"x-amz-request-id": [
{
"key": "x-amz-request-id",
"value": "1B822F690E9022FF"
}
],
"x-amz-id-2": [
{
"key": "x-amz-id-2",
"value": "rfK2MUwZnmBmp5KssOJfKK+hTLNwHiNrxFAwqbWRE2yXt8PQzEWNgJmhVSh488Me7wXupuu8w8A="
}
],
"date": [
{
"key": "Date",
"value": "Fri, 12 Oct 2018 10:04:55 GMT"
}
],
"server": [
{
"key": "Server",
"value": "AmazonS3"
}
],
"content-type": [
{
"key": "Content-Type",
"value": "application/xml"
}
],
"transfer-encoding": [
{
"key": "Transfer-Encoding",
"value": "chunked"
}
]
},
"status": "404",
"statusDescription": "Forbidden"
}
}
}
]
}
对于上述要求(横幅):
源图像桶:/images/0/banners/test.jpg
要生成的尺寸:10x10、20x20、30x30
目标图像段:
/images/0/banners/10x10/test.jpg
/images/0/banners/20x20/test.jpg
/images/0/banners/30x30/test.jpg
但是,它仅保存最后一张图像:/images/0/banners/30x30/test.jpg
我的Js代码:
'use strict';
const http = require('http');
const https = require('https');
const querystring = require('querystring');
const AWS = require('aws-sdk');
const S3 = new AWS.S3({
signatureVersion: 'v4',
});
const Sharp = require('sharp');
// set the S3 and API GW endpoints
const BUCKET = 'test-cloudfront-shirsh';
exports.handler = (event, context, callback) => {
let response = event.Records[0].cf.response;
console.log("Response Header::" + JSON.stringify(response));
console.log("Response status code :%s", response.status);
const variables = {
allowedDimension : [],
};
// check if image is not present
if (response.status == 404 || response.status == 403) {
let request = event.Records[0].cf.request;
let params = querystring.parse(request.querystring);
console.log("d=" + params.d);
// if there is no dimension attribute, just pass the response
if (!params.d) {
callback(null, response);
return;
}
variables.allowedDimension=params.d.split("$");
if(variables.allowedDimension.length >=1 ){
var prod_regex=/\/images\/0\/products\/(\d+)/;
var banner_regex=/\/images\/0\/banners/;
let path,prefix, originalKey, match, width, height, requiredFormat, imageName,bucketKey,key,dimArray,dimensionRatios;
console.log("Using forEach");
variables.allowedDimension.forEach(function(dimension, index){
path = request.uri;
dimensionRatios= path.split('/');
console.log("Path::" + path);
try {
// "/images/0/banners/20x20/jpg/abc.jpg";
if(banner_regex.test(path)){
console.log("Regex for banner");
key = path.replace(dimensionRatios[4],dimension);
dimArray = dimension.split("x");
match = key.match(/\/(.*)\/(.*)\/(.*)\/(\d+)x(\d+)\/(.*)/);
prefix = match[1]+"/"+match[2]+"/"+match[3]+ "/";
imageName = match[6];
}if(prod_regex.test(path)){
console.log("Regex for product");
key = path.replace(dimensionRatios[5],dimension);
dimArray = dimension.split("x");
match=key.match(/\/(.*)\/(.*)\/(.*)\/(\d+)\/(\d+)x(\d+)\/(.*)/);
prefix = match[1]+"/"+match[2]+"/"+match[3]+ "/" + match[4] + "/";
imageName = match[7];
}
width = parseInt(dimArray[0],10);
height = parseInt(dimArray[1],10);
requiredFormat = "jpg";
originalKey = prefix + imageName;
bucketKey= prefix + dimension + "/" + imageName;
console.log("dimension::" + dimension + "\nkey::"+ key +"\npath::"+path +"\nPrefx:::" + prefix + "\nimageName:" +imageName
+ "\nWidthxHeight" + width + "x" + height + "\nBucket Key:" + bucketKey+"\nOrig Key::" + originalKey);
}
catch (err) {
console.log("no prefix present.."+err);
}
// get the source image file
S3.getObject({ Bucket: BUCKET, Key: originalKey }).promise()
// perform the resize operation
.then(data => Sharp(data.Body)
.resize(width, height)
.ignoreAspectRatio()
.toFormat(requiredFormat)
.toBuffer()
)
.then(buffer => {
console.log("Putting image for buckt key :" + bucketKey );
// save the resized object to S3 bucket with appropriate object
// key.
S3.putObject({
Body: buffer,
Bucket: BUCKET,
ContentType: 'image/' + requiredFormat,
CacheControl: 'max-age=31536000',
Key: bucketKey,
StorageClass: 'STANDARD'
}).promise()
// even if there is exception in saving the object we send back
// the generated
// image back to viewer below
.catch(error => { console.log("Exception while writing resized image to bucket",error)});
response.status = 200;
response.body = buffer.toString('base64');
response.bodyEncoding = 'base64';
response.headers['content-type'] = [{ key: 'Content-Type', value: 'image/' + requiredFormat }];
callback(null, response);
})
.catch( err => {
console.log("Exception while reading source image with error :",err);
});
// generate a binary response with resized image
});
// read the S3 key from the path variable.
// Ex: path variable /images/100x100/webp/image.jpg
}else{
callback(null, response);
}
// read the required path. Ex: uri /images/100x100/webp/image.jpg
} // end of if block checking response statusCode
else {
// allow the response to pass through
callback(null, response);
}
};