Obtenga más de 2 GB de límite creando PDF con ImageMagick

19

Estoy usando convertpara crear un archivo PDF de aproximadamente 2,000 imágenes:

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

El proceso finaliza de forma reproducible cuando el archivo de salida ha alcanzado 2 ^ 31-1 bytes (2 GB −1) con el mensaje

convert: unknown `out.pdf'.

La especificación del archivo PDF permite ≈10 GB . Traté de obtener más información -debug all, pero no vi nada útil en la salida del registro. El sistema de archivos es ext3 que permite archivos de al menos hasta 16 GiB (puede ser más) . En cuanto a ulimit, file sizees unlimited. /etc/security/limits.confsolo contiene líneas comentadas. ¿Qué más puede causar esto y cómo puedo aumentar el límite?

Versión de ImageMagick: 6.4.3 2016-08-05 Q16
Distribución de OpenMP : SLES 11.4 (i586)

Matthias Ronge
fuente
44
¿Es posible que cree dos archivos con la mitad de las imágenes (o lo que más le convenga) y luego los combine con pdftk?
Gallifreyan
1
¿Tiene alguna buena razón para crear un archivo PDF de> 2 Gb? Temo que muchos lectores de PDF se bloqueen al intentar abrirlo.
dr01
Porque su copia de ImageMagick se ha compilado sin compatibilidad con archivos grandes. Presente un error: es 2017.
Vuelva a instalar a Monica - M. Schröder el
@ dr01: ¿Por qué deberían hacerlo? El soporte para archivos grandes ha existido desde hace décadas.
Restablece a Monica - M. Schröder el
@ MartinSchröder Y, sin embargo, algunos programas no pueden manejar archivos demasiado grandes. De todos modos, tenía curiosidad sobre la razón de crear un archivo PDF de 2 Gb (es decir, ~ 150'000 páginas A4).
dr01

Respuestas:

24

Su limitación no se deriva del sistema de archivos; o de las versiones del paquete , creo .

Su límite de 2 GB proviene de usted usando una versión de 32 bits de su sistema operativo.

La opción para aumentar el archivo sería instalar una versión de 64 bits si el hardware lo admite .

Ver soporte para archivos grandes

Tradicionalmente, muchos sistemas operativos y sus implementaciones de sistemas de archivos subyacentes usaban enteros de 32 bits para representar tamaños y posiciones de archivos. En consecuencia, ningún archivo puede ser mayor que 2 32-1 bytes (4 GB-1). En muchas implementaciones, el problema se exacerbó al tratar los tamaños como números con signo, lo que redujo aún más el límite a 2 31 - 1 bytes (2 GB - 1).

Rui F Ribeiro
fuente
3
Nota al margen: Linux puede usar tamaños y posiciones de archivos de 64 bits incluso en 32 bits desde hace aproximadamente una década. Aunque no es seguro, esta herramienta generadora de pdf puede usar esta funcionalidad.
peterh - Restablece a Mónica el
2
@peterh tener 64 bits off_tno ayudará si el software intenta crear todo el archivo en RAM y escribirlo en el disco de una vez.
Dmitry Grigoryev
2
Linux no trata los tamaños como si estuvieran firmados, pero el núcleo necesita un espacio de direcciones dedicado para funcionar, y en los viejos tiempos, dejar 2GB para el usuario parecía mucho, por lo que el núcleo reservaría los otros 2GB.
Dmitry Grigoryev
2
@DmitryGrigoryev: los tamaños no están firmados, pero las diferencias de puntero ( ptrdiff_t) sí, lo que significa que los tamaños deben estar limitados al valor máximo (firmado) que ptrdiff_tpuede representar, o de lo contrario obtendrá errores UB y UB realmente desagradables que las aplicaciones no tienen buena forma de evitarlo.
R ..
@DmitryGrigoryev En ese caso, el archivo no tendrá exactamente 2GB-1 bytes, ya que el programa necesita más memoria para almacenar cosas como el código ejecutable.
user23013
12

Intente limitar la caché de píxeles utilizada por, convertpor ejemplo, 1 GiB:

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

Con suerte, esto obligará a ImageMagic a volcar regularmente los datos ya procesados ​​en el disco en lugar de tratar de ajustar más de 2 GiB en los búferes de RAM.

Por cierto, la cantidad de memoria virtual disponible para un solo proceso en Linux de 32 bits está definida por la VMSPLITconfiguración de configuración del kernel. Puede ser 2G / 2G (2GB para kernel + 2GB para userland) o 1G / 3G (1 GB para kernel + 3 GB para userland). En un sistema en ejecución, la configuración se puede encontrar a través de

zcat /proc/config.gz | grep VMSPLIT

En algunos sistemas, la configuración del kernel se almacena en su /boot/config-$(uname -r)lugar.

Dmitry Grigoryev
fuente
1

Si no fuera por la gran cantidad de fotografías, podría usar TeX / LaTeX para crear el PDF. Entonces aún puede obtener el mismo resultado (pdf de imágenes) sin el problema del bloqueo del convertidor. Los límites de archivos en TeX deberían ser solo su sistema (hardware + SO)

Pero creo que podría usar un script de shell para escribir el TeX:

0)

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

1) hacer una plantilla

1.1) Estoy seguro de que hay una manera de hacer este paso de una vez, reemplazando el nombre de la imagen con variable e insertando en lugar de agregar, y formatear $ FOO para que tenga los primeros 0 correctos, pero lo siguiente es justo lo que sé .

1.2) La plantilla debe dividirse para que el script inserte el nombre del archivo

1.3) nano tmplt1 / * o editor de su elección * /

/* 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) Sin embargo, sus archivos van 0001.miff ... 0010.miff ... 0100.miff ... 2000.miff. Es decir, un número variable de ceros a la izquierda. Solución alternativa: 4 versiones de tmplt1: tmplt1-9, tmplt10-99, tmplt100-999, tmplt1000-2000. Tmplt1-9 termina “... ancho] {000” (es decir, agregue 3 0's); tmplt10-99 termina "... ancho] {00" (es decir, agregue 2 0). 100-999 agrega 1 cero y 1000-2000 es lo mismo que tmplt1

1.4) siguiente parte de la plantilla: nano tmplt2 / * OEOYC * /

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

1.5) siguiente parte de la plantilla: 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) siguiente plantilla: nano tmplt4 / * OEOYC * /

    }
\end{figure}

2) hacer el comienzo del archivo: nano head / * OEOYC * /

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

3) hacer el final del archivo: nano pie / * OEOYC * /

\end {document} 

4) crea el 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) hacer que el script sea ejecutable: chmod u + x loader

5.1) Después de probar esto, descubrí que cada vez que se insertaba $ FOO, se extendía en 3 líneas. No conozco otra solución que no sea entrar en el script y eliminar manualmente los retornos de carro. Al menos solo 36 para todas las fotos de 2000

6) script de llamada: cargador

7) compile el TeX: pdflatex out.pdf

DozenalVocyemyorka
fuente