Użyj Ghostscript, ale powiedz mu, żeby nie przetwarzał zdjęć ponownie?

30

Mam plik PDF, który już skompresował i zawiera nieco artefakty-y, i korzystam z Ghostscript, aby dołączyć stronę tytułową do tego pliku PDF.

Nie mogę jednak znaleźć sposobu, aby poinformować GS, aby po prostu używał istniejących obrazów bez ich ponownego przetwarzania, a teraz mam wrażenie, że ma to związek z tym, jak działa GS, tzn. Nie można ponownie skompilować / połączyć pliku PDF bez przetwarzania obrazów. Czy to prawda?

Mogę podnieść ustawienie DPI w GS, ale zwiększy się ono z 5 MB do 60 MB, wciąż wyglądając gorzej.

Czy jest jakaś lepsza alternatywa dla GS, która zrobi to, czego potrzebuję (najlepiej skompiluje się w systemie OS X)?

Mahmoud Al-Qudsi
źródło
Czy możesz edytować swoje pytanie i podać dokładną linię poleceń, której używasz, aby dołączyć stronę tytułową do oryginalnego pliku PDF? Potem mógłbym ci powiedzieć, co dokładnie zmienić lub dodać do wiersza poleceń, aby uzyskać lepszą wydajność dla obrazów ...
Kurt Pfeifle,
Nie chcę, aby wyglądało to lepiej, chcę się połączyć bez ponownego przetwarzania. Spowoduje to a) lepszą jakość (bezstratne transformacje) oraz b) nie marnowanie godzin procesora na przetwarzanie mojego ponad 1000 stronicowego dokumentu.
Mahmoud Al-Qudsi
1
Hej, nie odpowiedziałeś na moje pytanie i nie podałeś dokładnej linii poleceń GS, której używasz. Co oznacza: nie dostaniesz pomocy dotyczącej GS, którego szukasz ...
Kurt Pfeifle

Odpowiedzi:

44

Jeśli chcesz po prostu połączyć dwa pliki PDF bez ponownego przetwarzania ich zawartości, pdftkjest dla Ciebie. (W systemie Mac OS X powinno to być dostępne za pośrednictwem MacPorts lub Fink, w przypadku systemu Linux istnieją natywne pakiety dla wszystkich głównych dystrybucji; w przypadku systemu Windows spójrz tutaj. ) Wypróbuj to:

 pdftk title.pdf content.pdf cat output book.pdf

Spowoduje to dodanie tytułu.pdf do content.pdf i zapisanie wyniku w book.pdf .

pdftkto „głupi”, ale bardzo szybki sposób na połączenie dwóch (lub więcej) plików PDF. „Głupi” w tym pdftksensie , że nie interpretuje w żaden sposób strumienia danych PDF, po prostu upewnia się, że wewnętrzne numery obiektów są zmieniane w razie potrzeby i pojawiają się w xrefstrukturze PDF (która w zasadzie jest rodzajem PDF ToC dla obiekty).

Ghostscript:

Jeśli chcesz użyć Ghostscript, podstawową komendą do łączenia tych samych dwóch plików byłoby:

 gs \
  -o book.pdf \
  -sDEVICE=pdfwrite \
   title.pdf \
   content.pdf

Jednak, jak zauważyłeś, ta prosta linia poleceń może popsuć jakość obrazu. Powodem jest to, że Ghostscript nie „zrzuca” podczas przetwarzania plików PDF: całkowicie interpretuje je podczas wczytywania i tworzy zupełnie nowy plik podczas zapisywania wyniku. Aby utworzyć wynik, automatycznie użyje ustawień domyślnych dla wielu szczegółów w całym przetwarzaniu. Te domyślne będą obowiązywać we wszystkich przypadkach, w których wywołania nie nakazały Ghostscript inaczej.

Tak więc metoda tworzenia nowego book.pdf przez Ghostscript jest znacznie bardziej „inteligentna” (ale także znacznie wolniejsza) niż pdftkmetoda. (Jest to również powód, dla którego Ghostscript w wielu przypadkach może - w ramach ograniczeń - „naprawiać” pliki PDF b0rken lub osadzać czcionki w wyjściowych plikach PDF, które nie są osadzone w wejściowych plikach PDF, lub usuwać zduplikowane obrazy, zastępując za pomocą samych referencji itp. - i ogólnie stworzyliśmy mniejsze, lepiej zoptymalizowane pliki z rozdętych wejściowych plików PDF ...)

Rozwiązaniem jest niedopuszczenie, aby Ghostscript używał swoich ustawień domyślnych: dodając więcej niestandardowych parametrów do wiersza poleceń.

