diff --git a/source/image-handler/image-handler.ts b/source/image-handler/image-handler.ts index 82cd67937..703fa1b10 100644 --- a/source/image-handler/image-handler.ts +++ b/source/image-handler/image-handler.ts @@ -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) {} @@ -75,13 +76,29 @@ export class ImageHandler { */ async process(imageRequestInfo: ImageRequestInfo): Promise { 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 diff --git a/source/image-handler/test/image-handler/resize.spec.ts b/source/image-handler/test/image-handler/resize.spec.ts index 14193d4ae..c71d8a0db 100644 --- a/source/image-handler/test/image-handler/resize.spec.ts +++ b/source/image-handler/test/image-handler/resize.spec.ts @@ -33,4 +33,4 @@ describe("resize", () => { .toBuffer(); expect(resultBuffer).toEqual(convertedImage); }); -}); +}); \ No newline at end of file diff --git a/source/image-handler/test/image-handler/resizelimitpixel.spec.ts b/source/image-handler/test/image-handler/resizelimitpixel.spec.ts new file mode 100644 index 000000000..b51053a73 --- /dev/null +++ b/source/image-handler/test/image-handler/resizelimitpixel.spec.ts @@ -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); + }); +});