Разделение многостраничных tiff со сжатием CCITT T.6 очень медленное

Мне нужно разделить многокадровые файлы tiff и использовать следующий метод:

public static Image[] GetFrames(Image sourceImage)
{
    Guid objGuid = sourceImage.FrameDimensionsList[0];
    FrameDimension objDimension = new FrameDimension(objGuid);
    int frameCount = sourceImage.GetFrameCount(objDimension);
    Image[] images = new Image[frameCount];
    for (int i = 0; i < frameCount; i++)
    {
        MemoryStream ms = new MemoryStream();
        sourceImage.SelectActiveFrame(objDimension, i);
        sourceImage.Save(ms, ImageFormat.Tiff);
        images[i] = Image.FromStream(ms);
    }
    return images;
}

Это работает нормально, но если исходное изображение было закодировано с использованием сжатия CCITT T.6, разделение файла из 20 кадров занимает до 15 секунд на моем процессоре 2,5 ГГц. (Одно ядро ​​находится на 100% в процессе)

При последующем сохранении изображений в один файл с использованием стандартного сжатия (LZW) время разделения LZW-файла составляет менее 1 секунды.

Сохранение со сжатием CCITT также занимает очень много времени.

Есть ли способ ускорить процесс?

редактировать:

Я измерил время выполнения:

        sourceImage.SelectActiveFrame(objDimension, i);
        sourceImage.Save(ms, ImageFormat.Tiff);

На каждый из этих двух вызовов приходится около 50% общего времени обработки. Использование одного MemoryStream с начальной емкостью, достаточной для всех изображений, не приводит к ощутимому приросту скорости. Метод Image.FromStream практически не требует времени обработки.

Мне нужны отдельные кадры, потому что мне нужно их обработать (устранить перекос, повернуть и т. д.).

Если есть совсем другой метод, чем мой, буду рад его услышать.


person Alex AIT    schedule 08.05.2010    source источник
comment
Вы используете 64-битную операционную систему? Что делает индикатор жесткого диска во время выполнения?   -  person Hans Passant    schedule 09.05.2010
comment
Я использую Windows 7 x64. Жесткий диск почти не используется (также пробовал образ из MemoryStream, тоже медленный). Одно ядро ​​процессора во время процесса загружено на 100%. Переключение программы на x86 приводит к тому, что функция выполняется немного дольше.   -  person Alex AIT    schedule 09.05.2010


Ответы (2)


Первое, что нужно сделать в вашей ситуации, это измерить.

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

При этом вот несколько неосведомленных советов:

  1. Я предполагаю, что эти изображения довольно большие и все имеют одинаковые размеры, поэтому вместо создания нового потока памяти для каждого изображения и его динамического увеличения, почему бы не создать MemoryStream, который будет достаточно большим, а затем использовать что для всех из них это уменьшит количество мусора, создаваемого методом, и уменьшит количество общих распределений.
  2. Вы сказали, что используете одно из своих ядер на 100%, поэтому нам, вероятно, следует попытаться использовать более одного ядра. Вы можете попробовать разделить работу на несколько потоков. Возможно, один поток сохранит кадры в MemoryStreams, а другой загрузит их в новые изображения, они могут обмениваться данными через рабочую очередь.
  3. Вы говорите, что разбиваете его, а потом говорите, что сохраняете его снова, может быть, вы можете просто сохранить напрямую, вместо того, чтобы проходить через другой объект изображения в середине.
person luke    schedule 09.05.2010
comment
Я добавил меры и более подробную информацию в свой первоначальный пост. - person Alex AIT; 10.05.2010

Кажется, это проблема с GDI+ в Windows 7.

Я запустил пример программы на гораздо более медленной машине с Windows XP и получил гораздо лучшую производительность на сжатых изображениях, чем на Windows 7 (примерно в 2-3 раза быстрее).

person Alex AIT    schedule 18.05.2010