Co to znaczy „Ghostscript” interpretuje „dane wejściowe PDF” ?

Cały plik i jego zawartość (obiekty, strumienie, czcionki, obrazy, ...) są wczytywane, sprawdzane i przechowywane we własnej wewnętrznej reprezentacji przed ponownym wyrzuceniem wynikowego pliku PDF z obiektami PDF. Jednak podczas „wypluwania” Ghostscript zastosuje wszystkie swoje wewnętrzne ustawienia domyślne do setek parametrów [*], które są dostępne.

Niestety powoduje to „ponowne przetwarzanie” obrazów zgodnie z tymi ustawieniami domyślnymi - których można uniknąć lub zastąpić, dodając własne (pożądane) parametry wiersza polecenia.

Problemy z obrazem mogą być spowodowane potrzebą Ghostscript (z powodu problemów licencyjnych), aby ponownie zakodować obrazy JPEG2000 na kodowanie JPEG. Jeśli chcesz tego uniknąć, dodaj do wiersza polecenia:

-dAutoFilterColorImages=false \
-dAutoFilterGrayImages=false \
-dColorImageFilter=/FlateEncode \
-dGrayImageFilter=/FlateEncode \

Inne opcje wiersza polecenia związane z obrazami, które należy rozważyć, to:

-dColorConversionStrategy=/LeaveColorUnchanged \
-dDownsampleMonoImages=false \
-dDownsampleGrayImages=false \
-dDownsampleColorImages=false \

Więc pełna komenda Ghostscript, która może cię uszczęśliwić, powinna brzmieć:

 gs \
  -o book.pdf \
  -sDEVICE=pdfwrite \
  -dColorConversionStrategy=/LeaveColorUnchanged \
  -dDownsampleMonoImages=false \
  -dDownsampleGrayImages=false \
  -dDownsampleColorImages=false \
  -dAutoFilterColorImages=false \
  -dAutoFilterGrayImages=false \
  -dColorImageFilter=/FlateEncode \
  -dGrayImageFilter=/FlateEncode \
   title.pdf \
   content.pdf

Możesz także powiedzieć Ghostscript, aby wcale NIE kompresował obrazów w wyjściowym pliku PDF, używając tego wiersza poleceń:

 gs \
  -o book.pdf \
  -sDEVICE=pdfwrite \
  -dColorConversionStrategy=/LeaveColorUnchanged \
  -dEncodeColorImages=false \
  -dEncodeGrayImages=false \
  -dEncodeMonoImages=false \
   title.pdf \
   content.pdf

.


[*]:
Jeśli chcesz dowiedzieć się o pełnej liście ustawień domyślnych, których używa urządzenie do pisania pdf Ghostscript , uruchom następujące polecenie. Zwraca pełną listę:

 gs \
   -sDEVICE=pdfwrite \
   -o /dev/null \
   -c "currentpagedevice { exch ==only ( ) print == } forall"

Aby uzyskać wyjaśnienia na temat tego, co dokładnie oznaczają wszystkie te parametry, należy przeczytać dokumentację Adobe dotyczącą „parametrów destylatora” . Ghostscript bardzo stara się naśladować te wszystkie ...

Kurt Pfeifle
źródło
3
(FYI) W moim przypadku, flagi dEncodeColorImages, dEncodeGrayImages, dEncodeMonoImagesprzyczyna pliku wyjściowego, aby stać się dużo bardziej masywne. Po ich usunięciu rozmiar pliku zmienił się z 22 MB na 3,1 MB, a jakość obrazu wygląda dokładnie tak, jak przy użyciu tych flag. Wszystkie unikalne flagi z używam to: dColorConversionStrategy=/LeaveColorUnchanged, dDownsampleMonoImages=false, dDownsampleGrayImages=false, dDownsampleColorImages=false, dAutoFilterColorImages=false, dAutoFilterGrayImages=false, dColorImageFilter=/FlateEncode,dGrayImageFilter=/FlateEncode
Dor
@Kurt Pfeifle Jakie opcje są dozwolone -dColorImageFilter? Mogę tylko znaleźć FlateEncodei DCTEncode. DCT wydaje się robić JPEG (dlaczego to szyfrują?). Myślę, że FLATE jest już przestarzałą opcją dla obrazów, ponieważ patent firmy Bell Labs na LZW nie stanowi już problemu? Jednak po spędzeniu dłuższego czasu na wyszukiwaniu nie mogę znaleźć sposobu użycia PNG (ani niczego innego) ... Moje oryginalne obrazy to PNG i chcę, aby pozostały niezmienione. Wypróbowałem opcję -c, ale daje mi to -c can only be used in a built with POSTSCRIPT included....
Louis Somers