У меня есть файлы Tiff размером 10 МБ + с 50 страницами, и я хочу выполнить поворот всех страниц на 90 градусов одним щелчком мыши, но после выполнения операций поворота для каждого кадра и когда дело доходит до
Save(Encoder encoder)
тогда здесь
encoder.Save(temporaryStream); // this line is taking more time(almost 5-6 seconds for each page).
На самом деле, когда я отлаживал метод Save, я понял, что для каждой страницы требуется почти 5-6 секунд, поэтому для всех 50 страниц это занимает почти 5-6 минут на сохранение после ротации, этого времени достаточно для всего 50 страниц.
Ниже мой фрагмент кода:
/// <summary>
/// An object for thread-safe synchronization.
/// </summary>
internal object SyncRoot { get { return _guardedState; } }
private BitmapDecoder _p_decoder;
/// <summary>
/// The bitmap decoder. Created on demand
/// </summary>
internal BitmapDecoder Decoder
{
get
{
if (_p_decoder == null)
_p_decoder = CreateDecoder();
return _p_decoder;
}
set
{
_p_decoder = value;
// page count needs recalculating
_p_pageCount = UncalculatedPageCount;
}
}
/// <summary>
/// Whether or not the object has been disposed.
/// </summary>
protected bool IsDisposed
{
get
{
lock (_guardedState)
{
return _guardedState.IsDisposed;
}
}
private set
{
lock (_guardedState)
{
_guardedState.IsDisposed = value;
}
}
}
/// <summary>
/// Rotate all pages in the stream by the given amount
/// </summary>
/// <param name="pageNumbers">The number of the pages to be rotated</param>
/// <param name="rotationOperation">The type of rotation to perform</param>
public void RotateAllPages(IEnumerable<int> pageNumbers, RotationDegrees rotationOperation)
{
lock (SyncRoot)
{
foreach (var pageNumber in pageNumbers)
{
if (Disposed)
throw new ObjectDisposedException(GetType().Name);
if (!PageManipulationSupported) throw new NotSupportedException();
// sanity check
if ((pageNumber < 1) || pageNumber > PageCount)
throw new ArgumentOutOfRangeException("Page out of range: " + pageNumber, "pageNumber");
RotatePage(pageNumber, rotationOperation);
}
}
}
/// <summary>
/// Rotates a page in the stream by the given number of degrees.
/// </summary>
/// <param name="pageNumber">The number of the page to be rotated.</param>
/// <param name="rotationOperation">The type of rotation to perform.</param>
internal override void RotatePage(int pageNumber, RotationDegrees rotationOperation)
{
if (_mimeType != MimeTypes.Image.Tiff)
{
RotatePages(pageNumber, rotationOperation);
}
// Flush the contents
Stream.Flush();
RecreateState();
}
private void RotatePages(int pageNumber, RotationDegrees rotationOperation)
{
EnsureNotDisposed();
// 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)rotationOperation;
BitmapFrame oldFrame = encoder.Frames[pageNumber - 1];
// Create the TransformedBitmap to use as the Image source.
TransformedBitmap tb = new TransformedBitmap();
// Properties must be set between BeginInit and EndInit calls.
tb.BeginInit();
tb.Source = new CachedBitmap(oldFrame, BitmapCreateOptions.None, BitmapCacheOption.None);
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);
}
/// <summary>
/// Saves the contents of a bitmap encoder to <see cref="Stream"/>.
/// </summary>
/// <param name="encoder">
/// The encoder from which to obtain the data to save.
/// </param>
private void Save(BitmapEncoder encoder)
{
// save to a temporary stream
string tempFileName = Path.GetTempFileName();
try
{
using (FileStream temporaryStream = new FileStream(tempFileName, FileMode.OpenOrCreate))
{
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);
}
}
/// <summary>
/// Recreates the core's internal state to avoid cached stale data
/// being used.
/// </summary>
protected override void RecreateState()
{
// clear the decoder cache
Decoder = null;
}
/// <summary>
/// method for copying streams
/// </summary>
/// <param name="input">The source stream</param>
/// <param name="output">The destination stream</param>
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);
}
Пожалуйста, помогите исправить неисправный область в коде. Любое предложение приветствуется.