Получите лимит в 2 ГБ при создании PDF-файлов с помощью ImageMagick


19

Я использую convertдля создания PDF-файла из примерно 2000 изображений:

convert 0001.miff 0002.miff ... 2000.miff -compress jpeg -quality 80 out.pdf

Процесс заканчивается воспроизводимым, когда выходной файл достиг 2 ^ 31-1 байт (2 ГБ -1) с сообщением

convert: unknown `out.pdf'.

Спецификация файла PDF допускает ≈10 ГБ . Я пытался получить больше информации -debug all, но не нашел ничего полезного в выводе журнала. Файловая система ext3, которая допускает файлы по крайней мере до 16 ГиБ (может быть больше) . Что касается ulimit, file sizeесть unlimited. /etc/security/limits.confсодержит только закомментированные строки. Что еще может вызвать это и как я могу увеличить лимит?

Версия ImageMagick: 6.4.3 2016-08-05 Q16
Распространение OpenMP : SLES 11.4 (i586)


4
Возможно ли вам создать два файла с половиной изображений (или любым другим, который вам больше подходит), а затем объединить их с pdftk?
Галлифреян

1
У вас есть веская причина для создания PDF-файла размером более 2 Гб? Я боюсь, что многие читатели PDF потерпят крах, пытаясь открыть его.
dr01

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

@ dr01: почему они должны? Поддержка больших файлов существует уже несколько десятилетий.
Восстановить Монику - М. Шредер

@ MartinSchröder И все же некоторые программы не могут обрабатывать файлы слишком большого размера. В любом случае, мне было любопытно узнать причину создания PDF-файла объемом 2 Гб (то есть ~ 150 000 страниц формата A4).
dr01

Ответы:


24

Ваше ограничение действительно не вытекает из файловой системы; или из версий пакета, я думаю .

Ваш лимит в 2 ГБ исходит от вас, используя 32-битную версию вашей ОС.

Опция увеличения файла будет установка 64-битной версии, если оборудование поддерживает его .

Смотрите Поддержка больших файлов

Традиционно многие операционные системы и их базовые реализации файловой системы использовали 32-разрядные целые числа для представления размеров и позиций файлов. Следовательно, размер файла не может превышать 2 32 - 1 байт (4 ГБ - 1). Во многих реализациях проблема усугублялась обработкой размеров как чисел со знаком, что еще больше снизило ограничение до 2 31 - 1 байт (2 ГБ - 1).


3
Примечание: Linux может использовать 64-битные размеры и позиции файлов даже в 32-битных версиях около десяти лет назад. Хотя не уверен, что этот инструмент генератора PDF может использовать эту функциональность.
Петер - Восстановить Монику

2
@peterh, имеющий 64-битную версию, off_tне поможет, если программа попытается создать весь файл в оперативной памяти и записать его на диск за один раз.
Дмитрий Григорьев

2
Linux не рассматривает размеры как подписанные, но ядру для работы требуется некоторое выделенное адресное пространство, и в старые времена оставление 2 ГБ для пользовательского пространства казалось очень большим, поэтому ядро ​​резервировало бы остальные 2 ГБ.
Дмитрий Григорьев

2
@DmitryGrigoryev: Размеры не подписаны, но есть различия в указателях ( ptrdiff_t), которые фактически означают, что размеры должны быть ограничены максимальным (подписанным) значением, которое ptrdiff_tможно представить, иначе вы получите действительно очень неприятные ошибки, связанные с UB и UB, которых у приложений нет хороший способ обойти.
R ..

@DmitryGrigoryev В этом случае файл не будет иметь ровно 2 ГБ-1 байта, поскольку программе требуется больше памяти для хранения таких вещей, как исполняемый код.
user23013

12

Попробуйте ограничить используемый кэш пикселей, convertнапример, до 1 ГиБ:

convert 0001.miff ... 2000.miff -limit memory 1GiB -limit map 1GiB -compress jpeg -quality 80 out.pdf

Надеемся, что это заставит ImageMagic регулярно выгружать уже обработанные данные на диск, вместо того, чтобы пытаться разместить более 2 ГБ в буферах ОЗУ.

Кстати, объем виртуальной памяти, доступной для одного процесса в 32-битном Linux, определяется VMSPLITнастройкой ядра. Это может быть 2G / 2G (2 ГБ для ядра + 2 ГБ для пользовательского пространства) или 1G / 3G (1 ГБ для ядра + 3 ГБ для пользовательского пространства). В работающей системе настройку можно найти через

zcat /proc/config.gz | grep VMSPLIT

В некоторых системах /boot/config-$(uname -r)вместо этого хранится конфигурация ядра .


1

Если бы не огромное количество фотографий, вы могли бы использовать TeX / LaTeX для создания PDF. Тогда вы все равно можете получить тот же результат (PDF изображений) без проблемы сбоя конвертера. Ограничения на файлы в TeX должны соответствовать вашей системе (аппаратная часть + ОС)

Но я думаю, что вы могли бы использовать скрипт оболочки для написания TeX:

0)

mkdir convert
pushd convert
PATH=convert:$PATH /* keep everything in one directory for tidyness.*/

1) сделать шаблон

1.1) Я уверен, что есть способ сделать этот шаг за один раз, заменив имя изображения на переменную и вставив, а не добавляя, и отформатировав $ FOO, чтобы иметь правильные начальные 0, но вот что я знаю ,

1.2) Шаблон нужно разделить, чтобы скрипт вставил имя файла

1.3) nano tmplt1 / * или редактор на ваш выбор * /

/* white space line */ 
\begin{figure}[h!]
    \includegraphics[width=0.5\linewidth]{
/* at this point the script will insert $FOO, the file name variable */

1.3.1) Однако ваши файлы отправляются в 0001.miff… 0010.miff… 0100.miff… 2000.miff. Т.е. переменное число ведущих нулей. Обходной путь: 4 версии tmplt1: tmplt1-9, tmplt10-99, tmplt100-999, tmplt1000-2000. Tmplt1-9 оканчивается на «... width] {000» (то есть добавляет 3 0); tmplt10-99 оканчивается на «... width] {00» (т.е. добавляет 2 0). 100-999 добавляет 1 ноль, а 1000-2000 совпадает с tmplt1

1.4) следующая часть шаблона: nano tmplt2 / * OEOYC * /

.miff}
   \caption{ /* if you want to caption, otherwise skip to  tmplt3.
Same again, script will insert $FOO here */

1.5) следующая часть шаблона: nano tmplt3 / * OEOYC * /

}
\label{f:   /*if you want them labelled which is actually
a index/reference for the text to refer to, not a caption.
Same again, the script will insert $FOO here. If you do not
want labels, skip to tmplt4*/

1.6) следующий шаблон: nano tmplt4 / * OEOYC * /

    }
\end{figure}

2) сделать начало файла: nano head / * OEOYC * /

\documentclass{article} /* Or more suitable class */
 \usepackage{graphicx}
 \begin{document}
  /* white space line*/

3) сделать конец файла: nano foot / * OEOYC * /

\end {document} 

4) сделать скрипт: nano loader / * OEOYC * /

#! /bin/bash

cat head > out.pdf

for FOO in {1...9}
do
    cat tmplt1-9 >> out.pdf
    echo "$FOO" | cat >> out.pdf
    cat tmplt2 >> out.pdf
    echo "$FOO" | cat >> out.pdf
    cat tmplt3 >> out.pdf
    echo "$FOO" | cat >> out.pdf
    cat tmplt4 >> out.pdf
done

for FOO in {10...99}
do
    cat tmplt10-99 >> out.pdf /* this looks like a lot but
is actually copy-paste of first block, just add relevant 0's and 9's */
    echo "$FOO" | cat >> out.pdf
    cat tmplt2 >> out.pdf
    echo "$FOO" | cat >> out.pdf
    cat tmplt3 >> out.pdf
    echo "$FOO" | cat >> out.pdf
    cat tmplt4 >> out.pdf
done

for FOO in {100...999}
do
    cat tmplt100-999 >> out.pdf
    echo "$FOO" | cat >> out.pdf
    cat tmplt2 >> out.pdf
    echo "$FOO" | cat >> out.pdf
    cat tmplt3 >> out.pdf
    echo "$FOO" | cat >> out.pdf
    cat tmplt4 >> out.pdf
done

for FOO in {1000...2000}
do
    cat tmplt1000-2000 >> out.pdf
    echo "$FOO" | cat >> out.pdf
    cat tmplt2 >> out.pdf
    echo "$FOO" | cat >> out.pdf
    cat tmplt3 >> out.pdf
    echo "$FOO" | cat >> out.pdf
    cat tmplt4 >> out.pdf
done

cat foot >> out.pdf

5) сделать исполняемый скрипт: chmod u + x loader

5.1) После тестирования я обнаружил, что каждый раз, когда $ FOO был вставлен, он был распределен по 3 строкам. Я не знаю другого обходного пути, кроме как войти в сценарий и вручную удалить возврат каретки. По крайней мере, это всего 36 для всех 2000 фотографий

6) вызов скрипта: загрузчик

7) скомпилируйте TeX: pdflatex out.pdf

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.