Jiří Meitner | IT služby Linux | Kladno | Česko

A wide-angle image showing a futuristic, high-tech computer screen displaying a complex Bash script with colorful syntax highlighting.

Jak zkomprimovat a optimalizovat pdf soubory v linuxu

Už se vám stalo, že jste chtěli poslat pdf soubor a měl velkou velikost? V tomto článku se podělím o script, který vám pdf soubor zkomprimuje.

Pro kompresi použijeme ghostscript. Ve scriptu můžeme měnit nejen přednastavenou kvalitu (screen, ebook, printer, prepress), ale měnit barevný prostor (Gray, LeaveColorUnchanged, UseDeviceIndependentColor, RGB, sRGB, CMYK). Můžeme měnit i formát papíru (například změnit A4 na Letter či něco jiného). Dále například přiložit jen použité znaky z fontů. U opakujících se obrázků uložit jen jeden. Můžeme také uložit jen určitý rozsah stránek (například 2 až tři).

pdf_compress – skript pro kompresi pdf souborů

Script pro kompresi pdf souboru v linuxu si uložte třeba do ~/bin/pdf_compress. Spouští se s pozičním parametrem – jméno vstupního souboru, jméno výstupního souboru se generuje ze jména vstupního souboru a použitého nastavení.

#!/bin/bash
# shellcheck disable=SC2086,SC2016,SC2034
####################################################################
help()
{
echo 'soubor $1 jako poziční parametr je povinný'
echo "příklad: ${0} itislove.pdf"
exit 1
}
if [[ -z ${1} ]]; then help; fi
####################################################################
in="${1}"
out="$(echo "${in}"|sed -e 's/.pdf$//' -e 's/.PDF$//')_optimized"
title="$(basename "${in}"|iconv -f UTF-8 -t ASCII//TRANSLIT)"
FirstPage="${2:-}"
LastPage="${3:-$FirstPage}"
GS_ARGS=''
if [[ -n "${FirstPage}" ]]; then
        GS_ARGS="-dFirstPage=${FirstPage} -dLastPage=${LastPage}"
