Although this doesn't have anything to do with my problem, I would like to give some context.
My setup is as follows : An Amazon S3 bucket that stores images and another S3 bucket that stores the thumbnail of the images. The goal is whenever a new image is uploaded to the first bucket, a Lambda function is triggered, reads the image from the first bucket, creates a thumbnail and stores it in the second bucket. The issue that I'm facing is that this procedure works perfectly when the images are small in size but when the image size gets bigger, I run out of Java heap space when reading the image.
Note: I CANNOT increase the Java heap size of the AWS Lambda function, it is at the max permissible amount already.
The code I use is as follows:
AmazonS3 s3Client = new AmazonS3Client();
S3Object s3Object = s3Client.getObject(new GetObjectRequest(srcBucket, srcKey));
InputStream objectData = s3Object.getObjectContent();
System.out.println("Reading source image");
BufferedImage srcImage = ImageIO.read(objectData);
The ImageIO.read() throws the following error when trying to read in a 200 MB image:
Java heap space: java.lang.OutOfMemoryError java.lang.OutOfMemoryError: Java heap space
at java.awt.image.DataBufferByte.<init>(DataBufferByte.java:92)
at java.awt.image.ComponentSampleModel.createDataBuffer(ComponentSampleModel.java:445)
at java.awt.image.Raster.createWritableRaster(Raster.java:941)
at javax.imageio.ImageTypeSpecifier.createBufferedImage(ImageTypeSpecifier.java:1074)
at javax.imageio.ImageReader.getDestination(ImageReader.java:2892)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:1071)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:1039)
at javax.imageio.ImageIO.read(ImageIO.java:1448)
at javax.imageio.ImageIO.read(ImageIO.java:1352)
Now, as I understand, using BufferedImage is bad since it uncompresses the image. So, my question is: Is there any other way to read the image other than ImageIO.read()? Or read in an image into some other format perhaps?
Another thought that crossed my mind was to read parts of image at a time by using rectangular dimensions, but I wouldn't know the dimensions of the complete image without reading the image so I wasn't sure how to go about this.
Any help is much appreciated!