haraldk / TwelveMonkeys

TwelveMonkeys ImageIO: Additional plug-ins and extensions for Java's ImageIO
https://haraldk.github.io/TwelveMonkeys/
BSD 3-Clause "New" or "Revised" License
1.83k stars 309 forks source link

Unable to read dynamic webp using javax.imageio.ImageIO#read(java.io.InputStream) on aws lambda #969

Open coffee-developer opened 2 weeks ago

coffee-developer commented 2 weeks ago

Describe the bug A clear and concise description of what the bug is. I can use javax.imageio.ImageIO#read(java.io.InputStream) to read the webp file on my win10 computer, but it cannot be read on aws lambda. ImageIo.read returns null. The java version on aws lambda is twenty one Version information

  1. The version of the TwelveMonkeys ImageIO library in use. For example: 4.0.0 org.apache.xmlgraphics batik-all 1.17
    <dependency>
        <groupId>com.twelvemonkeys.imageio</groupId>
        <artifactId>imageio-batik</artifactId>
        <version>3.11.0</version>
    </dependency>
    <dependency>
        <groupId>com.twelvemonkeys.imageio</groupId>
        <artifactId>imageio-webp</artifactId>
        <version>3.11.0</version>
    </dependency>
  2. The exact output of java --version (or java -version for older Java releases). Java environment on my localhost win10 openjdk version "21.0.3" 2024-04-16 LTS OpenJDK Runtime Environment Corretto-21.0.3.9.1 (build 21.0.3+9-LTS) OpenJDK 64-Bit Server VM Corretto-21.0.3.9.1 (build 21.0.3+9-LTS, mixed mode, sharing)

aws lambda java version is jdk21

  1. Extra information about OS version, server version, standalone program or web application packaging, executable wrapper, etc. Please state exact version numbers where applicable. aws lamdba java 21 To Reproduce Steps to reproduce the behavior:

  2. Compile the below sample code AWSCredentials awsCredentials = new BasicAWSCredentials(accessKeyId, secretAccessKey); AmazonS3ClientBuilder builder = AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(awsCredentials)); builder.setRegion(region); AmazonS3 s3Client = builder.build(); @Cleanup S3ObjectInputStream objectContent = s3Object.getObjectContent(); BufferedImage bufferedImage = ImageIO.read(objectContent) bufferedImage is null

  3. Download the sample image file https://cdn.acop.makeronline.com/asop/2024-03/17/webp/171063400961894800-65f63419.webp

haraldk commented 2 weeks ago

Hi,

I don't have access to an AWS Lambda environment, but I have some ideas to what is happening here. If ImageIO.read(InputSttream) returns null (as opposed to throwing exceptions), that means the image file format is not recognized, and no decoding is attempted. This is typically caused by two things:

  1. Either the image is not in the format you think, is corrupted in a way such that the file "magic identifier" is no longer correct, or the file is empty (etc.). The best way to verify this, is to use the same code as above, but instead of invoking ImageIO.read you just download the data to a new file (use Files.copy(objectContent, tempWebPFile) or similar). Inspect the file in a hex editor, or verify that the files's content is exactly the same as the file you uploaded.
  2. The ImageIO plugin for the file format is not (correctly) installed at runtime. The Readme has an example on how you can verify that, just replace "JPEG" with "WebP".

My hunch is that the problem you face is the latter. I don't know exactly how you install 3rd party libs on Lambda, but there might be some issues related to that, perhaps similar to how you deploy the library in a web app. The Readme has some guidance there too, that might help.