Folgendes Problem: man hat einige Screenshots von einem Buch o.ä. gemacht und möchte daraus jetzt ein PDF haben. Das PDF soll per Text durchsuchbar sein. Die Screenshots sind in umgekehrter Reihenfolge.
Also folgende Schritte:
Dafür nutzen wir mehrere Programme in einer langen Pipe, inspiriert von Stackoverflow.
Ausgabe der Dateien in umgekehrter Sortierungsreihenfolge, Sortierung in natürlicher Reihenfolge der Nummern:
$ ls -r -v *.jpg
Screenshot_20250521-193144.jpg Screenshot_20250521-193141.jpg Screenshot_20250521-193139.jpg Screenshot_20250521-193134.jpg
Ausgabe der Liste mit einer Datei pro Zeile, dabei Numerierung der Zeilen:
$ ls -r -v *.jpg | cat -n
1 Screenshot_20250521-193144.jpg
2 Screenshot_20250521-193141.jpg
3 Screenshot_20250521-193139.jpg
4 Screenshot_20250521-193134.jpg
Jede Zeile nehmen und umbenennen, in $n
wird die Nummer gespeichert, in $f
der Dateiname, mit printf
wird die Nummer zweistellig mit führenden Nullen formatiert:
$ ls -r -v *.jpg | cat -n | while read n f; do mv -v "$f" `printf "%02d_$f" $n`; done
renamed 'Screenshot_20250521-193144.jpg' -> '01_Screenshot_20250521-193144.jpg'
renamed 'Screenshot_20250521-193141.jpg' -> '02_Screenshot_20250521-193141.jpg'
renamed 'Screenshot_20250521-193139.jpg' -> '03_Screenshot_20250521-193139.jpg'
renamed 'Screenshot_20250521-193134.jpg' -> '04_Screenshot_20250521-193134.jpg'
Durch die Umbenennung können wir einfach eine Schleife über alls Bilder mit ls
laufen lassen und die Bilder mit ocrmypdf in PDF umwandeln, gleich mit Texterkennung.
Die Screenshots meines Handys haben keine DPI in den Metadaten gespeichert, diese ist für ocrmypdf
nötig.
Dafür habe ich mir ein Convenience-Script geschrieben: ocr.
Grob zusammengefasst (nicht getestet, nur die Idee):
for file in *.jpg
do
ocrmypdf -l "deu" --image-dpi 300 "$file" "$file.pdf"
done
Wer sich ocrmypdf
nicht installieren will, kann das über Docker aufrufen, auch dafür habe ich ein Convenience-Script: ocrmypdf-docker.
Damit reduziert sich mein konkreter Aufruf auf:
$ ocr -t jpg
ocring all files (jpg) in current directory /home/...
ocr 01_Screenshot_20250521-193144.jpg -> 01_Screenshot_20250521-193144-ocr.pdf, language deu, dpi 300
Input file is not a PDF, checking if it is an image...
Input file is an image
Input image has no ICC profile, assuming sRGB
Image seems valid. Try converting to PDF...
Successfully converted to PDF, processing...
Postprocessing...
Image optimization ratio: 1.04 savings: 4.1%
Total file size ratio: 0.97 savings: -3.1%
Output file is a PDF/A-2B (as expected)
ocr 02_Screenshot_20250521-193141.jpg -> 02_Screenshot_20250521-193141-ocr.pdf, language deu, dpi 300
[...]
Die einzelnen PDFs können wir mit pdftk zusammenkleben. Das kann man installieren, auch hier kann man Docker verwenden, den direkten Aufruf hier nachschauen.
Das PDf soll nach dem Unterverzeichnis benannt werden, in dem es liegt, dafür benutzen wir basename
, und eine Ebene höher gespeichert werden:
$ pdftk *.pdf cat output "../`basename "$PWD"`.pdf" verbose
Command Line Data is valid.
[...]
Creating Output ...
Adding page 1 XNORTHX from 01_Screenshot_20250521-193144-ocr.pdf
Adding page 1 XNORTHX from 02_Screenshot_20250521-193141-ocr.pdf
Adding page 1 XNORTHX from 03_Screenshot_20250521-193139-ocr.pdf
Adding page 1 XNORTHX from 04_Screenshot_20250521-193134-ocr.pdf
In Linux kann man die Aufrufe noch prima mit &&
verknüpfen mit dem Vorteil, dass die verknüpften Befehle nur ausgeführt werden, wenn der vorige ohne Fehler beendet wurde.
$ ls -r -v *.jpg | cat -n | while read n f; do mv -v "$f" `printf "%02d_$f" $n`; done && ocr -t jpg && pdftk *.pdf cat output "../`basename "$PWD"`.pdf" verbose
Ob man diese Kette jetzt in einem Script speichert oder direkt aufruft ist Geschmackssache und hängt bei mir davon ab, ob ich das noch öfter brauche oder nur heute. Man könnte die benutzten Dateien jetzt noch löschen, da prüfe ich lieber noch das erzeugte Ergebnis und lösche manuell. Außerdem könnte man das Script noch über alle Unterverzeichnisse laufen lassen, auch das ist den Aufwand für einen Tag nicht wert, macht man das öfter – auf jeden Fall 😄
Quick’n’dirty (wirklich dirty, da wird nicht geschaut, ob die generierten PDF zu Problemen führen etc.):
find . -type d | \
while read dir; do
(cd "$dir" && ls -r -v *.jpg | cat -n | while read n f; do mv -v "$f" `printf "%02d_$f" $n`; done && ocr -t jpg && pdftk *.pdf cat output "../`basename "$PWD"`.pdf" verbose)
done