Методы удаления пустых (или почти пустых) страниц из файлов TIFF - PullRequest
1 голос
/ 19 апреля 2011

У меня есть что-то вроде 40 миллионов документов TIFF, все однобитные одностраничные дуплексы. Примерно в 40% случаев заднее изображение этих TIFF-файлов является «пустым», и я хотел бы удалить их перед загрузкой в ​​CMS, чтобы уменьшить требования к пространству.

Есть ли простой способ просмотреть содержимое данных каждой страницы и удалить его, если он падает ниже заданного порогового значения, скажем, 2% «черный»?

Я не разбираюсь в технологиях, но решение C #, вероятно, будет проще всего поддерживать. Проблема в том, что у меня нет опыта работы с изображениями, поэтому я не знаю, с чего начать.

Редактировать, чтобы добавить: Изображения - это старые сканы, поэтому они «грязные», так что это не является точной наукой. Порог должен быть установлен, чтобы избежать вероятности ложных срабатываний.

Ответы [ 3 ]

3 голосов
/ 19 апреля 2011

Вам, вероятно, следует:

  • открыть каждое изображение
  • перебирать его страницы (используя Bitmap.GetFrameCount / Bitmap.SelectActiveFrame методы)
  • бит доступа каждогостраница (с использованием метода Bitmap.LockBits)
  • анализ содержимого каждой страницы (простой цикл)
  • , если содержимое того стоит, скопировать данные в другое изображение (Bitmap.LockBits и цикл)

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

PS Я предполагаю, что все изображения могут быть успешно загружены в System.Drawing.Bitmap.

1 голос
/ 20 апреля 2011

Вы можете сделать что-то подобное с DotImage (отказ от ответственности, я работаю в Atalasoft и написал большинство базовых классов, которые вы будете использовать). Код для этого будет выглядеть примерно так:

public void RemoveBlankPages(Stream source stm)
{
    List<int> blanks = new List<int>();
    if (GetBlankPages(stm, blanks)) {
        // all pages blank - delete file?  Skip?  Your choice.
    }
    else {
        // memory stream is convenient - maybe a temp file instead?
        using (MemoryStream ostm = new MemoryStream()) {
            // pulls out all the blanks and writes to the temp stream
            stm.Seek(0, SeekOrigin.Begin);
            RemoveBlanks(blanks, stm, ostm);
            CopyStream(ostm, stm); // copies first stm to second, truncating at end
        }
    }
}

private bool GetBlankPages(Stream stm, List<int> blanks)
{
    TiffDecoder decoder = new TiffDecoder();
    ImageInfo info = decoder.GetImageInfo(stm);
    for (int i=0; i < info.FrameCount; i++) {
        try {
            stm.Seek(0, SeekOrigin.Begin);
            using (AtalaImage image = decoder.Read(stm, i, null)) {
                if (IsBlankPage(image)) blanks.Add(i);
            }
        }
        catch {
            // bad file - skip? could also try to remove the bad page:
            blanks.Add(i);
        }
    }
    return blanks.Count == info.FrameCount;
}

private bool IsBlankPage(AtalaImage image)
{
    // you might want to configure the command to do noise removal and black border
    // removal (or not) first.
    BlankPageDetectionCommand command = new BlankPageDetectionCommand();
    BlankPageDetectionResults results = command.Apply(image) as BlankPageDetectionResults;
    return results.IsImageBlank;
}

private void RemoveBlanks(List<int> blanks, Stream source, Stream dest)
{
    // blanks needs to be sorted low to high, which it will be if generated from
    // above
    TiffDocument doc = new TiffDocument(source);
    int totalRemoved = 0;
    foreach (int page in blanks) {
        doc.Pages.RemoveAt(page - totalRemoved);
        totalRemoved++;
    }
    doc.Save(dest);
}

Вы должны заметить, что обнаружение пустой страницы не так просто, как "все ли пиксели белые (-ish)?" так как сканирование вводит все виды интересных артефактов. Чтобы получить BlankPageDetectionCommand, вам потребуется пакет Document Imaging.

0 голосов
/ 22 апреля 2011

Вы заинтересованы в сокращении файлов или просто хотите, чтобы люди не тратили время на просмотр пустых страниц?Вы можете быстро и просто отредактировать файлы, чтобы избавиться от известных пустых страниц, просто установив в качестве второго IFD значение 0x00000000.Вот что я имею в виду - файлы TIFF имеют простой макет, если вы просто перемещаетесь по страницам:

Заголовок TIFF (4 байта) Первое смещение IFD (4 байта - обычно указывает на 0x00000008)

IFD:

Количество тегов (2 байта)

{отдельные теги TIFF} (12 байтов каждый)

Следующее смещение IFD (4 байта)

Просто установите «следующее смещение IFD» на значение 0x00000000, чтобы «отсоединить» страницы от текущей.

...