Image.Save() too slow C#

For Jpeg and PNG images it takes anywhere from 10-60 seconds to save an image as a pdf. This is unacceptable for our application. It has slowed down our processing tremendously. The code in the else statement was fast but caused a cannot access closed stream error.

Below is the code we are using:

public async Task<MemoryStream> ConvertImageToPDF(Stream streamToConvert, int intDocNo)
{
Aspose.Pdf.Document doc = new Aspose.Pdf.Document();
Page page = doc.Pages.Add();
page.PageInfo.Margin.Top = 0;
page.PageInfo.Margin.Bottom = 0;
page.PageInfo.Margin.Left = 0;
page.PageInfo.Margin.Right = 0;

Aspose.Pdf.Image pdfImage = new Aspose.Pdf.Image();
pdfImage.FixWidth = page.PageInfo.Width;
pdfImage.FixHeight = page.PageInfo.Height;

int imagebuffersize = streamToConvert.Length >= 1048576 ? (int)((float)(streamToConvert.Length / 1048576) * 2) : 10;

streamToConvert.Position = 0;
Aspose.Imaging.Image Asposeimage = Aspose.Imaging.Image.Load(streamToConvert, new Aspose.Imaging.LoadOptions { BufferSizeHint = imagebuffersize });

if (image.FileFormat == FileFormat.Tiff)
{
    //Working
    stopwatch.Start();
    
    TiffImage tiffImage = (TiffImage)image;
    PdfOptions pdfOptions = new PdfOptions();
    pdfOptions.ResolutionSettings = new ResolutionSetting(tiffImage.HorizontalResolution, tiffImage.VerticalResolution);
    image.Save(outStream, pdfOptions);

    stopwatch.Stop();
    Log.Information("save tiff image {ElapsedMilliseconds} ms", stopwatch.ElapsedMilliseconds);
}
else if (image.FileFormat == FileFormat.Jpeg)
{
    stopwatch.Start();

    var saveOptions = new Aspose.Imaging.ImageOptions.JpegOptions
    {
        CompressionType = Aspose.Imaging.FileFormats.Jpeg.JpegCompressionMode.Progressive,
        ColorType = Aspose.Imaging.FileFormats.Jpeg.JpegCompressionColorMode.YCbCr,
        Quality = 50
    };

    image.Save(imageStream, saveOptions);
    imageStream.Position = 0;

    if (imageStream.Length > 0)
    {
        pdfImage.ImageStream = imageStream;
        pdfImage.ImageStream.Position = 0;
        page.Paragraphs.Add(pdfImage);
        doc.Save(outStream);
    }
    else
    {
        Log.Information("jpeg image length was 0 after saving options");
    }


    stopwatch.Stop();
    Log.Information("save jpeg image {ElapsedMilliseconds} ms", stopwatch.ElapsedMilliseconds);
}
else if (image.FileFormat == FileFormat.Png)
{
    stopwatch.Start();

    var saveOptions = new Aspose.Imaging.ImageOptions.PngOptions
    {
        ColorType = Aspose.Imaging.FileFormats.Png.PngColorType.TruecolorWithAlpha,
        BitDepth = 8,
        CompressionLevel = 9,
        FilterType = Aspose.Imaging.FileFormats.Png.PngFilterType.Adaptive
    };

    image.Save(imageStream, saveOptions);
    imageStream.Position = 0;

    if (imageStream.Length > 0)
    {
        pdfImage.ImageStream = imageStream;
        pdfImage.ImageStream.Position = 0;
        page.Paragraphs.Add(pdfImage);
        doc.Save(outStream);
    }
    else
    {
        Log.Information("png image length was 0 after saving options");
    }


    stopwatch.Stop();
    Log.Information("save png image {ElapsedMilliseconds} ms", stopwatch.ElapsedMilliseconds);
}
else
{
    //cannot access closed stream error
    stopwatch.Start();
    
    pdfImage.ImageStream = streamToConvert;
    pdfImage.ImageStream.Position = 0;
    page.Paragraphs.Add(pdfImage);
    doc.Save(outStream);

    stopwatch.Stop();
    Log.Information(image.FileFormat.ToString() + " image {ElapsedMilliseconds} ms", stopwatch.ElapsedMilliseconds);

}
}

@scoutd

It seems that you are experiencing performance issues when saving JPEG and PNG images as PDFs using Aspose.Imaging, with save times ranging from 10 to 60 seconds. Here are some suggestions to potentially improve the performance of your image saving process:

  1. Buffer Size Optimization: You are currently setting the buffer size based on the length of the stream. Consider experimenting with different buffer sizes to find an optimal value that balances memory usage and performance. The default buffer size is often sufficient, but increasing it may help in some cases.

  2. Image Caching: In your code, you are not caching the image data. Caching can significantly improve performance when working with large images. You can call the CacheData() method on the image object after loading it. However, be cautious as caching can lead to increased memory usage.

  3. Image Format Handling: Ensure that you are using the most efficient image options for saving. For example, when saving JPEG images, you can adjust the quality setting to a lower value if high quality is not necessary. Similarly, for PNG images, consider using a lower compression level if it meets your quality requirements.

  4. Stream Management: Make sure that the streams you are using are properly managed. If you encounter a “cannot access closed stream” error, ensure that the stream is open and valid before attempting to save the image. You might want to check the lifecycle of your streams to avoid closing them prematurely.

  5. Asynchronous Processing: If your application allows it, consider implementing asynchronous processing for saving images. This can help improve the responsiveness of your application while the images are being processed in the background.

Here is a modified version of your code snippet that includes caching and optimized buffer size:

int imagebuffersize = streamToConvert.Length >= 1048576 ? (int)((float)(streamToConvert.Length / 1048576) * 2) : 10;

streamToConvert.Position = 0;
Aspose.Imaging.Image Asposeimage = Aspose.Imaging.Image.Load(streamToConvert, new Aspose.Imaging.LoadOptions { BufferSizeHint = imagebuffersize });

// Cache the image data
Asposeimage.CacheData();

if (image.FileFormat == FileFormat.Tiff)
{
    // Handle TIFF saving
}
else if (image.FileFormat == FileFormat.Jpeg)
{
    // Handle JPEG saving with optimized options
}
else if (image.FileFormat == FileFormat.Png)
{
    // Handle PNG saving with optimized options
}
else
{
    // Handle other formats
}

By implementing these suggestions, you may see an improvement in the performance of your image saving process. If the issue persists, consider reaching out to Aspose support for further assistance.

@scoutd, could you provide an example image for analysis that is slow to save.

I can’t unfortunately. Those images contain PHI. I will try my best to reproduce a similar image. In the mean time the images are usually less than 10 mb and jpeg file type.
I am running my application on window servers and that is when I am seeing the slowness issue. In visual studio it seems to be working fine.

I can advise you 2 options

  1. Try saving jpg to pdf, using Aspose.Imaging, as in your case with Tiff
  2. Try using Aspose.Imaging.Pdf.Adapter - NuGet Gallery | Aspose.Imaging.Pdf.Adapter 24.10.0

Okay thank you I will try and update you