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
Save(Encoder encoder)
then here,
encoder.Save(temporaryStream);
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.
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:
RotateImagePages(IEnumerable<int> pageNumbers, Degrees degree)
code snippet:
private void RotateImagePages(IEnumerable<int> pageNumbers, Degrees degree)
{
BitmapEncoder encoder = BitmapEncoder.Create(Decoder.CodecInfo.ContainerFormat);
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];
TransformedBitmap tb = new TransformedBitmap();
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)
{
string tempFileName = Path.GetTempFileName();
try
{
using (FileStream temporaryStream = new FileStream(tempFileName, FileMode.Open))
{
if (encoder.Frames.Count > 0)
encoder.Save(temporaryStream);
if (Stream.CanWrite && Stream.CanSeek)
CopyStream(temporaryStream, Stream);
else
throw new UnauthorizedAccessException();
}
}
finally
{
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);
}