2015-06-25 4 views
-1

Как я могу обрезать большой JPG и извлечь небольшую его часть? Проблема в том, что основные JPG такие большие, и я не могу загрузить их все в памяти. Я использовал convert.exe из ImageMagick, но он не работает должным образом во всех версиях окон, и я предпочитаю какой-то C# метод вместо автономного exe.Обрезка JPG без загрузки всего его в память

+0

Что вы пытается, показать нам свою вопрос, пробовал использовать filestream? то вы передаете его на диск, а не в память, он будет намного медленнее, чем просто нажимать его на память и обрабатывать там. Размер в памяти должен быть примерно шириной * height * 4channels * 8bit = общие бит в памяти для растрового изображения. изображение 41mp (lumia 1020) должно быть около 150 МБ в памяти, что вполне приемлемо, и я думаю, что это код для обрезки, который вы пытались использовать для хранения свиней. –

+0

Это для мобильного телефона для Windows 8? какова оценка размера изображения? – n00b

ответ

0

Я нашел решение командной строки, которое не зависит от внешних библиотек, jpegtran.

Вы можете jpegtran.exe рядом с вашим основным ехе и вызвать его с этими параметрами:

jpegtran -crop WxH+X+Y input_file output_file 

Скачать jpegtran здесь: http://jpegclub.org/jpegtran/

1

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

Если вы решили не загружать в память, то у вас есть много файлов, которые делают ваш декодер менее интенсивным в памяти, но больше интенсивнее ввода-вывода.

проект NanoJpeg хорошее начало https://github.com/Deathspike/NanoJPEG.NET/blob/master/NanoJPEG.cs

+0

Декодер vips jpeg будет распаковываться по требованию, поэтому, если вам нужен только фрагмент в верхней части файла, он будет декодировать только верхнюю часть файла. Если вы попросите кусок внизу, он распакует все это, но сохранит только нижнюю часть в памяти, он отбросит нежелательную часть. – user894763

3

Есть несколько возможностей. Вы можете использовать stream, который является частью ImageMagick, или vips. Давайте сначала сделаем stream.

Я могу сделать большой (10,000x5,000) JPEG, как это:

convert -size 10000x5000 xc:blue BigBoy.jpg 

затем использовать stream, как это, чтобы извлечь кусок из 1,000x1,000 смещение 8000 + 50

stream -extract 1000x1000+8000+50 BigBoy.jpg extract.rgb 

и файл extraact.rgb - 3000000 байт, то есть 1,000x1,000 при 3 байтах/пиксель.

Если бы я сделать это с time -l вы можете увидеть резидентного набора мало, несмотря на большое изображение

/usr/bin/time -l stream -extract 1000x1000+8000+50 BigBoy.jpg extract.rgb 
     0.81 real   0.79 user   0.01 sys 
    2924544 maximum resident set size  <----- 2MB RAM **** 
     0 average shared memory size 
     0 average unshared data size 
     0 average unshared stack size 
     796 page reclaims 

Вы можете конвертировать, что extract.rgb в JPEG с convert

convert -size 1000x1000 -depth 8 extract.rgb chunk.jpg 

Я не эксперт на vips, но у вас может быть некоторый успех с этой командой, которая также показывает использование пиковой памяти с флагом --vips-leak в конце

vips extract_area BigBoy.jpg SmallBoy.jpg 8000 50 1000 1000 --vips-leak 
memory: high-water mark 8.72 MB 
+0

Есть ли. Net/C# порт ImageMagic или Vips? – n00b

+0

Существует реализация .Net, поддерживаемая @dlemstra на SO, которая может консультироваться далее ... http://magick.codeplex.com –

+0

Или я полагаю, что C# должен иметь что-то вроде 'system()' функция для нереста программ командной строки ... –

Смежные вопросы