Obtenha mais de 2 GB de limite na criação de PDFs com o ImageMagick


19

Estou usando convertpara criar um arquivo PDF a partir de cerca de 2.000 imagens:

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

O processo termina reproduzível quando o arquivo de saída atinge 2 ^ 31-1 bytes (2 GB -1) com a mensagem

convert: unknown `out.pdf'.

A especificação do arquivo PDF permite ± 10 GB . Tentei obter mais informações -debug all, mas não vi nada útil na saída do log. O sistema de arquivos é ext3, que permite arquivos com pelo menos 16 GiB (pode ser mais) . Quanto a ulimit, file sizeé unlimited. /etc/security/limits.confcontém apenas linhas comentadas. O que mais pode causar isso e como posso aumentar o limite?

Versão do ImageMagick: 6.4.3-05-08 2016 Q16
Distribuição do OpenMP : SLES 11.4 (i586)


4
É possível criar dois arquivos com metade das imagens (ou o que melhor lhe convier) e depois mesclá-los com o pdftk?
— precisa

1
Você tem algum bom motivo para criar um arquivo PDF> 2 Gb? Receio que muitos leitores de PDF falhem ao tentar abri-lo.
— dr01

Porque sua cópia do ImageMagick foi compilada sem o suporte a arquivos grandes. Por favor, registre um bug - é 2017.
— Reinstate Monica - M. Schröder

@ dr01: Por que deveriam? O suporte a arquivos grandes existe há décadas.
— Reintegrar Monica - M. Schröder

@ MartinSchröder E, no entanto, alguns programas não conseguem lidar com arquivos muito grandes. Enfim, fiquei curioso sobre o motivo da criação de um arquivo PDF de 2 Gb (ou seja, ~ 150.000 páginas A4).
— dr01

Respostas:


24

Sua limitação não deriva de fato do sistema de arquivos; ou de versões de pacotes, eu acho .

Seu limite de 2 GB vem de você usando uma versão de 32 bits do seu sistema operacional.

A opção para aumentar o arquivo seria instalar uma versão de 64 bits se o hardware suportar .

Consulte Suporte a arquivos grandes

Tradicionalmente, muitos sistemas operacionais e suas implementações subjacentes de sistemas de arquivos usavam números inteiros de 32 bits para representar tamanhos e posições de arquivos. Conseqüentemente, nenhum arquivo pode ser maior que 2 32 - 1 bytes (4 GB - 1). Em muitas implementações, o problema foi agravado ao tratar os tamanhos como números assinados, o que reduziu ainda mais o limite para 2 31-1 bytes (2 GB-1).


3
Nota lateral: o Linux pode usar tamanhos e posições de arquivos de 64 bits, mesmo em 32 bits, desde cerca de uma década atrás. Embora não seja certo, essa ferramenta geradora de pdf pode usar essa funcionalidade.
— peterh diz restabelecer Monica 16/08/17

2
@peterh ter 64 bits off_tnão ajudará se o software tentar criar o arquivo inteiro na RAM e gravá-lo no disco de uma só vez.
— Dmitry Grigoryev

2
O Linux não trata os tamanhos como assinados, mas o kernel precisa de algum espaço de endereço dedicado para funcionar, e antigamente, deixar 2 GB para a terra do usuário parecia muito, então o kernel reservaria os outros 2 GB.
— Dmitry Grigoryev

2
@DmitryGrigoryev: Os tamanhos não são assinados, mas as diferenças de ponteiro ( ptrdiff_t) são, o que significa efetivamente que os tamanhos devem ser limitados ao valor máximo (assinado) ptrdiff_tpode representar, ou então você recebe bugs realmente desagradáveis ​​relacionados a UB e UB que os aplicativos não têm boa maneira de contornar.
— R ..

@DmitryGrigoryev Nesse caso, o arquivo não terá exatamente 2 GB-1 bytes, pois o programa precisa de mais memória para armazenar itens como o código executável.
— user23013

12

Tente limitar o cache de pixels usado por, convertpor exemplo, 1 GiB:

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

Espero que isso force o ImageMagic a despejar regularmente os dados já processados ​​no disco, em vez de tentar ajustar mais de 2 GiB nos buffers de RAM.

BTW, a quantidade de memória virtual disponível para um único processo no Linux de 32 bits é definida pela VMSPLITconfiguração do kernel. Pode ser 2G / 2G (2 GB para o kernel + 2 GB para a terra do usuário) ou 1G / 3G (1 GB para o kernel + 3 GB para a terra do usuário). Em um sistema em execução, a configuração pode ser encontrada via

zcat /proc/config.gz | grep VMSPLIT

Em alguns sistemas, a configuração do kernel é armazenada /boot/config-$(uname -r).


1

Se não fosse o grande número de fotografias, você poderia usar o TeX / LaTeX para criar o PDF. Então você ainda pode obter o mesmo resultado (pdf de imagens) sem o problema de falha do conversor. Os limites de arquivo no TeX devem ser apenas o seu sistema (hardware + SO)

Mas acho que você poderia usar um shell script para escrever o TeX:

0)

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

1) faça um modelo

1.1) Tenho certeza de que há uma maneira de executar essa etapa de uma só vez, substituindo o nome da imagem por variável e inserindo, em vez de anexando, e formatando $ FOO para ter os 0s iniciais corretos, mas a seguir é exatamente o que eu sei .

1.2) O modelo precisa ser dividido para que o script insira o nome do arquivo

1.3) nano tmplt1 / * ou editor de sua escolha * /

/* 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) No entanto, seus arquivos ficam 0001.miff… 0010.miff… 0100.miff… 2000.miff. Ou seja, um número variável de zeros à esquerda. Solução alternativa: 4 versões do tmplt1: tmplt1-9, tmplt10-99, tmplt100-999, tmplt1000-2000. Tmplt1-9 termina "... width] {000" (ou seja, adicione 3 0's); tmplt10-99 termina “... width] {00” (ou seja, adicione 2 0's). 100-999 adiciona 1 zero e 1000-2000 é o mesmo que tmplt1

1.4) próxima parte do modelo: nano tmplt2 / * OEOYC * /

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

1.5) próxima parte do modelo: 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) próximo modelo: nano tmplt4 / * OEOYC * /

    }
\end{figure}

2) faça o início do arquivo: nano head / * OEOYC * /

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

3) faça o final do arquivo: nano foot / * OEOYC * /

\end {document} 

4) faça o 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) torne o script executável: chmod u + x loader

5.1) Depois de testar isso, descobri que toda vez que $ FOO era inserido, ele se espalhava por três linhas. Não conheço nenhuma solução alternativa a não ser entrar no script e excluir manualmente os retornos de carro. Pelo menos são apenas 36 para todas as 2.000 fotos

6) script de chamada: carregador

7) compile o TeX: pdflatex out.pdf

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.