Отримайте ліміт понад 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 GiB (може бути більше) . Щодо 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 Gb? Я побоююся, що багато читачів PDF зазнають аварійних спроб відкрити його.
dr01

Тому що ваша копія ImageMagick була складена без підтримки великого файлу. Будь ласка, подайте помилку - це 2017.
Відновіть Моніку - М. Шредер

@ dr01: Чому вони повинні? Підтримка великих файлів існує вже з десятиліть.
Відновіть Моніку - М. Шредер

@ MartinSchröder І все ж деякі програми не в змозі обробляти файли занадто великими. У всякому разі, мені було цікаво, чому було створено PDF-файл 2 Гб (тобто ~ 150 000 сторінок формату А4).
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, у яких програми не мають хороший спосіб обійти.
Р ..

@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 ГБ для користувальницької), або 1 Г / 3 Г (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 закінчується "... ширина] {000" (тобто додайте 3 0's); tmplt10-99 закінчується "... ширина] {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) зробіть кінець файлу: нано нога / * OEOYC * /

\end {document} 

4) складіть сценарій: нанонавантажувач / * 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.