ImageSaveException: Image export failed

Here i want to perform Image rotation using batch file.
I am loading tiffImages from Stream and trying to save it in place only.
suppose total tiff image pages are 50, then I am sending every 5 pages for saving after rotation.
Here, for first 5 pages images are rotated and saved properly but when it goes for next 5 pages that time it is giving exception like Aspose.Imaging.CoreExceptions.ImageSaveException: ‘Image export failed.’ FrameworkException: Cannot parse file.

Type : Aspose.Imaging.CoreExceptions.ImageSaveException
Message : Image export failed.
HResult : 0x80131500
Source : Aspose.Imaging
**
Aspose.Imaging.Image.Save(Stream stream, ImageOptionsBase optionsBase, Rectangle boundsRectangle)

at Aspose.Imaging.Image.Save(Stream stream, ImageOptionsBase optionsBase)

Code snippet.

 //Load input Tiff image
     using (TiffImage tiffImage = (TiffImage)Image.Load(Stream))
     {
        var batchSize = 5;
        var frameCount = tiffImage.Frames.Length;  

        TiffOptions saveOptions = null;
        saveOptions = new TiffOptions(TiffExpectedFormat.TiffJpegRgb);

        for (var i = 0; i < frameCount; i += batchSize)
        {
           TiffFrame frame = tiffImage.Frames[i];

           tiffImage.ActiveFrame = tiffImage.Frames[i];

           //Set RGB color mode.
           saveOptions.Photometric = TiffPhotometrics.Rgb;
           

           int batchSizeCounter = i + batchSize >= frameCount ? frameCount - i : batchSize;
           int k = i;
           for (int j = 0; j < batchSizeCounter; j++)
           {
              tiffImage.Frames[k].Rotate(angleOfRotation);
           }
           k = 0;
		   tiffImage.Save(Stream,saveOptions);
         
        }
     }

Reason for using batch file: for large size of pages normal rotation and saving is taking more time which is not acceptable.

Is batch processing is possible in Aspose.Imaging?
If yes, then can you please suggest me the code changes using Aspose.Imaging ?

Can you please suggest about this approach is fine or not, if yes then how to overcome from this exception?

@ankitraman.

I have observed your requirements along with provision of using API in batch mode. We are investigating your requirements and have created a ticket with ID IMAGINGNET-3673 to investigate the requirement. We request for your patience and will try our best to give you some workable approach very soon after investigation.

@mudassir.fayyaz ,
Okay.
The reason for using Batch File only is if the frames size is large that time it is taking much time while saving the Images.

@ankitraman,

We are checking this on our end and will share the feedback with you as soon as it will be shared.

1 Like

@ankitraman,

We have internally investigated the possibilities in our issue tracking system. After investigating your sample code, we have following consideration :

  1. Batch processing could could be better accomplished using input - output streams.

     private static void batchPro(Stream input, Stream output, float angleOfRotation, int batchSize = 5)
     {
         Stopwatch sw = new Stopwatch();
    
         sw.Start();
    
         if(batchSize==0)
         {
             throw new ArgumentOutOfRangeException("Batch size should be positive");
         }
    
         //Load input Tiff image           
         using (TiffImage tiffImage = (TiffImage)Image.Load(input))
         {
             TiffImage outputImage = null;
             try
             {
                 var frameCount = tiffImage.Frames.Length;
                 TiffOptions saveOptions = new TiffOptions(TiffExpectedFormat.TiffJpegRgb);
    
                 for (var i = 0; i < frameCount; i += batchSize)
                 {
                     Console.WriteLine("Processed batches " + i);
                     int batchSizeCounter = i + batchSize >= frameCount ? frameCount - i : batchSize;
    
                     for (int j = 0, k = i; j < batchSizeCounter; j++, k++)
                     {
                         Console.WriteLine("Processed frames " + k);
                         tiffImage.Frames[k].Rotate(angleOfRotation, true, Color.White);
                     }
    
                     for (int j = 0, k = i; j < batchSizeCounter; j++, k++)
                     {
                         if (outputImage == null)
                         {
                             saveOptions.Source = new StreamSource(output);
                             outputImage = (TiffImage)Image.Create(saveOptions, tiffImage.Width, tiffImage.Height);
                             outputImage.ReplaceFrame(k, TiffFrame.CopyFrame(tiffImage.Frames[k]));
                             k++;
                         }
    
                         outputImage.AddFrame(TiffFrame.CopyFrame(tiffImage.Frames[k]));
                     }
                 }
    
                 outputImage.Save(output);
             }
             finally
             {
                 if(outputImage!=null)
                 {
                     outputImage.Dispose();
                 }                    
             }
         }
    
         sw.Stop();
         Console.WriteLine("Elapsed for batch ={0}", sw.Elapsed);
     }
    

    In common cases it works slower than batchless processing

    private static void noBatchPro(Stream input, Stream output, float angleOfRotation, int bufferSizeHint)
    {
    Stopwatch sw = new Stopwatch();

         sw.Start();
    
         int batchSize = 1;
    
         //Load input Tiff image           
         using (TiffImage tiffImage = (TiffImage)Image.Load(input, new LoadOptions { BufferSizeHint = bufferSizeHint } ))
         {
             tiffImage.CacheData();
    
             var frameCount = tiffImage.Frames.Length;
    
             TiffOptions saveOptions = new TiffOptions(TiffExpectedFormat.TiffJpegRgb);
    
             for (var i = 0; i < frameCount; i += batchSize)
             {
                 Console.WriteLine("Processed batches " + i);
                 int batchSizeCounter = i + batchSize >= frameCount ? frameCount - i : batchSize;
    
                 for (int j = 0, k = i; j < batchSizeCounter; j++, k++)
                 {
                     Console.WriteLine("Processed frames " + k);
                     tiffImage.Frames[k].Rotate(angleOfRotation, true, Color.White);
                 }
    
             }
    
             tiffImage.Save(output);
         }
    
         sw.Stop();
         if(bufferSizeHint > 0)
         {
             Console.WriteLine("Buffer limit {0} Mb", bufferSizeHint);
         }
    
         Console.WriteLine("Elapsed for no batch ={0}", sw.Elapsed );
     }
    

Please note that usage of Buffer size hint could be beneficial in some scenarios.

The issues you have found earlier (filed as IMAGINGNET-3673) have been fixed in this update.