Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在AWS Lambda上以有限的堆空间读取Java中的大图像?_Java_Image_Amazon Web Services_Amazon S3_Aws Lambda - Fatal编程技术网

如何在AWS Lambda上以有限的堆空间读取Java中的大图像?

如何在AWS Lambda上以有限的堆空间读取Java中的大图像?,java,image,amazon-web-services,amazon-s3,aws-lambda,Java,Image,Amazon Web Services,Amazon S3,Aws Lambda,虽然这与我的问题无关,但我想给出一些背景 我的设置如下:一个AmazonS3存储桶存储图像,另一个S3存储桶存储图像的缩略图。目标是每当新图像上传到第一个bucket时,就会触发Lambda函数,从第一个bucket读取图像,创建缩略图并将其存储在第二个bucket中。我所面临的问题是,当图像较小时,此过程非常有效,但当图像较大时,我在读取图像时会耗尽Java堆空间 注意:我不能增加AWS Lambda函数的Java堆大小,它已经达到了允许的最大值 我使用的代码如下: Amazo

虽然这与我的问题无关,但我想给出一些背景

我的设置如下:一个AmazonS3存储桶存储图像,另一个S3存储桶存储图像的缩略图。目标是每当新图像上传到第一个bucket时,就会触发Lambda函数,从第一个bucket读取图像,创建缩略图并将其存储在第二个bucket中。我所面临的问题是,当图像较小时,此过程非常有效,但当图像较大时,我在读取图像时会耗尽Java堆空间

注意:我不能增加AWS Lambda函数的Java堆大小,它已经达到了允许的最大值

我使用的代码如下:

        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);
ImageIO.read()在尝试读取200 MB图像时引发以下错误:

        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)
Java堆空间:Java.lang.OutOfMemoryError Java.lang.OutOfMemoryError:Java堆空间
位于java.awt.image.DataBufferByte。(DataBufferByte.java:92)
位于java.awt.image.ComponentSampleModel.createDataBuffer(ComponentSampleModel.java:445)
位于java.awt.image.Raster.createWritableRaster(Raster.java:941)
在javax.imageio.ImageTypeSpecifier.createBuffereImage(ImageTypeSpecifier.java:1074)
位于javax.imageio.ImageReader.getDestination(ImageReader.java:2892)
位于com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:1071)
位于com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:1039)
在javax.imageio.imageio.read(imageio.java:1448)
在javax.imageio.imageio.read(imageio.java:1352)
现在,据我所知,使用BuffereImage是不好的,因为它会解压缩映像。所以,我的问题是:除了ImageIO.read()之外,还有其他方法读取图像吗?或者将图像读入其他格式

我脑海中闪过的另一个想法是通过使用矩形尺寸一次读取图像的一部分,但如果不读取图像,我就不知道完整图像的尺寸,因此我不确定如何进行此操作


非常感谢您的帮助

这是一个棘手的问题。AWS Lambda允许512 MB的临时本地磁盘存储。您必须将图像流式传输到磁盘,然后找到一种增量调整其大小的方法。我不确定是否有任何Java库可以做到这一点。Python可能有一些与PIL相关的选项。您是否查看了
ImageIO.createImageInputStream
?@aglassman感谢您的回复!Lambda真的很严格,不是吗(我曾尝试在nodeJS中执行此操作,但内存也不足。如果这不起作用,我也会查看Python选项。是的,它可能会有限制,lambda我认为更适合于海量数据收集和数据转换/操作。我不会想到使用它来处理大型图像。可能会有更好的方法选项。如果您专门为S3触发器使用它,您可以让它向一个更强大的后端服务器发送消息,然后通过ID或其他方式提取对象。@BrianKent感谢您回来!我想我可以使用ImageIO.createImageInputStream。我使用的代码是“ImageInputStream iis=ImageIO.CreateMageInputStream(objectData);System.out.println(“10位=“+iis.readBits(10));”,输出为“10位=1023”"-->只是打印一些东西以确保它能够读取原始图像。考虑到这一点,您建议我下一步做什么?这是一个棘手的问题。AWS Lambda允许512 MB的临时本地磁盘存储。您必须将图像流式传输到磁盘,然后找到一种方法以增量方式调整其大小。我不确定是否有Java Librarr就是这样。Python对PIL可能有一些选择。你看过
ImageIO.createImageInputStream
了吗?@aglassman谢谢你的回复!Lambda真的很有限制,不是吗(我曾尝试在nodeJS中执行此操作,但内存也不足。如果这不起作用,我也会查看Python选项。是的,它可能会有限制,lambda我认为更适合于海量数据收集和数据转换/操作。我不会想到使用它来处理大型图像。可能会有更好的方法选项。如果您专门为S3触发器使用它,您可以让它向一个更强大的后端服务器发送消息,然后通过ID或其他方式提取对象。@BrianKent感谢您回来!我想我可以使用ImageIO.createImageInputStream。我使用的代码是“ImageInputStream iis=ImageIO.CreateMageInputStream(objectData);System.out.println(“10位=“+iis.readBits(10));”,输出为“10位=1023”->只是打印一些东西以确保它能够读取原始图像。考虑到这一点,您建议我下一步做什么?