Click here to Skip to main content
15,881,810 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more: , +
I have 10MB+ Tiff files having 50 pages, and I want to perform rotation of all the pages by 90 degree at one click only, but after performing the rotation operations for each frames in foreach loop and when it comes to the
C#
Save(Encoder encoder)
then here,
C#
encoder.Save(temporaryStream); // this line is giving exception.


Here, If I am doing rotation for 6 pages tiff images that time I am not getting any exception but when doing the same operation for 50 pages that time I am getting exception.
C#
Type :	System.OutOfMemoryException
Message :	Insufficient memory to continue the execution of the program.
HResult :	0x8007000E
Source :	PresentationCore
   at System.Windows.Media.Imaging.BitmapEncoder.SaveFrame(SafeMILHandle frameEncodeHandle, SafeMILHandle encoderOptions, BitmapFrame frame)
   at System.Windows.Media.Imaging.BitmapEncoder.Save(Stream stream)


Am I wrong here while saving the images after rotation?

Any help is appreciated.

What I have tried:

C#
RotateImagePages(IEnumerable<int> pageNumbers, Degrees degree) //here, pageNumbers is total number of pages i.e 50,degree= 90.

code snippet:

C#
private void RotateImagePages(IEnumerable<int> pageNumbers, Degrees degree)
  {
     // create the encoder
     BitmapEncoder encoder = BitmapEncoder.Create(Decoder.CodecInfo.ContainerFormat);

     // copy the destination frames
     foreach (BitmapFrame frame in Decoder.Frames)
        encoder.Frames.Add(frame);

     double angleOfRotation = (double)degree;

		foreach (var pageNumber in pageNumbers)
         {
            BitmapFrame oldFrame = encoder.Frames[pageNumber - 1];

            // Create the TransformedBitmap to use as the Image source.
            TransformedBitmap tb = new TransformedBitmap();
            //BitmapImage bi = new BitmapImage();
            
            // Properties must be set between BeginInit and EndInit calls.
            tb.BeginInit();

            tb.Source = new CachedBitmap(oldFrame, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
            RotateTransform transform = new RotateTransform(angleOfRotation);
            tb.Transform = transform;

            tb.EndInit();

            encoder.Frames.RemoveAt(pageNumber - 1);
            encoder.Frames.Insert(pageNumber - 1, BitmapFrame.Create(tb));
         }
		 Save(encoder);
	}
private void Save(BitmapEncoder encoder)
	{
     // save to a temporary stream
     string tempFileName = Path.GetTempFileName();

     try
     {
        using (FileStream temporaryStream = new FileStream(tempFileName, FileMode.Open))
        {
           if (encoder.Frames.Count > 0)
              encoder.Save(temporaryStream);

           // write back out to permanent stream
           if (Stream.CanWrite && Stream.CanSeek)
              CopyStream(temporaryStream, Stream);
           else
              throw new UnauthorizedAccessException();
        }
     }
     finally
     {
        // Delete the temporary file
        File.Delete(tempFileName);
     }
  }
  protected static void CopyStream(Stream input, Stream output)
  {
     input.Seek(0, SeekOrigin.Begin);
     output.Seek(0, SeekOrigin.Begin);
     output.SetLength(0);

     byte[] buffer = new byte[4096];
     int read;

     while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
        output.Write(buffer, 0, read);

     output.Seek(0, SeekOrigin.Begin);
  }
Posted
Updated 1-Jan-20 6:33am
Comments
Member 13187373 3-Jan-20 2:52am    
Here, I am keeping all the pages in memory and sending them to Save method after rotation, but When I am trying to save each page that time I am not getting any exception and rotation is performed successfully ,but the problem with individual page saving is ,it is far too slow(5 minute for 50 pages.).
Is there any way to save all at once not individual or is there any way to save these files efficiently ?

1 solution

The error is quite clear, you have run out of memory. You will need to modify your code so that it does not keep all the pages in memory. You could try saving each page as you process it so that it reduces the amount of memory in use at any time. Also, I am not sure why your Save method writes the data to a temporary file, and then immediately copies it from there to a permanent one. Why not just write to the permanent file in the first place?
 
Share this answer
 
Comments
Member 13187373 1-Jan-20 12:53pm    
@Richard MacCutchan ,
I am very young in Image-processing.
Can you please provide me the changes which is required in Save method because from RotateImagePages method I am sending all the rotated tiff Frames to the Save method.
your help is appreciated.
Richard MacCutchan 1-Jan-20 13:01pm    
Sorry, I do not know what changes are required. You will need to check the documentation to see how you can save each page as you process it.
Member 13187373 2-Jan-20 11:49am    
@Richard MacCutchan ,
I tried saving eah page and now I am not getting exception but it is taking almost 5 minutes to rotate the all the 50 pages which is still far too slow.
Is there any more need to do for efficiency?
Richard MacCutchan 2-Jan-20 12:22pm    
That is impossible to answer. You will need to do some instrumentation tests to find out which part of the program takes all the time.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900