Dapatkan lebih dari 2 GB batas membuat PDF dengan ImageMagick

19

Saya menggunakan convertuntuk membuat file PDF dari sekitar 2.000 gambar:

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

Proses ini mengakhiri reproducible ketika file output telah mencapai 2 ^ 31-1 byte (2 GB −1) dengan pesan

convert: unknown `out.pdf'.

Spesifikasi file PDF memungkinkan untuk ≈10 GB . Saya mencoba menarik lebih banyak informasi dari -debug all, tetapi saya tidak melihat sesuatu membantu dalam hasil logging. Sistem file adalah ext3 yang memungkinkan untuk file setidaknya hingga 16 GiB (mungkin lebih) . Adapun ulimit, file sizeadalah unlimited. /etc/security/limits.confhanya berisi baris komentar. Apa lagi yang bisa menyebabkan ini dan bagaimana saya bisa menambah batas?

Versi ImageMagick: 6.4.3 2016-08-05 Q16
Distribusi OpenMP : SLES 11.4 (i586)

Matthias Ronge
sumber
4
Apakah mungkin bagi Anda membuat dua file dengan setengah gambar (atau apa pun yang paling cocok untuk Anda), dan kemudian menggabungkannya dengan pdftk?
Gallifreyan
1
Apakah Anda punya alasan kuat untuk membuat file PDF> 2 Gb? Saya khawatir banyak pembaca PDF akan macet saat mencoba membukanya.
dr01
Karena salinan ImageMagick Anda telah dikompilasi tanpa Dukungan File Besar. Silakan ajukan bug - ini tahun 2017.
Reinstate Monica - M. Schröder
@ dr01: Kenapa mereka harus? Dukungan File Besar telah ada sejak puluhan tahun.
Pasang kembali Monica - M. Schröder
@ MartinSchröder Namun beberapa program tidak dapat menangani file terlalu besar. Lagi pula, saya ingin tahu tentang alasan membuat file PDF 2-Gb (yaitu, ~ 150'000 halaman).
dr01

Jawaban:

24

Keterbatasan Anda memang tidak berasal dari sistem file; atau dari versi paket saya pikir .

Batas 2GB Anda berasal dari Anda menggunakan versi 32-bit OS Anda.

Opsi untuk menambah file akan menginstal versi 64-bit jika perangkat keras mendukungnya .

Lihat Dukungan file besar

Secara tradisional, banyak sistem operasi dan implementasi sistem file yang mendasarinya menggunakan bilangan bulat 32-bit untuk mewakili ukuran dan posisi file. Akibatnya, tidak ada file yang lebih besar dari 2 32 - 1 byte (4 GB - 1). Dalam banyak implementasi, masalahnya diperburuk dengan memperlakukan ukuran sebagai angka yang ditandatangani, yang selanjutnya menurunkan batas menjadi 2 31 - 1 byte (2 GB - 1).

Rui F Ribeiro
sumber
3
Catatan: Linux dapat menggunakan ukuran dan posisi file 64-bit bahkan pada 32-bit sejak sekitar satu dekade lalu. Meskipun tidak yakin, alat generator pdf ini dapat menggunakan fungsi ini.
peterh
2
@peterh memiliki 64-bit off_ttidak akan membantu jika perangkat lunak mencoba membuat seluruh file dalam RAM dan menulisnya ke disk dalam sekali jalan.
Dmitry Grigoryev
2
Linux tidak memperlakukan ukuran sebagai ditandatangani, tetapi kernel membutuhkan beberapa ruang alamat khusus agar berfungsi, dan di masa lalu meninggalkan 2GB ke userland tampak seperti banyak, sehingga kernel akan memesan 2GB lainnya.
Dmitry Grigoryev
2
@DmitryGrigoryev: Ukuran tidak masuk, tetapi perbedaan pointer ( ptrdiff_t) adalah, yang berarti secara efektif bahwa ukuran harus dibatasi pada nilai maksimum (ditandatangani) yang ptrdiff_tdapat diwakilkan, atau Anda mendapatkan bug UB dan UB yang benar-benar buruk yang aplikasi tidak punya cara yang baik untuk bekerja.
R ..
@DmitryGrigoryev Dalam hal ini file tidak akan memiliki tepat 2GB-1 byte, karena program ini membutuhkan lebih banyak memori untuk menyimpan hal-hal seperti kode yang dapat dieksekusi.
user23013
12

Coba batasi cache piksel yang digunakan oleh convertmisalnya 1 GiB:

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

Semoga ini akan memaksa ImageMagic untuk secara teratur membuang data yang sudah diproses pada disk alih-alih mencoba memuat lebih dari 2 GiB dalam buffer RAM.

BTW, jumlah memori virtual yang tersedia untuk satu proses di Linux 32-bit ditentukan oleh VMSPLITpengaturan konfigurasi kernel. Ini bisa berupa 2G / 2G (2GB untuk kernel + 2GB untuk userland) atau 1G / 3G (1 GB untuk kernel + 3 GB untuk userland). Pada sistem yang sedang berjalan, pengaturan dapat ditemukan melalui

zcat /proc/config.gz | grep VMSPLIT

Pada beberapa sistem, konfigurasi kernel disimpan /boot/config-$(uname -r)sebagai gantinya.

Dmitry Grigoryev
sumber
1

Jika bukan karena banyaknya foto, Anda dapat menggunakan TeX / LaTeX untuk membuat PDF. Maka Anda masih bisa mendapatkan hasil yang sama (pdf gambar) tanpa masalah konverter crash. Batas file pada TeX seharusnya menjadi sistem Anda (perangkat keras + OS)

Tapi saya pikir Anda bisa menggunakan skrip shell untuk menulis TeX:

0)

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

1) membuat templat

1.1) Saya yakin ada cara untuk melakukan langkah ini dalam sekali jalan, dengan mengganti nama gambar dengan variabel dan memasukkan daripada menambahkan, dan memformat $ FOO untuk memiliki 0 yang benar, tetapi berikut ini hanya apa yang saya tahu .

1.2) Templat perlu dipisah agar skrip memasukkan nama file

1.3) nano tmplt1 / * atau editor pilihan Anda * /

/* 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) Namun, file Anda pergi 0001.miff ... 0010.miff ... 0100.miff ... 2000.miff. Yaitu sejumlah variabel nol terkemuka. Penanganan masalah: 4 versi tmplt1: tmplt1-9, tmplt10-99, tmplt100-999, tmplt1000-2000. Tmplt1-9 berakhir "... lebar] {000" (yaitu, tambahkan 3 0); tmplt10-99 berakhir "... lebar] {00" (yaitu, tambahkan 2 0). 100-999 menambahkan 1 nol dan 1000-2000 sama dengan tmplt1

1.4) bagian selanjutnya dari templat: nano tmplt2 / * OEOYC * /

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

1.5) bagian selanjutnya dari templat: 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) templat berikutnya: nano tmplt4 / * OEOYC * /

    }
\end{figure}

2) buat awal dari file: nano head / * OEOYC * /

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

3) buat akhir file: nano foot / * OEOYC * /

\end {document} 

4) buat skrip: 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) membuat skrip dapat dieksekusi: chmod u + x loader

5.1) Setelah menguji ini, saya menemukan bahwa setiap kali $ FOO dimasukkan, itu tersebar di 3 baris. Saya tidak tahu solusi apa pun selain masuk ke skrip dan menghapus secara manual pengembalian carriage. Setidaknya hanya 36 untuk semua 2000 foto

6) skrip panggilan: loader

7) kompilasi TeX: pdflatex out.pdf

DozenalVocyemyorka
sumber