Member 13187373 Ответов: 1

Получение “недостаточной памяти для продолжения выполнения программы " при сохранении изображений tiff после поворота.


У меня есть 10 МБ+ Tiff-файлы, содержащие 50 страниц, и я хочу выполнить поворот всех страниц на 90 градусов только одним щелчком мыши, но после выполнения операций поворота для каждого кадра в цикле foreach и когда дело доходит до
Save(Encoder encoder)
нажмите здесь,
encoder.Save(temporaryStream); // this line is giving exception.


Здесь, Если я делаю поворот для 6 страниц tiff-изображений в этот раз, я не получаю никакого исключения, но при выполнении той же операции для 50 страниц в этот раз я получаю исключение.
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)


Может быть, я ошибаюсь здесь при сохранении изображений после поворота?

Любая помощь будет оценена по достоинству.

Что я уже пробовал:

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

фрагмент кода:

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);
  }

Member 13187373

Здесь я сохраняю все страницы в памяти и отправляю их в метод сохранения после поворота, но когда я пытаюсь сохранить каждую страницу в это время, я не получаю никаких исключений ,и поворот выполняется успешно ,но проблема с сохранением отдельных страниц заключается в том, что это слишком медленно(5 минут для 50 страниц).
Есть ли какой-то способ сохранить все сразу, а не отдельные, или есть какой-то способ сохранить эти файлы эффективно ?

1 Ответов

Рейтинг:
0

Richard MacCutchan

Ошибка вполне понятна, у вас закончилась память. Вам нужно будет изменить свой код так, чтобы он не хранил все страницы в памяти. Вы можете попробовать сохранить каждую страницу по мере ее обработки, чтобы уменьшить объем используемой памяти в любое время. Кроме того, я не уверен, почему ваш метод сохранения записывает данные во временный файл, а затем немедленно копирует их оттуда в постоянный. Почему бы просто не написать в постоянный файл в первую очередь?


Member 13187373

@Ричард MacCutchan ,
Я очень молод в обработке изображений.
Не могли бы вы предоставить мне изменения, которые требуются в методе сохранения, потому что из метода RotateImagePages я отправляю все повернутые кадры tiff в метод сохранения.
мы ценим вашу помощь.

Richard MacCutchan

Извините, я не знаю, какие изменения требуются. Вам нужно будет проверить документацию, чтобы увидеть, как вы можете сохранить каждую страницу во время ее обработки.

Member 13187373

@Ричард MacCutchan ,
Я попытался сохранить страницу eah, и теперь я не получаю исключения, но это занимает почти 5 минут, чтобы повернуть все 50 страниц, что все еще слишком медленно.
Нужно ли еще что-то делать для повышения эффективности?

Richard MacCutchan

На это невозможно ответить. Вам нужно будет сделать некоторые тесты инструментов, чтобы выяснить, какая часть программы занимает все время.