Jak przekonwertować plik pdf z skali szarości na czarno-biały?


11

Mój system operacyjny to Ubuntu 12.04. Jak przekonwertować plik pdf z skali szarości na czarno-biały? Plik pdf w skali szarości pochodzi ze skanowania z opcją skali szarości, a OCR wymaga czarno-białej skali pdf.


Aktualizacja:

Po odpowiedzi Marco, BW pdf nie jest dobry, a oryginalny plik jest tutaj .


spróbujscantailor
frostschutz

scantailorma mnóstwo innych przydatnych funkcji, jeśli chodzi o przygotowywanie skanów do OCR, i to jest jedyny powód, dla którego zasugerowałem (jako komentarz, a nie odpowiedź)
frostschutz

Możesz otwierać i eksportować (przynajmniej niektóre) pliki .pdf w libreoffice (i dlatego sądzę, że większość nowoczesnych edytorów tekstu). Nie wiem, czy to sprawi, że pożądana zmiana będzie możliwa, czy łatwa.
goldilocks

1
Istnieje również pdfimages(poppler) do wyodrębnienia zeskanowanych obrazów z kontenera PDF. Przede wszystkim może być bardziej wydajna w obsłudze ich za pomocą ImageMagick.
frostschutz

Odpowiedzi:


9

1) Użyj ghostscript, aby przekonwertować plik PDF na monochromatyczny plik PostScript za pomocą urządzenia psmono :

gs -q -sDEVICE=psmono -o mono.ps input.pdf

2) Następnie przekonwertuj monochromatyczny PostScript z powrotem do formatu PDF:

ps2pdf mono.ps

EDIT:psmono urządzenie tworzy 1-bitowy pół tonu obrazu, który nie jest najwyraźniej to, co chcesz. Nie mogłem znaleźć sposobu na określenie progu za pomocą ghostscript, więc skorzystałem z imagemagick. convertwewnętrznie używa ghostscript do konwersji pliku PDF. Następnie stosuje filtrowanie progowe, aby utworzyć obraz 1-bitowy, i ponownie korzysta z ghostscript, aby utworzyć plik PDF. Ponieważ convertdomyślnie używa rozdzielczości 75DPI, która może nie odpowiadać rzeczywistej rozdzielczości, możesz podać densityargument. I eksperymentuj z thresholdustawieniami. Optymalne wartości w dużym stopniu zależą od pliku wejściowego.

convert -density 150 -threshold 50% input.pdf output.pdf

Dzięki! Jeden problem z uruchomieniem pierwszego polecenia: oryginalny plik PDF w skali szarości ma około 25 MB, a uruchomienie jeszcze się nie zakończyło po 15 minutach, a plik wyjściowy mono.ps ma już 150 MB i wciąż rośnie. Martwię się o to. Czy istnieją inne sposoby, na przykład drukowanie do pliku pdf BW?
Tim

@Tim To nie jest rzadkie. Pliki PostScript są nieskompresowane, wynikowy plik PDF będzie mniejszy.
Marco

Dzięki. Zajęło to około 20 minut. BW pdf nie jest dobry. a oryginalny plik jest tutaj
Tim

@ Czas okropna jakość, nie nadaje się do OCR bez względu na to, co robisz.
frostschutz

4

Najlepszy sposób, w jaki się tam znalazłem, bez utraty jakości, usuwa cienie, szum, tekst z następnej strony, krwawiące itp.:

1) Najpierw przekonwertuj pdf na pojedyncze obrazy

pdfimages combined_ocr.pdf page

2) Po drugie usuwaj cienie, szumy, krwawiące teksty z następnej strony (napisy do tego bloga )

ls ./p*.ppm | xargs -L1 -I {} convert {}  -quality 100 -density 300 -fill white -fuzz 80% +opaque "#000000" {}.jpg

można to dodać jako dodatkowy krok lub zamiast polecenia powyżej, aby uzyskać tylko dwa kolory:

ls ./p*.ppm | xargs -L1 -I {} convert {} +dither -colors 2 -type bilevel -density 300 -fill white -fuzz 40% +opaque "#000000" -density 300 {}.jpg

3) Aby utworzyć plik pdf z każdego obrazu jpg bez utraty rozdzielczości lub jakości:

