Откройте огромный TIF в .NET и скопируйте части на новое изображение
Я ищу библиотеку, которая может открывать и копировать разделы большого файла TIFF. Я просмотрел LibTiff.Net, который быстро открывает файл, но у него нет никаких функций для обрезки или копирования разделов изображения. Мое изображение составляет 100 000 х 100 000 пикселей вверх, а создание System.Drawing.Bitmap
этого размера приводит к сбою приложения, поэтому преобразование в Bitmap
не является вариантом.
Кто-нибудь может рекомендовать библиотеку .NET?
Ответы
Ответ 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" в цикле.