Откройте огромный TIF в .NET и скопируйте части в новое изображение - PullRequest
14 голосов
/ 25 января 2012

Я ищу библиотеку, которая может открывать и копировать разделы большого файла TIFF. Я посмотрел на LibTiff.Net , который очень быстро открывает файл, но у него нет никаких функций для обрезки или копирования участков изображения. Мое изображение имеет размер 100 000 x 100 000 пикселей и выше, и создание System.Drawing.Bitmap такого размера приводит к сбою приложения, поэтому преобразование в Bitmap сначала невозможно.

Кто-нибудь может порекомендовать библиотеку .NET?

Ответы [ 4 ]

6 голосов
/ 26 января 2012

Если размер вашего файла меньше 4 ГБ на диске , чем я рекомендую вам еще раз взглянуть на LibTiff.Net. Даже с такими большими изображениями у вас есть несколько вариантов.

Прежде всего, проверьте, является ли ваше изображение мозаичным или полосатым. Tiff.IsTiled метод даст вам ответ.

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

Если ваши изображения обрезаны, вы можете использовать методы ReadScanline и ReadEncodedStrip, чтобы прочитать их.

Если вы хотите использовать что-то, что ожидает System.Drawing.Bitmap, попробуйте использовать ReadRGBATile или ReadRGBAStrip. Эти методы могут быть использованы для создания растровых изображений из частей вашего изображения. Для этого нет примера, но Преобразование цветного TIFF в 32-разрядный System.Drawing.Bitmap должно предоставить вам почти всю необходимую информацию о том, как преобразовать плитку или полосу изображения в растровое изображение. *

EDIT:

В LibTiff.Net 2.4.508 добавлена ​​поддержка BigTiff, поэтому также поддерживаются файлы размером более 4 ГБ.

5 голосов
/ 25 января 2012

Ваше изображение должно быть в формате BigTIFF , так как обычный TIFF не может быть больше 4 ГБ.

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

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

0 голосов
/ 17 апреля 2017

Как упоминал Бобровский, вы должны проверить, мозаичное изображение вашего файла или нет.Далее я представил код фрагмента для чтения потока и обрезки верхней левой части изображения.

using (Tiff input = Tiff.Open(@"imageFile.tif", "r"))
        {
            // get properties to use in writing output image file
            int width = input.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
            int height = input.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
            int samplesPerPixel = input.GetField(TiffTag.SAMPLESPERPIXEL)[0].ToInt();
            int bitsPerSample = input.GetField(TiffTag.BITSPERSAMPLE)[0].ToInt();
            int photo = input.GetField(TiffTag.PHOTOMETRIC)[0].ToInt();

            int scanlineSize = input.ScanlineSize();    
            byte[][] buffer = new byte[height][]; 
            for (int i = 0; i < height; ++i)
            {
                buffer[i] = new byte[scanlineSize];
                input.ReadScanline(buffer[i], i);
            }



            using (Tiff output = Tiff.Open("splitedImage.tif", "w"))
            {
                output.SetField(TiffTag.SAMPLESPERPIXEL, samplesPerPixel);
                output.SetField(TiffTag.IMAGEWIDTH, width/2);
                output.SetField(TiffTag.IMAGELENGTH, height/2);
                output.SetField(TiffTag.BITSPERSAMPLE, bitsPerSample);
                output.SetField(TiffTag.ROWSPERSTRIP, output.DefaultStripSize(0));
                output.SetField(TiffTag.PHOTOMETRIC, photo);
                output.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);


                int c = 0;
                byte[][] holder = new byte[height][];

                for (int i = height/2; i < height; i++)
                //for (int j = 0; j < height/2 ; j++)
                {
                    holder[i] = buffer[i].Skip(buffer[i].Length/2).ToArray();

                    output.WriteScanline(holder[i], c);
                    c++;
                }
            }
        }

        System.Diagnostics.Process.Start("splitedImage.tif");

Для других частей изображения вы можете изменить диапазон «i"в течение цикла.

0 голосов
/ 06 февраля 2012

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

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

(отказ от ответственности, я работаю в Atalasoft и написал этот интерфейс и реализовал его в декодере TIFF)

...