2014-12-09 2 views
1

Я пытаюсь использовать LibTiff.Net для разделения многостраничного изображения TIFF на одностраничные изображения TIFF.libtiff.net split multipage tiff в одностраничные изображения tiff

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

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

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

Возможно ли это с помощью LibTiff.Net?

ОБНОВЛЕНО @bobrovsky - спасибо за ваше предложение.

Вот что я пробовал. Я взял класс Copier из исходного кода для TiffCP, чтобы использовать его в моем проекте с нулевыми изменениями. Ниже приведен код, как я его использую. Когда этот код завершает выполнение, объекты MemoryStream, которые должны иметь весь одностраничный TIFF-образ внутри них, составляют ровно 1,282 байта. Кажется, что мне не хватает вызова функции, который заставляет данные изображения TIFF записываться в основное хранилище (в этом случае MemoryStream). Я включил вызов Flush(), чтобы попытаться исправить эту проблему, но это не повлияло. Кто-нибудь знает, что мне не хватает?

using (memoryStream) 
{ 
    memoryStream.Position = 0; 
    using (Tiff image = Tiff.ClientOpen("iqdoc", "r", memoryStream, new TiffStream())) 
    { 
     int totalPages = image.NumberOfDirectories(); 
     for (int i = 0; i < totalPages; i++) 
     { 
      image.SetDirectory((short)i); 
      using (var ms = new MemoryStream()) 
      using (Tiff page = Tiff.ClientOpen("page", "w", ms, new TiffStream())) 
      { 
       var c = new Copier(); 
       c.m_compression = c.m_defcompression; // THIS WAS MISSING 
       if (!c.Copy(image, page) || !page.WriteDirectory()) 
        throw new ApplicationException("Failed to extract page from document for presentation."); 

       FieldValue[] field = image.GetField(TiffTag.IMAGEWIDTH); 
       int width = field[0].ToInt(); 

       field = image.GetField(TiffTag.IMAGELENGTH); 
       int height = field[0].ToInt(); 

       page.Flush(); 

       pages.Add(new 
       { 
        Height = height, 
        Width = width, 
        PageBytes = Convert.ToBase64String(ms.ToArray()), 
       }); 

       c = null; 
      } 
     } 
    } 
} 

Спасибо!

ответ

1

Да, это возможно. TiffCP делает это.

Вы можете взять код TiffCP и адаптировать его под свои нужды (измените способ сохранения вывода).

Вы также можете придумать другие идеи и реализовать один из них.

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

EDIT:

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

К сожалению, Tiff закрывает поток памяти в нем Dispose и Close методов. Вы можете попробовать два подхода для решения проблемы:

  • Позвонить Tiff.WriteDirectory перед доступом к байтам в потоке памяти. Этот должен быть в порядке, но вы можете получить неполный TIFF в потоке.
  • Создайте свой собственный поток (на основе System.IO.MemoryStream), который перегружает метод Close с пустой реализацией и использует этот поток вместо MemoryStream. Доступ к байтам доступа в этом потоке после Tiff.
+0

спасибо за ваше предложение. Я обновил этот вопрос с более подробной информацией и новыми задачами. Дайте мне знать, если у вас есть какие-либо советы для меня. Еще раз спасибо! – Steve

+0

Спасибо за отзыв. Я более подробно рассмотрел код в TiffCP и то, как он использовал класс Copier, и понял, что я не устанавливаю значения по умолчанию одинаково. Я добавил недостающий код к моему вопросу, чтобы другие могли его увидеть. Могут быть другие значения по умолчанию, которые мне нужно предоставить, но пока мои тестовые изображения CCITT4 работают нормально. Вот код, который мне не хватало: c.m_compression = c.m_defcompression; // ЭТО БЫЛО ПРОПУСТИТЬ – Steve

Смежные вопросы