SixLabors / ImageSharp

:camera: A modern, cross-platform, 2D Graphics library for .NET
https://sixlabors.com/products/imagesharp/
Other
7.34k stars 847 forks source link

Issues Loading JFIF/JPG images from S3 #2783

Closed damihundeyinflynn closed 1 month ago

damihundeyinflynn commented 1 month ago

Prerequisites

ImageSharp version

3.1.5

Other ImageSharp packages and versions

N/A

Environment (Operating system, version and so on)

AWS Lambda (Linux)

.NET Framework version

8.0

Description

Were trying to create a lambda that compresses images and sets them in a pdf, we get these images from AWS S3. on s3 we noticed that the images were saved as .jpg and when we try to load them into Image sharp we were getting errors of unsupported format. I opened up the image in a text editor and noticed that the images were actually JFIF images. Can we know if there will be any support for JFIF images? currently imagesharp is the only package i've found that works on Linux using .NET and now were stuck because we cant load JFIF images. Can support be added for this?

Thanks

Steps to Reproduce

try to load JFIF image into imagesharp

Images

No response

JimBobSquarePants commented 1 month ago

JPEG File Interchange Format (JFIF) is simply the JPEG standard and ImageSharp opens JPEG files just fine.

I suspect the issue lies with your code in that you would not be providing the input stream correctly however since you have not provided any images it’s not possible to prove that.

damihundeyinflynn commented 1 month ago

1699962405693 This is an example of the image

And a bit of the code: image

To provide the input stream into the function we do:

var msImage = new MemoryStream();
var response = await s3utils.DownloadS3Bucket(imgUrlStr, context).ConfigureAwait(false);
await response.ResponseStream.CopyToAsync(msImage).ConfigureAwait(false);
msImage.Position = 0;
msImage = await FileService.Compress(msImage);

Please let me know if you need anything else

antonfirsov commented 1 month ago

We still don't know what does s3utils.DownloadS3Bucket() do.

Can please you create a minimal self-contained repro app? Can you check with that app if the issue is indeed specific to S3, ie. replacing the S3 stream with a FileStream will change anything?

This would speed up the investigation a lot.

damihundeyinflynn commented 1 month ago

The DownloadS3Bucket function simply calls the Aws Api for get object Async and returns the response. The s3 stream is not the problem as it works fine with other library's like Aspose and System.Drawing.Common but for reasons i cant use both of them right now so i opted to use image sharp and got the issues below.

JimBobSquarePants commented 1 month ago

I'm able to load the image just fine. I've simulated the same copy from a file stream to ensure I'm matching the input process and I've checked using both the asynchronous and synchronous APIs.

using FileStream fs = File.OpenRead(@"C:\Users\james\Downloads\2783.jpg");
using MemoryStream ms = new();
await fs.CopyToAsync(ms);
ms.Position = 0;

using Image img = await Image.LoadAsync(ms);
JpegEncoder encoder = new() { Quality = 50 };
await img.SaveAsync($@"C:\Users\james\Downloads\2783-out-stream.jpg", encoder);

Here's the output. 2783-out-stream

I can only assume you've got something wrong going on in your codebase given that there is code like this present in the sample you've provided.

await Task.Run(() => img.Save(outputStream, jpegencoder));
JimBobSquarePants commented 1 month ago

I'm closing this. We've proven that we can decode the image. I'd also like to add that ImageSharp.Web has an AWS S3 provider which also works well.

@damihundeyinflynn I would advise a review of your stream reading code. My guess is that it's a combination of bad sync/async code and no assurances that the stream is actually completely read from AWS.