ls -1 ./*jpg | xargs -L1 -I {} img2pdf {} -o {}.pdf

4) Aby połączyć strony pdf w jeden:

pdftk *.pdf cat output combined.pdf

5) Na koniec dodaję warstwę tekstową OCRed, która nie zmienia jakości skanu w plikach pdf, dzięki czemu można je przeszukiwać:

pypdfocr combined.pdf 

3

Miałem też zeskanowane kolorowe pliki PDF i pliki w skali szarości, które chciałem przekonwertować na bw. Próbowałem przy użyciu gsz kodu wymienionych tutaj , a jakość obrazu jest dobra z tekstem pdf nadal. Jednak ten kod gs konwertuje tylko do skali szarości (zgodnie z pytaniem w pytaniu) i nadal ma duży rozmiar pliku. convertprzy bezpośrednim stosowaniu daje bardzo słabe wyniki.

Chciałem bw pdf z dobrą jakością obrazu i małym rozmiarem pliku. Moje rozwiązanie wykorzystuje gsdo wyodrębnienia plików bmp w odcieniach szarości z pliku pdf, convertdo progowania tych plików bmps do plików bw i zapisania ich jako plików tiff, a następnie img2pdf do skompresowania obrazów tiff i scalenia ich w jeden plik pdf.

Próbowałem przejść bezpośrednio do formatu tiff z pliku pdf, ale jakość nie jest taka sama, więc zapisuję każdą stronę na bmp. W przypadku jednostronicowego pliku pdf convertrobi świetną robotę od bmp do pdf. Przykład:

gs -sDEVICE=bmpgray -dNOPAUSE -dBATCH -r300x300 \
   -sOutputFile=./pdf_image.bmp ./input.pdf

convert ./pdf_image.bmp -threshold 40% -compress zip ./bw_out.pdf

W przypadku wielu stron gsmoże łączyć wiele plików pdf w jeden, ale img2pdfdaje mniejszy rozmiar pliku niż gs. Pliki tiff muszą być rozpakowane jako dane wejściowe do img2pdf. Pamiętaj, że w przypadku dużej liczby stron pośrednie pliki bmp i tiff mają zwykle duży rozmiar. pdftklub joinpdfbyłoby lepiej, gdyby mogli scalić skompresowane pliki pdf z convert.

Myślę, że istnieje bardziej eleganckie rozwiązanie. Jednak moja metoda daje wyniki o bardzo dobrej jakości obrazu i znacznie mniejszym rozmiarze pliku. Aby odzyskać tekst w bw pdf, uruchom ponownie OCR.

Mój skrypt powłoki używa gs, convert i img2pdf. W razie potrzeby zmień parametry (liczba stron, rozdzielczość skanowania, wartość progowa% itp.) Wymienione na początku i uruchom chmod +x ./pdf2bw.sh. Oto pełny skrypt (pdf2bw.sh):

#!/bin/bash

num_pages=12
dpi_res=300
input_pdf_name=color_or_grayscale.pdf
bw_threshold=40%
output_pdf_name=out_bw.pdf
#-------------------------------------------------------------------------
gs -sDEVICE=bmpgray -dNOPAUSE -dBATCH -q -r$dpi_res \
   -sOutputFile=./%d.bmp ./$input_pdf_name
#-------------------------------------------------------------------------
for file_num in `seq 1 $num_pages`
do
  convert ./$file_num.bmp -threshold $bw_threshold \
          ./$file_num.tif
done
#-------------------------------------------------------------------------
input_files=""

for file_num in `seq 1 $num_pages`
do
  input_files+="./$file_num.tif "
done

img2pdf -o ./$output_pdf_name --dpi $dpi_res $input_files
#-------------------------------------------------------------------------
# clean up bmp and tif files used in conversion

for file_num in `seq 1 $num_pages`
do
  rm ./$file_num.bmp
  rm ./$file_num.tif
done

2

W rzeczywistości, jeśli pochodzi ze skanu, jedynym rozsądnym sposobem jest użycie obrazów pdf i konwersja podstawowej grafiki. Użyłem tego skryptu, aby go przekonwertować:

#!/bin/sh
if [ -z "$1" -o -z "$2" ]; then
    echo "Syntax: $0 <input.pdf> <output.pdf>"
    exit 1
fi

pdfimages "$1" scan
for a in scan*.ppm; do 
   convert -white-threshold 85% -monochrome $a `basename $a .ppm`.tiff
done
tiffcp scan*.tiff output.tiff
tiff2pdf output.tiff -o "$2" -p A4 -F
rm scan*.ppm scan*.tiff output.tiff

2

Podziękowania dla OccamsRazor za skrypt, który świetnie wykonuje konwersję plików PDF w kolorze i skali szarości na kompaktową i czytelną wersję monochromatyczną. To jest naprawdę komentarz do postu OccamsRazor, ale nie mam wystarczającej liczby punktów do skomentowania.

Skrypt zawiedzie, img2pdf -o ./$output_pdf_name --dpi $dpi_res $input_files ponieważ --dpinie jest już akceptowanym argumentem dla img2pdf. Zamiast tego pobiera rozdzielczość z pliku wejściowego, więc możesz go po prostu pominąć.

Oto moja wersja skryptu. Nie chciałem edytować skryptu dla każdego pliku, więc podaję liczbę stron i wprowadzam nazwę pliku po uruchomieniu. Mam zestaw do nazwy wyjściowego i rozdzielczości do 200 dpi, który pracuje dla mojego przepływu pracy, ale możesz go zmienić, lub przekształcić je w i i przekazać je.00input_name$3$4

Aby uruchomić, użyj np ../pdf2bw.sh <number_of_pages> <input_name>./pdf2bw.sh 55 input.pdf

#!/bin/bash

num_pages=$1
input_pdf_name=$2
output_pdf_name="00$2"
bw_threshold=40%
dpi_res=200
#-------------------------------------------------------------------------
gs -sDEVICE=bmpgray -dNOPAUSE -dBATCH -q -r$dpi_res \
   -sOutputFile=./%d.bmp ./$input_pdf_name
#-------------------------------------------------------------------------
for file_num in `seq 1 $num_pages`
do
  convert ./$file_num.bmp -threshold $bw_threshold \
          ./$file_num.tif
done
#-------------------------------------------------------------------------
input_files=""

for file_num in `seq 1 $num_pages`
do
  input_files+="./$file_num.tif "
done

img2pdf -o ./$output_pdf_name $input_files
#-------------------------------------------------------------------------
# clean up bmp and tif files used in conversion

for file_num in `seq 1 $num_pages`
do
  rm ./$file_num.bmp
  rm ./$file_num.tif
done

Powinieneś zacytować swoje zmienne powłoki; zwłaszcza te, które pochodzą z argumentów lub innych danych wejściowych użytkownika: np. "./$input_pdf_name"a nawet seq 1 "$num_pages". Możesz także zmienić `…`na $(…)- zobacz to , to i to .
G-Man mówi „Przywróć Monikę”

To jest skrypt OccamsRazor, z wyjątkiem zmian, które zauważyłem. Nie jestem programistą powłoki, więc nie chciałem zadzierać z czymś, co działało. Ale jeśli ktoś chce to posprzątać, masz moje podziękowania.
dolna ściana
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.