2015-05-08 6 views
0

Мне нужно изменить размер огромных (до 30000x30000) файлов JPEG без использования ОЗУ, скорость не имеет значения, есть ли способ сделать это? Я пробовал разные библиотеки (родной и другие), но они используют всю бесплатную оперативную память и сбой с ошибками типа «Недостаточно памяти» или «Недостаточно памяти для обработки этой команды». Я даже попробовал утилиту командной строки imagemagick, но она также использует гигабайты памяти.Изменение размера огромного jpeg без памяти

+1

@KenWhite Нет. Это неправильно. Вы можете обрабатывать изображение по частям. Вам не нужно загружать все изображение в память. –

+1

@ KenWhite Вы знаете, что я говорю, это правда. Давайте сосредоточимся на концепциях. –

+1

@Alex Проблема с вашим вопросом заключается в том, что вы, кажется, просите рекомендации библиотеки, которые не соответствуют теме. Вы спрашиваете, возможно ли это. Да, это возможно. Либо вам нужно найти библиотеку, либо самостоятельно обработать изображение. –

ответ

2

Предлагаю взглянуть на vips. Документировано here.

Я могу создать 10000x10000 образ шума, как это с ImageMagick

convert -size 10000x10000! xc:gray50 +noise poisson image.jpg 

и проверить это правильный размер, как это:

identify image.jpg 
image.jpg JPEG 10000x10000 10000x10000+0+0 8-bit sRGB 154.9MB 0.000u 

теперь я могу использовать vips, чтобы изменить размер 10000x10000 изображения до 2500x2500, как этот

time vipsthumbnail image.jpg -s 2500 -o small.jpg --vips-leak 
memory: high-water mark 20.48 MB 

real 0m1.974s 
user 0m2.158s 
sys  0m0.096s 

Обратите внимание на использование памяти достиг только 20MB

Проверить результат, как это с ImageMagick

identify result.jpg 
result.jpg JPEG 2500x2500 2500x2500+0+0 8-bit sRGB 1.33MB 0.000u 0:00.000 

Посмотрите на Техническую ноту тоже относительно производительности и памяти - here.

Вы также можете позвонить по телефону от C, а также к командной строке.

+1

Привет, я поддерживаю vips. Я бы использовал 'vipsthumbnail', а не' im_resize_linear', качество намного выше, он передает изображение, и он достаточно умен, чтобы использовать такие вещи, как libjpeg shrink-on-load, поэтому он намного быстрее. Try: '$ время vipsthumbnail big.jpg -s 2500 -o small.jpg --vips утечек памяти: знак высокой воды 29,93 MB реального \t 0m2.362s пользователь \t 0m2.873s SYS \t 0m0.082s ' – user894763

+0

О, отлично! Большое спасибо за ваш вклад - я обновлю свой ответ. –

2

Вы можете сделать это с помощью imagemagick, если вы включите libjpeg shrink-on-load. Попытайтесь:

$ identify big.jpg 
big.jpg JPEG 30000x30000 30000x30000+0+0 8-bit sRGB 128MB 0.000u 0:00.000 
$ time convert -define jpeg:size=2500x2500 big.jpg -resize 2500x2500 small.jpg 
real 0m3.169s 
user 0m2.999s 
sys 0m0.159s 
peak mem: 170MB 

Как это работает: libjpeg имеет отличную функцию усадки при загрузке. Когда вы открываете изображение, вы можете попросить библиотеку уменьшить размер x2, x4 или x8 во время процесса загрузки - тогда библиотека просто расшифровывает часть каждого блока DCT.

Однако эта функция должна быть включена, когда изображение открыто, вы не можете установить его позже. Поэтому convert нуждается в подсказке, что, когда он открывается big.jpg, ему нужно только получить изображение размером не менее 2500x2500 (ваш целевой размер). Теперь все -resize сокращает изображение размером 3800x3800 пикселей до 2500x2500, что довольно просто. Вам понадобится только 1/64-й процессор и память.

Как @ наценки Setchell сказанное выше, vipsthumbnail еще быстрее:

$ time vipsthumbnail big.jpg -s 2500 -o small.jpg --vips-leak 
memory: high-water mark 29.93 MB 
real 0m2.362s 
user 0m2.873s 
sys 0m0.082s 

Хотя убыстрение не очень драматично, так как обе системы действительно только изменение размера 3800 -> 2500.

Если вы попробовать TIF вместо этого, вы увидите большую разницу, так как нет термоусадочных под нагрузку трюка вы можете использовать:

$ identify 360mp.tif 
360mp.tif TIFF 18000x18000 18000x18000+0+0 8-bit sRGB 972MB 0.000u 0:00.000 
$ time convert 360mp.tif -resize 2500 x.tif 
peak mem: 2.8 GB 
real 0m8.397s 
user 0m25.508s 
sys 0m1.648s 
$ time vipsthumbnail 360mp.tif -o x.tif -s 2500 --vips-leak 
memory: high-water mark 122.08 MB 
real 0m2.583s 
user 0m9.012s 
sys 0m0.308s 

Теперь vipsthumbnail является Abou t 4x быстрее и требует только 1/20-й памяти.

1

Со встроенной поддержкой Delphi Jpeg вы можете загружать большое JPEG-изображение, переустановленное на меньший размер, при загрузке без чрезмерного использования ОЗУ.

Jpeg изображения Масштаб свойство может иметь следующие значения jsFullSize, jsHalf, jsQuarter, jsEighth

procedure ScaleJpg(const Source, Dest: string); 
var 
    SourceImg, DestImg: TJPEGImage; 
    Bmp: TBitmap; 
begin 
    Bmp := TBitmap.Create; 
    try 
    SourceImg := TJPEGImage.Create; 
    try 
     SourceImg.Scale := jsEighth; 
     SourceImg.LoadFromFile(Source); 
     Bmp.Width := SourceImg.Width; 
     Bmp.Height := SourceImg.Height; 
     Bmp.Canvas.Draw(0, 0, SourceImg); 
    finally 
     SourceImg.Free; 
    end; 
    DestImg := TJPEGImage.Create; 
    try 
     DestImg := TJPEGImage.Create; 
     DestImg.Assign(Bmp); 
     DestImg.SaveToFile(Dest); 
    finally 
     DestImg.Free; 
    end; 
    finally 
    Bmp.Free; 
    end; 
end; 

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

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