Подтвердить что ты не робот

Откройте огромный TIF в .NET и скопируйте части на новое изображение

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

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

4b9b3361

Ответ 1

Если ваш файл меньше 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 ГБ также поддерживаются.

Ответ 2

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

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

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

Ответ 3

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

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

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

Ответ 4

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

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" в цикле.