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.
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:
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.
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.
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.
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.
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.
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.
Apologies for the delayed response.
I have tried saving jpeg images like I do with tiff and it drastically increased the time it took to save. I tried #2 and it helped. Now it is saving at 5-10 seconds instead of 10-30.
It is better after the pdf Adapter changes but jpeg images (5-10 sec) still are not saving as fast as tiff images (1-2 sec). Also the jpeg images that are taking a long time to save are not large files (~300 KB). Is there anything else I can try to boost the performance of image.Save()?
Below are the code changes I have made for reference:
Stopwatch sw = new Stopwatch();
Document doc = new Document();
//// Add an empty page
Page page = doc.Pages.Add();
//// Set margins so image will fit, etc.
page.PageInfo.Margin.Top = 0;
page.PageInfo.Margin.Bottom = 0;
page.PageInfo.Margin.Left = 0;
page.PageInfo.Margin.Right = 0;
PdfImage.Register();
string fileType = string.Empty;
MemoryStream outStream = new MemoryStream();
outStream.Position = 0;
try
{
//Bytes to MB Formula
long lengthInMB = streamToConvert.Length / 1048576;
int imagebuffersize = streamToConvert.Length >= 1048576 ? (int)(lengthInMB * 2) : 10;
streamToConvert.Position = 0;
using (Aspose.Imaging.Image image = Aspose.Imaging.Image.Load(streamToConvert, new Aspose.Imaging.LoadOptions { BufferSizeHint = imagebuffersize }))
{
streamToConvert.Position = 0;
fileType = image.FileFormat.ToString();
if (image.FileFormat == FileFormat.Tiff)
{
sw.Start();
TiffImage tiffImage = (TiffImage)image;
PdfOptions pdfOptions = new PdfOptions();
pdfOptions.ResolutionSettings = new ResolutionSetting(tiffImage.HorizontalResolution, tiffImage.VerticalResolution);
image.Save(outStream, pdfOptions);
sw.Stop();
}
else if (image.FileFormat == FileFormat.Jpeg)
{
sw.Start();
image.Save(outStream, new ImageOptionsExt<PdfSaveOptionsExt>()
{
SaveOptions = new PdfSaveOptionsExt()
{
FormatConversionOptions = new PdfFormatConversionOptions(PdfFormat.PDF_A_1A)
},
VectorRasterizationOptions = new CdrRasterizationOptions()
{
PageSize = image.Size
}
});
sw.Stop();
}
else
{
sw.Start();
image.Save(outStream, new PdfOptions()
{
PdfDocumentInfo = new Aspose.Imaging.FileFormats.Pdf.PdfDocumentInfo(),
PageSize = new Aspose.Imaging.SizeF((float)page.PageInfo.Width, (float)page.PageInfo.Height)
});
sw.Stop();
}
}
//Log to document time for conversion
Log.Information(this.GetType().ToString() + " Time Elapsed for " + fileType + " image " + sw.ElapsedMilliseconds + " ms ";
sw.Reset();
outStream.Position = 0;
return outStream;
}
catch (Exception ex)
{
Log.Error(ex, this.GetType().FullName + "Error converting " + fileType + " to PDF --- InstanceID: " + instanceId + "-- - DocNo: " + intDocNo.ToString() );
throw;
}
finally
{
doc.FreeMemory();
streamToConvert.Dispose();
}
@scoutd In your example, you limit the amount of RAM. What is the reason?
If you do not limit the use of RAM, then the work will be much faster, and you can save RAM in another way, for example, by using FileStream instead of MemoryStream.
If you still need to save RAM, you can increase the buffer, or increase the file size limit not by 1 MB, but by 15, for example.
And please write the environment where this is used, the version of the framework, the OS.
const long mb = 1024 * 1024;
long lengthInMB = streamToConvert.Length / mb;
int imagebuffersize = streamToConvert.Length >= (mb * 15) ? (int)(lengthInMB * 2) : 0;
I originally included the buffer size because without it caused a severe memory leak in our application, causing our servers to crash.
The above code changes you suggested to increase the buffer/file size limit appear to be working! I need to do some more testing to confirm that it works for all scenarios but this looks a lot better performance for jpeg images.
Our C# application is hosted on a windows (2019 server) farm and it is written in .Net 8. Our servers have a limited RAM space of 32 GB and we do share the space with other applications.
Thank you @stanislav.popov for all your help and the timely responses!
I ended up changing the value from 0 (no limit) to 10000 mb. When the value is at 0 my application uses up to 25 GB of RAM which is unacceptable for my application. 10000 mb keeps the RAM around 2 GB and the jpeg to pdf conversion is still under a second which resolves my issue. Thank you again for your support!
const long mb = 1024 * 1024;
long lengthInMB = streamToConvert.Length / mb;
int imagebuffersize = streamToConvert.Length >= (mb * 15) ? (int)(lengthInMB * 2) : 10000;
Sets consent for sending user data to Google for online advertising purposes.
Sets consent for personalized advertising.
Cookie Notice
To provide you with the best experience, we use cookies for personalization, analytics, and ads. By using our site, you agree to our cookie policy.
More info
Enables storage, such as cookies, related to analytics.
Enables storage, such as cookies, related to advertising.
Sets consent for sending user data to Google for online advertising purposes.
Sets consent for personalized advertising.
Cookie Notice
To provide you with the best experience, we use cookies for personalization, analytics, and ads. By using our site, you agree to our cookie policy.
More info
Enables storage, such as cookies, related to analytics.
Enables storage, such as cookies, related to advertising.
Sets consent for sending user data to Google for online advertising purposes.