Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix large pixel image rendition issue by adding limitInputPixels option #476

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions source/image-handler/image-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {

export class ImageHandler {
private readonly LAMBDA_PAYLOAD_LIMIT = 6 * 1024 * 1024;
private readonly LARGE_IMAGE_SIZE = 16364 * 16364;

constructor(private readonly s3Client: S3, private readonly rekognitionClient: Rekognition) {}

Expand Down Expand Up @@ -75,13 +76,29 @@ export class ImageHandler {
*/
async process(imageRequestInfo: ImageRequestInfo): Promise<string> {
const { originalImage, edits } = imageRequestInfo;
const options = { failOnError: false, animated: imageRequestInfo.contentType === ContentTypes.GIF };
const options = {
failOnError: false,
limitInputPixels: false,
animated: imageRequestInfo.contentType === ContentTypes.GIF,
};
let base64EncodedImage = "";

// Apply edits if specified
if (edits && Object.keys(edits).length) {
// convert image to Sharp object
const image = await this.instantiateSharpImage(originalImage, edits, options);
let image = await this.instantiateSharpImage(originalImage, edits, options);
//Get source image metadata
const metadata = await image.metadata();
const pixel = metadata.width * metadata.height;
// To avoid unwanted resource consumption, check and set the pixel limit to true for images with width and height less than 16364 * 16364. Reinstantiate the Image with low pixel limit.
if (pixel <= this.LARGE_IMAGE_SIZE) {
const newoptions = {
failOnError: false,
limitInputPixels: true,
animated: imageRequestInfo.contentType === ContentTypes.GIF,
};
image = await this.instantiateSharpImage(originalImage, edits, newoptions);
}
// apply image edits
let modifiedImage = await this.applyEdits(image, edits, options.animated);
// modify image output if requested
Expand Down
2 changes: 1 addition & 1 deletion source/image-handler/test/image-handler/resize.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ describe("resize", () => {
.toBuffer();
expect(resultBuffer).toEqual(convertedImage);
});
});
});
44 changes: 44 additions & 0 deletions source/image-handler/test/image-handler/resizelimitpixel.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import Rekognition from "aws-sdk/clients/rekognition";
import S3 from "aws-sdk/clients/s3";
import sharp from "sharp";
import fs from "fs";

import { ImageHandler } from "../../image-handler";
import { ImageEdits } from "../../lib";

const s3Client = new S3();
const rekognitionClient = new Rekognition();
const LARGE_IMAGE_SIZE = 16364 * 16364;

describe("resizelimitpixel", () => {
it("Should pass if resize width and height are provided as string number to the function", async () => {
const originalImage = fs.readFileSync("./test/image/aws_logo.png");
let limitFlag = false;
let image = sharp(originalImage, { failOnError: false, limitInputPixels: limitFlag }).withMetadata();
//Get source image metadata
const metadata = await image.metadata();
const pixel = metadata.width * metadata.height;
console.log("Source Image Pixel Size: " + pixel + " pixels");
// To avoid unwanted resource consumption, check and set the pixel limit to true for images with width and height less than 16364 * 16364.
// Reinstantiate the Image with low pixel limit.
if (pixel <= LARGE_IMAGE_SIZE) {
limitFlag = true;
image = sharp(originalImage, { failOnError: false, limitInputPixels: limitFlag }).withMetadata();
}
const edits: ImageEdits = { resize: { width: "99.1", height: "99.9" } };
// Act
const imageHandler = new ImageHandler(s3Client, rekognitionClient);
const result = await imageHandler.applyEdits(image, edits, false);

// Assert
const resultBuffer = await result.toBuffer();
const convertedImage = await sharp(originalImage, { failOnError: false, limitInputPixels: limitFlag })
.withMetadata()
.resize({ width: 99, height: 100 })
.toBuffer();
expect(resultBuffer).toEqual(convertedImage);
});
});