Uzyskaj ponad 2 GB limitu na tworzenie plików PDF za pomocą ImageMagick

19

Używam convertdo utworzenia pliku PDF z około 2000 obrazów:

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

Proces kończy się odtwarzalnie, gdy plik wyjściowy osiągnie 2 ^ 31-1 bajtów (2 GB -1) z komunikatem

convert: unknown `out.pdf'.

Specyfikacja pliku PDF pozwala na ≈10 GB . Próbowałem pobrać więcej informacji -debug all, ale nie widziałem nic przydatnego w danych wyjściowych logowania. System plików to ext3, który pozwala na pliki co najmniej do 16 GiB (może być więcej) . Co do ulimit, file sizejest unlimited. /etc/security/limits.confzawiera tylko skomentowane linie. Co jeszcze może to powodować i jak mogę zwiększyć limit?

Wersja ImageMagick: 6.4.3 2016-08-05 Q16
Dystrybucja OpenMP : SLES 11.4 (i586)

Matthias Ronge
źródło
4
Czy jest możliwe, aby utworzyć dwa pliki z połową obrazów (lub cokolwiek, co najbardziej ci odpowiada), a następnie scalić je za pomocą pdftk?
Gallifreyan,
1
Czy masz jakiś dobry powód, aby utworzyć plik PDF> 2 Gb? Obawiam się, że wiele czytników plików PDF zawiesiłoby się przy próbie jego otwarcia.
dr01
Ponieważ twoja kopia ImageMagick została skompilowana bez obsługi dużych plików. Zgłoś błąd - jest rok 2017.
Przywróć Monikę - M. Schröder
@ dr01: Dlaczego powinni? Obsługa dużych plików istnieje już od dziesięcioleci.
Przywróć Monikę - M. Schröder
@ MartinSchröder A jednak niektóre programy nie są w stanie obsłużyć plików zbyt dużych. W każdym razie byłem ciekawy powodu utworzenia pliku PDF 2 Gb (czyli około 150 000 stron A4).
dr01

Odpowiedzi:

24

Twoje ograniczenia nie wynikają z systemu plików; lub z wersji pakietu, jak sądzę .

Twój limit 2 GB pochodzi od Ciebie w 32-bitowej wersji systemu operacyjnego.

Opcją zwiększenia pliku byłoby zainstalowanie wersji 64-bitowej, jeśli sprzęt go obsługuje .

Zobacz Obsługa dużych plików

Tradycyjnie wiele systemów operacyjnych i bazowe implementacje systemu plików używały 32-bitowych liczb całkowitych do reprezentowania rozmiarów i pozycji plików. W rezultacie żaden plik nie może być większy niż 2 32-1 bajtów (4 GB - 1). W wielu implementacjach problem pogłębiał się, traktując rozmiary jako liczby ze znakiem, co dodatkowo obniżyło limit do 2 31–1 bajtów (2 GB - 1).

Rui F. Ribeiro
źródło
3
Uwaga dodatkowa: Linux może używać 64-bitowych rozmiarów i pozycji plików nawet w wersji 32-bitowej od około dekady temu. Chociaż nie jest pewne, czy to narzędzie do generowania plików PDF może korzystać z tej funkcji.
peterh - Przywróć Monikę
2
@peterh mający 64-bit off_tnie pomoże, jeśli oprogramowanie spróbuje utworzyć cały plik w pamięci RAM i zapisać go na dysku za jednym razem.
Dmitrij Grigoriew
2
Linux nie traktuje rozmiarów jako podpisanych, ale jądro potrzebuje do działania dedykowanej przestrzeni adresowej, a dawniej pozostawianie 2 GB w przestrzeni użytkownika wydawało się bardzo duże, więc jądro rezerwowało pozostałe 2 GB.
Dmitrij Grigoryev,
2
@DmitryGrigoryev: Rozmiary nie są podpisane, ale różnice między wskaźnikami ( ptrdiff_t) są, co oznacza, że ​​rozmiary muszą być ograniczone do maksymalnej (podpisanej) wartości, która ptrdiff_tmoże reprezentować, w przeciwnym razie otrzymasz naprawdę bardzo nieprzyjemne błędy związane z UB i UB, których aplikacje nie mają dobry sposób na obejście.
R ..
@DmitryGrigoryev W takim przypadku plik nie będzie miał dokładnie 2 GB-1 bajtów, ponieważ program potrzebuje więcej pamięci do przechowywania takich rzeczy, jak kod wykonywalny.
user23013
12

Spróbuj ograniczyć pamięć podręczną pikseli używaną convertnp. Do 1 GiB:

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

Mamy nadzieję, że zmusi to ImageMagic do regularnego zrzucania już przetworzonych danych na dysk, zamiast próbować zmieścić więcej niż 2 GiB w buforach RAM.

BTW, ilość pamięci wirtualnej dostępnej dla pojedynczego procesu w 32-bitowym systemie Linux jest określona przez VMSPLITustawienie konfiguracji jądra. Może to być 2G / 2G (2 GB dla jądra + 2 GB dla przestrzeni użytkownika) lub 1G / 3G (1 GB dla jądra + 3 GB dla przestrzeni użytkownika). W działającym systemie ustawienie można znaleźć za pośrednictwem

zcat /proc/config.gz | grep VMSPLIT

W niektórych systemach konfiguracja jądra jest przechowywana w /boot/config-$(uname -r)zamian.

Dmitrij Grigoriew
źródło
1

Gdyby nie ogromna liczba zdjęć, można użyć TeX / LaTeX do utworzenia pliku PDF. Wtedy nadal możesz uzyskać ten sam wynik (pdf obrazów) bez problemu z awarią konwertera. Limity plików w TeXie powinny być po prostu twoim systemem (sprzęt + system operacyjny)

Ale myślę, że możesz użyć skryptu powłoki, aby napisać TeX:

0)

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

1) zrób szablon

1.1) Jestem pewien, że jest sposób, aby zrobić ten krok za jednym razem, zastępując nazwę obrazu zmienną i wstawiając zamiast dodawać, a także sformatować $ FOO, aby mieć prawidłowe początkowe zera, ale następujące jest to, co wiem .

1.2) Szablon musi zostać podzielony, aby skrypt mógł wstawić nazwę pliku

1.3) nano tmplt1 / * lub dowolny edytor * /

/* 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) Jednak twoje pliki idą 0001.miff… 0010.miff… 0100.miff… 2000.miff. To jest zmienna liczba wiodących zer. Obejście: 4 wersje tmplt1: tmplt1-9, tmplt10-99, tmplt100-999, tmplt1000-2000. Tmplt1-9 kończy „… szerokość] {000” (tzn. Dodaje 3 0); tmplt10-99 kończy „… width] {00” (tzn. dodaje 2 0). 100-999 dodaje 1 zero, a 1000-2000 jest takie samo jak tmplt1

1.4) następna część szablonu: nano tmplt2 / * OEOYC * /

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

1.5) następna część szablonu: 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) Następny szablon: nano tmplt4 / * OEOYC * /

    }
\end{figure}

2) utwórz początek pliku: nano head / * OEOYC * /

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

3) zrób koniec pliku: nano foot / * OEOYC * /

\end {document} 

4) wykonaj skrypt: 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) uczynić skrypt wykonywalnym: chmod u + x loader

5.1) Po przetestowaniu tego stwierdziłem, że za każdym razem, gdy wstawiano $ FOO, rozkładało się ono na 3 linie. Nie znam żadnego innego obejścia niż przejście do skryptu i ręczne usuwanie zwrotów karetki. Przynajmniej 2000 na wszystkie 2000 zdjęć

6) skrypt wywołania: moduł ładujący

7) skompiluj TeX: pdflatex out.pdf

DozenalVocyemyorka
źródło