fi
####################################################################
A0='-dDEVICEWIDTHPOINTS=2384 -dDEVICEHEIGHTPOINTS=3370         A0'
A1='-dDEVICEWIDTHPOINTS=1684 -dDEVICEHEIGHTPOINTS=2384	       A1'
A2='-dDEVICEWIDTHPOINTS=1191 -dDEVICEHEIGHTPOINTS=1684         A2'
A3='-dDEVICEWIDTHPOINTS=842 -dDEVICEHEIGHTPOINTS=1191          A3'
A4='-dDEVICEWIDTHPOINTS=595 -dDEVICEHEIGHTPOINTS=842           A4'
A5='-dDEVICEWIDTHPOINTS=420 -dDEVICEHEIGHTPOINTS=595           A5'
A6='-dDEVICEWIDTHPOINTS=298 -dDEVICEHEIGHTPOINTS=420           A6'
B0='-dDEVICEWIDTHPOINTS=2835 -dDEVICEHEIGHTPOINTS=4008         B0'
B1='-dDEVICEWIDTHPOINTS=2004 -dDEVICEHEIGHTPOINTS=2835         B1'
B2='-dDEVICEWIDTHPOINTS=1417 -dDEVICEHEIGHTPOINTS=2004         B2'
B3='-dDEVICEWIDTHPOINTS=1001 -dDEVICEHEIGHTPOINTS=1417         B3'
B4='-dDEVICEWIDTHPOINTS=709 -dDEVICEHEIGHTPOINTS=1001          B4'
B5='-dDEVICEWIDTHPOINTS=499 -dDEVICEHEIGHTPOINTS=709           B5'
Letter='-dDEVICEWIDTHPOINTS=612 -dDEVICEHEIGHTPOINTS=791   Letter'
Legal='-dDEVICEWIDTHPOINTS=612 -dDEVICEHEIGHTPOINTS=1009   Legal'
Format=${A4}                    # zde možné nastavit velikost papíru
####################################################################
format="$(echo "${Format}"|awk '{print $3}')"
out="${out}_${format}"
####################################################################
Quality_1='-dPDFSETTINGS=/screen'
Quality_2='-dPDFSETTINGS=/ebook'
Quality_3='-dPDFSETTINGS=/printer'
Quality_4='-dPDFSETTINGS=/prepress'
Quality=${Quality_2} # zde možné nastavit kvalitu
####################################################################
quality="$(echo "${Quality}"|cut -f2 -d/)"
out="${out}_${quality}"
####################################################################
Gray='-dColorConversionStrategy=/Gray'
ColorUnchanged='-dColorConversionStrategy=/LeaveColorUnchanged'
IndColor='-dColorConversionStrategy=/UseDeviceIndependentColor'
RGB='-dColorConversionStrategy=/RGB'
sRGB='-dColorConversionStrategy=/sRGB'
CMYK='-dColorConversionStrategy=/CMYK'
Color=${sRGB} # zde možné nastavit barevný prostor
####################################################################
color="$(echo "${Color}"|cut -f2 -d/)"
out="${out}_${color}.pdf"
####################################################################
pdfcompress()
# funkce pro post optimalizace vygenerovaného pdf ghostscrptem
{
Paper=$(echo "${Format}"|awk '{print $1, $2}')
gs -sDEVICE=pdfwrite -dFIXEDMEDIA -dPDFFitPage ${Paper} \
 ${Quality} ${Color} -dCompatibilityLevel='1.7' \
 -dFastWebView=true -dCompressPages=true \
 -dDetectDuplicateImages=true -dOptimize=true -dSubsetFonts=true \
 -dNOPAUSE -dBATCH $GS_ARGS \
 -o "${out}" -f "${in}" \
 -c "[ /Title (${title}) /DOCINFO pdfmark"
}
rm "${out}" -rf &>/dev/null
pdfcompress
echo "${out}"
velikost_in=$(du -k "${in}"|cut -f1)
velikost_out=$(du -k "${out}"|cut -f1)
rozdil=$(echo "${velikost_in} - ${velikost_out}"|bc)

if (( velikost_out > velikost_in )); then
echo "komprimovaný soubor ${out} je větší než ${in}, mažu ${out}"
else
echo "Kompresí souboru bylo ušetřeno ${rozdil} KB"
echo "Otevírám výstupní soubor ${out} pro kontrolu."
xdg-open "${out}"
fi

exitCode language: Bash (bash)

Snažil jsem se skript napsat srozumitelně.

Tip: zazálohování záložek před oříznutím a samotné oříznutí pdf souboru

pdfcrop – oříznutí pdf

Určitě se vám někdy stalo, že jste chtěli oříznout pdf soubor na nějakou velikost, nebo odstranit vodoznak na okraji. V linuxu je to jednoduché. Pokud chcete odstranit část trvale, tak použijete pdcrop a zaexperimentovat si s ořezem.

  • Levý okraj: První číslo určuje velikost levého okraje.
  • Horní okraj: Druhé číslo určuje velikost horního okraje.
  • Pravý okraj: Třetí číslo určuje velikost pravého okraje.
  • Dolní okraj: Čtvrté číslo určuje velikost dolního okraje.

Příklad: oříznutí 50 bodů ze souboru rhcsa_book.pdf a zbavení vodoznaku se jménem

pdfcrop --margins '-50 0 0 0' rhcsa_book.pdf rhcsa_book_cropped.pdfCode language: Bash (bash)

Příklad: přidání zpět 50 bodů k souboru rhcsa_book_cropped.pdf do soboru rhcsa_book_cropped2.pdf, tím získáme soubor se stejnými rozměry jako původní rhcsa_book.pdf, ale tentokrát bez vodoznaku.

pdfcrop --margins '50 0 0 0' rhcsa_book_cropped.pdf rhcsa_book_cropped2.pdfCode language: Bash (bash)

