Ottieni oltre 2 GB di limite per la creazione di PDF con ImageMagick


19

Sto usando convertper creare un file PDF da circa 2.000 immagini:

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

Il processo termina riproducibile quando il file di output ha raggiunto 2 ^ 31-1 byte (2 GB −1) con il messaggio

convert: unknown `out.pdf'.

Le specifiche del file PDF consentono ≈10 GB . Ho provato a ottenere maggiori informazioni da -debug all, ma non ho visto nulla di utile nell'output di registrazione. Il file system è ext3 che consente di file almeno fino a 16 GiB (potrebbe essere maggiore) . Quanto a ulimit, file sizeè unlimited. /etc/security/limits.confcontiene solo righe commentate. Cos'altro può causare questo e come posso aumentare il limite?

Versione ImageMagick: 6.4.3 2016-08-05 Q16
Distribuzione OpenMP : SLES 11.4 (i586)


4
È possibile creare due file con metà delle immagini (o qualunque cosa ti si adatti meglio) e poi unirli con pdftk?
Gallifreyan,

1
Hai qualche buon motivo per creare un file PDF> 2 Gb? Temo che molti lettori PDF si blocchino nel tentativo di aprirlo.
dr01,

Perché la tua copia di ImageMagick è stata compilata senza supporto per file di grandi dimensioni. Si prega di presentare un bug - è il 2017.
Ripristinare Monica - M. Schröder il

@ dr01: Perché dovrebbero? Il supporto per file di grandi dimensioni esiste da decenni.
Ripristina Monica - M. Schröder il

@ MartinSchröder Eppure alcuni programmi non sono in grado di gestire file troppo grandi. Ad ogni modo, ero curioso del motivo della creazione di un file PDF da 2 Gb (ovvero, circa 150.000 pagine A4).
dr01,

Risposte:


24

La tua limitazione non deriva in effetti dal filesystem; o dalle versioni del pacchetto penso .

Il limite di 2 GB viene da te utilizzando una versione a 32 bit del sistema operativo.

L'opzione per aumentare il file sarebbe installare una versione a 64 bit se l'hardware lo supporta .

Vedere Supporto per file di grandi dimensioni

Tradizionalmente, molti sistemi operativi e le loro implementazioni di file system sottostanti utilizzavano numeri interi a 32 bit per rappresentare dimensioni e posizioni dei file. Di conseguenza, nessun file potrebbe essere più grande di 2 32 - 1 byte (4 GB - 1). In molte implementazioni, il problema è stato aggravato trattando le dimensioni come numeri con segno, il che ha ulteriormente abbassato il limite a 2 31 - 1 byte (2 GB - 1).


3
Nota a margine: Linux può utilizzare dimensioni e posizioni di file a 64 bit anche a 32 bit da circa un decennio fa. Sebbene non sia sicuro, questo strumento di generazione di pdf può utilizzare questa funzionalità.
Peter - Ripristina Monica il

2
@peterh con 64 bit off_tnon aiuta se il software tenta di creare l'intero file nella RAM e di scriverlo sul disco in una volta sola.
Dmitry Grigoryev il

2
Linux non considera le dimensioni come firmate, ma il kernel ha bisogno di uno spazio di indirizzi dedicato per funzionare, e ai vecchi tempi lasciare 2 GB nella zona utente sembrava molto, quindi il kernel riservava gli altri 2 GB.
Dmitry Grigoryev il

2
@DmitryGrigoryev: le dimensioni non sono firmate, ma le differenze del puntatore ( ptrdiff_t) lo sono, il che significa che le dimensioni devono essere limitate al valore massimo (firmato) ptrdiff_t, oppure si ottengono bug davvero molto brutti su UB e UB che le applicazioni non hanno buon modo per aggirare.
R ..

@DmitryGrigoryev In quel caso il file non avrà esattamente 2 GB-1 byte, poiché il programma ha bisogno di più memoria per archiviare cose come il codice eseguibile.
user23013

12

Prova a limitare la cache di pixel utilizzata da convertad esempio 1 GiB:

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

Speriamo che questo costringa ImageMagic a scaricare regolarmente i dati già elaborati sul disco invece di provare a inserire più di 2 GiB nei buffer RAM.

A proposito, la quantità di memoria virtuale disponibile per un singolo processo su Linux a 32 bit è definita dall'impostazione di VMSPLITconfigurazione del kernel. Può essere 2G / 2G (2 GB per kernel + 2 GB per userland) o 1G / 3G (1 GB per kernel + 3 GB per userland). Su un sistema in esecuzione, è possibile trovare l'impostazione tramite

zcat /proc/config.gz | grep VMSPLIT

Su alcuni sistemi è /boot/config-$(uname -r)invece memorizzata la configurazione del kernel .


1

Se non fosse per l'enorme numero di fotografie, è possibile utilizzare TeX / LaTeX per creare il PDF. Quindi puoi comunque ottenere lo stesso risultato (pdf di immagini) senza il problema di crash del convertitore. I limiti dei file su TeX dovrebbero essere solo il tuo sistema (hardware + sistema operativo)

Ma penso che potresti usare uno script di shell per scrivere il TeX:

0)

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

1) crea un modello

1.1) Sono sicuro che c'è un modo per eseguire questo passaggio in una volta sola, sostituendo il nome dell'immagine con la variabile e inserendola anziché aggiungerla, e formattare $ FOO per avere gli 0 iniziali corretti, ma quanto segue è proprio quello che so .

1.2) Il modello deve essere diviso affinché lo script inserisca il nome del file

1.3) nano tmplt1 / * o editor a scelta * /

/* 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) Tuttavia, i file vanno 0001.miff ... 0010.miff ... 0100.miff ... 2000.miff. Vale a dire un numero variabile di zeri iniziali. Soluzione alternativa: 4 versioni di tmplt1: tmplt1-9, tmplt10-99, tmplt100-999, tmplt1000-2000. Tmplt1-9 termina "... larghezza] {000" (ovvero aggiunge 3 0); tmplt10-99 termina “... larghezza] {00” (cioè aggiungi 2 0). 100-999 aggiunge 1 zero e 1000-2000 è uguale a tmplt1

1.4) prossima parte del modello: nano tmplt2 / * OEOYC * /

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

1.5) parte successiva del modello: 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) modello successivo: nano tmplt4 / * OEOYC * /

    }
\end{figure}

2) crea l'inizio del file: nano head / * OEOYC * /

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

3) crea la fine del file: nano foot / * OEOYC * /

\end {document} 

4) crea lo script: 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) rendere eseguibile lo script: chmod u + x loader

5.1) Dopo aver provato questo, ho scoperto che ogni volta che $ FOO veniva inserito, veniva distribuito su 3 righe. Non conosco alcuna soluzione alternativa se non andare nello script e cancellare manualmente i ritorni a capo. Almeno sono solo 36 per tutte le 2000 foto

6) call script: loader

7) compilare il TeX: pdflatex out.pdf

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.