Как обрезать огромное изображение

Мне нужно обрабатывать большие изображения (20 000 x 20 000 пикселей) на C#. Открытие этих изображений напрямую не подходит из-за ограничений памяти, но я хочу разделить изображение на более мелкие части (обрезать). Я искал стороннюю библиотеку, которая могла бы помочь, но пока безрезультатно. Я пробовал FreeImage и ImageMagick, но они не могут открыть изображение размером 20 000x20x000 пикселей. Как я могу этого добиться?


person Community    schedule 19.06.2009    source источник
comment
В каком формате картинка? В таких форматах, как растровое изображение, вы можете просто использовать файл io напрямую. Если вы хотите использовать GDI или что-то еще, вы должны преобразовать отдельные фрагменты в поток, а затем загрузить его в изображение). Такие форматы, как PNG, потребуют от вас более глубокого изучения, изучения того, как файлы PNG разбиты на блоки, и работы с ними напрямую.   -  person Brian    schedule 19.06.2009


Ответы (5)


Мой текущий проект на работе состоит из программы просмотра/анализа изображений, способной загружать изображения размером более 16 ГБ. Вы должны использовать ручной файловый ввод-вывод, извлекать информацию из заголовка и создавать свои субизображения по запросу (или, если вы обрабатываете изображение, вы можете создать одну плитку и обработать ее на месте). Очень немногие библиотеки дадут вам возможность загружать/изменять изображения 20k на 20k (1,2 ГБ при 24bpp), а те, которые это делают, редко делают это с чем-то, напоминающим производительность (если это вызывает беспокойство).

person Ron Warholic    schedule 19.06.2009
comment
16gb+ изображения? Круто, а откуда они? - person Allen Rice; 19.06.2009
comment
Мы работаем с радиолокационными изображениями с синтезированной апертурой, которые могут генерировать очень большие изображения :P - person Ron Warholic; 19.06.2009
comment
ха, это круто (в Google есть несколько отличных изображений), какие языки вы используете. Мне любопытно, сможет ли C# справиться с такой нагрузкой. - person Allen Rice; 19.06.2009
comment
Мы используем C# для отображения всего и P/Invoke для C++ с OpenGL, чтобы сделать тяжелую работу. Это работает на удивление хорошо :P - person Ron Warholic; 19.06.2009

Не знаю, поможет ли это, но вот статья на обработка изображений с помощью лямбда-выражений C#.

person jjclarkson    schedule 19.06.2009

Я не знаю ни одной существующей библиотеки для этого.

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

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

person Judah Gabriel Himango    schedule 05.12.2012

Я бы сделал это с ImageMagick. Существует довольно надежный .NET API, и, как правило, это лучший способ такой обработки изображений.

Посмотрите под .NET, часть пути вниз по странице.

http://www.imagemagick.org/script/api.php

Вот информация о том, как работает кадрирование в ImageMagick, для версии командной строки.

http://www.imagemagick.org/Usage/crop/#crop

person Matthew Kennedy    schedule 06.12.2012

Вы можете использовать встроенные библиотеки .Net.

Использовать

sourceBitmap = (Bitmap)Image.FromStream(sourceFileStream, false, false);

Это предотвратит кэширование данных изображения в памяти. Вы можете создать новое целевое растровое изображение, чтобы нарисовать подраздел этого массивного изображения:

var output = new Bitmap(outputWidth, outputHeight);
var outputGraphics = Graphics.FromImage(output);

outputGraphics.DrawImage(sourceBitmap, destRect, srcRect, GraphicsUnit.Pixel);

using (var fs = File.OpenWrite(outputFilePath))
{
    output.Save(fs, System.Drawing.Imaging.ImageFormat.Png);
}

Где destRect может быть полным размером выходного изображения или меньшей областью.

person Todd    schedule 22.11.2017