Nevýhodou pdfcrop je, že nezachovává záložky, proto z původního souboru rhcsa_book.pdf vyextrahujeme záložky a spojíme je s rhcsa_book_cropped2.pdf za vzniku rhcsa_book_cropped3.pdf.

pdftk – exktrakce záložek z původního souboru
pdftk rhcsa_book.pdf dump_data output bookmarks.txt
pdftk rhcsa_book_cropped2.pdf update_info bookmarks.txt output rhcsa_book_cropped3.pdf
Code language: Bash (bash)

Ještě se podělím o skript, který webovou stránku převede do pdf a rovnou zkomprimuje. Ne, není to stejný script jako v minulém článku.

web2pdf skript pro převod webu do pdf

Oproti scriptu v minulém článku (https://itislove.cz/2024/02/jak-vytisknout-web-na-linuxu-do-pdf-v-bash-scriptu/ jsou výsledné soubory cca desetinové. Používá stejný postup komprese a nastavení, jako skript výše. Můžete v něm nastavit, jestli má pracovat s google chrome nebo s wkhtmltopdf. Skript by měl vytvářet i záložky v pdf na základě nadpisů na webové stránce.

#!/bin/bash
# shellcheck disable=SC2086,SC2034
####################################################################
#pdf=wkhtml # vyberte buď wkhtml nebo google_chrome, pro chromium google_chrome
pdf=google_chrome
####################################################################
help()
{
echo "url jako poziční parametr je povinné"
echo "příklad: ${0} https://itislove.cz"
exit 1
}
if [[ -z ${1} ]]; then help; fi
####################################################################
user_data_dir="${HOME}/.config/google-chrome-for-print"
in="${1}"
out="./$(echo ${in}|sed 's@http://@@; s@https://@@'|tr '/' '_' \
 |sed 's/$/.pdf/; s/_.pdf$/.pdf/')"
####################################################################
# určuje stránky od do, které se budou tisknout, nastavuje se
# volitelnými druhým a třetím pozičním paramtetrem, neměňte
FirstPage="${2:-}"
LastPage="${3:-$FirstPage}"
GS_ARGS=''
if [[ -n "${FirstPage}" ]]; then
        GS_ARGS="-dFirstPage=${FirstPage} -dLastPage=${LastPage}"
fi
####################################################################
A0='-dDEVICEWIDTHPOINTS=2384 -dDEVICEHEIGHTPOINTS=3370    A0'
A1='-dDEVICEWIDTHPOINTS=1684 -dDEVICEHEIGHTPOINTS=2384    A1'
A2='-dDEVICEWIDTHPOINTS=1191 -dDEVICEHEIGHTPOINTS=1684    A2'
A3='-dDEVICEWIDTHPOINTS=842 -dDEVICEHEIGHTPOINTS=1191     A3'
A4='-dDEVICEWIDTHPOINTS=595 -dDEVICEHEIGHTPOINTS=842      A4'
A5='-dDEVICEWIDTHPOINTS=420 -dDEVICEHEIGHTPOINTS=595      A5'
A6='-dDEVICEWIDTHPOINTS=298 -dDEVICEHEIGHTPOINTS=420      A6'
B0='-dDEVICEWIDTHPOINTS=2835 -dDEVICEHEIGHTPOINTS=4008    B0'
B1='-dDEVICEWIDTHPOINTS=2004 -dDEVICEHEIGHTPOINTS=2835    B1'
B2='-dDEVICEWIDTHPOINTS=1417 -dDEVICEHEIGHTPOINTS=2004    B2'
B3='-dDEVICEWIDTHPOINTS=1001 -dDEVICEHEIGHTPOINTS=1417    B3'
B4='-dDEVICEWIDTHPOINTS=709 -dDEVICEHEIGHTPOINTS=1001     B4'
B5='-dDEVICEWIDTHPOINTS=499 -dDEVICEHEIGHTPOINTS=709      B5'
Letter='-dDEVICEWIDTHPOINTS=612 -dDEVICEHEIGHTPOINTS=791  Letter'
Legal='-dDEVICEWIDTHPOINTS=612 -dDEVICEHEIGHTPOINTS=1009  Legal'
Format=${A4} #zde možné nastavit velikost papíru
####################################################################
Quality_1='-dPDFSETTINGS=/screen'
Quality_2='-dPDFSETTINGS=/ebook'
Quality_3='-dPDFSETTINGS=/printer'
Quality_4='-dPDFSETTINGS=/prepress'
Quality=${Quality_2} # zde možné nastavit kvalitu
####################################################################
Gray='-dColorConversionStrategy=/Gray'
ColorUnchanged='-dColorConversionStrategy=/LeaveColorUnchanged'
IndColor='-dColorConversionStrategy=/UseDeviceIndependentColor'
RGB='-dColorConversionStrategy=/RGB'
sRGB='-dColorConversionStrategy=/sRGB'
CMYK='-dColorConversionStrategy=/CMYK'
Color=${sRGB} # zde možné nastavit barevný prostor
####################################################################
google_chrome()
# funkce pro tisk pomocí google chrome
{
pdf=$(command -v google-chrome chromium)
if [[ -z ${pdf} ]]; then
echo "google-chrome ani chromium nenalezeno, nejprve nainstalujte"
pkexec "$(command -v apt dnf yum zypper|head -n1)" \
 install -y chromium-browser
exit 2
fi
WindowSize="$(echo "${Format}"|awk '{print $1, $2}'|tr ' ' '\n' \
|cut -f2 -d=|tr '\n' ','|cut -f1,2 -d,)"
"${pdf}" --headless --disable-gpu \
 --run-all-compositor-stages-before-draw \
 --no-pdf-header-footer --print-to-pdf-no-header --no-margins \
 --hide-scrollbars \
 --generate-pdf-document-outline --force-device-scale-factor=1 \
 --new-window --enable-font-antialiasing \
 --window-size="${WindowSize}" --print-to-pdf="${out}" "${in}"
}

wkhtml()
{
pdf=$(command -v wkhtmltopdf)
if [[ -z ${pdf} ]]; then
echo "wkhtmltopdf není nainstalováno, nejprve nainstalujte"
xdg-open https://wkhtmltopdf.org/downloads.html
exit 2
fi
PaperSize="$(echo "${Format}"|awk '{print $3}')"
wkhtmltopdf -q --page-size "${PaperSize}" --enable-javascript \
 --title "${in}" "${in}" "${out}"
}

ghostscript()
# funkce pro post optimalizace vygenerovaného pdf ghostscrptem
{
Format="$(echo "${Format}"|awk '{print $1, $2}')"
gs -q -sDEVICE=pdfwrite -dFIXEDMEDIA -dPDFFitPage \
 ${Format} ${Quality} ${Color} \
 -dCompatibilityLevel='1.7' -dFastWebView=true \
 -dCompressPages=true -dDetectDuplicateImages=true \
 -dOptimize=true -dSubsetFonts=true -dNOPAUSE -dBATCH \
 $GS_ARGS -o "${out}.tmp" -f "${out}" \
 -c "[ /Title ($in) /DOCINFO pdfmark" &>/dev/null
mv "${out}.tmp" "${out}"
}
rm "${out}" -rf &>/dev/null
${pdf}
ghostscript #zakomentováním vypnete post zpracování přes ghostscript
du -h "${out}"
xdg-open "${out}" # pokud nechcete automaticky otevřít, zakomentujte
exitCode language: Bash (bash)

Summary
Jak zkomprimovat a optimalizovat pdf soubory v linuxu
Article Name
Jak zkomprimovat a optimalizovat pdf soubory v linuxu
Description
V tomto článku vás naučím ořez pdf souborů v linuxovém terminálu, změnu velikosti stran, export a import záložek pdf, změnu formátu a barevného prostoru.
Author
Publisher Name
ITisLove.cz
Publisher Logo

Comments

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *

Tato stránka používá Akismet k omezení spamu. Podívejte se, jak vaše data z komentářů zpracováváme..