From e4ffd0e21b17e7b10f5637b23eaa3d012162fa91 Mon Sep 17 00:00:00 2001 From: karl Date: Fri, 9 Dec 2022 12:41:20 +0100 Subject: [PATCH] =?UTF-8?q?JPG=20Verkleinerung=20erm=C3=B6glichen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 10 +++++----- structmeta/__init__.py | 17 ++++++++++++++--- structmeta/helpers.py | 41 ++++++++++++++++++++++++++++++++++++++--- toml-elements.md | 2 +- 4 files changed, 58 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index c23dbab..cb50ee6 100644 --- a/README.md +++ b/README.md @@ -41,9 +41,7 @@ Das Programm geht davon aus, dass die Namen der Bilderdateien auf Projektebene e ## Metadaten -Die TOML Datei besteht aus vier Ebenen: Einmal Informationen zum Datenpartner, und einmal Informationen zu den Objekten. Die Ebenen werden durch die festgelegte Strings in eckigen Klammern definiert. `[institution]` und `[objects]` sind verpflichtend, `[images]` und `[OCR]` können auch weg gelassen werden. Unterhalb dieser Ebenen wird pro Zeile einem Schlüssel durch ein `=` Zeichen ein Wert zugewiesen. Zeichenfolgen werden dabei in Anführungsstriche gesetzt. Die TOML-Datei ist mit einem Plaintext-Texteditor zu bearbeiten (nicht etwa mit Word o.ä.). Mit Tools wie bspw. [TOML Lint](https://www.toml-lint.com/) kann die erzeugte TOML Datei validiert und auf Syntaxfehler geprüft werden. Das sieht dann exemplarisch so aus - hier fehlt in Zeile 16 ein einfaches Anführungszeichen: - -![](assets/tomllint.png) +Die TOML Datei besteht aus vier Ebenen: Einmal Informationen zum Datenpartner, und einmal Informationen zu den Objekten. Die Ebenen werden durch die festgelegte Strings in eckigen Klammern definiert. `[institution]` und `[objects]` sind verpflichtend, `[images]` und `[OCR]` können auch weg gelassen werden. Unterhalb dieser Ebenen wird pro Zeile einem Schlüssel durch ein `=` Zeichen ein Wert zugewiesen. Zeichenfolgen werden dabei in Anführungsstriche gesetzt. Die TOML-Datei ist mit einem Plaintext-Texteditor zu bearbeiten (nicht etwa mit Word o.ä.). Mit Tools wie bspw. [TOML Lint](https://www.toml-lint.com/) kann die erzeugte TOML Datei validiert und auf Syntaxfehler geprüft werden. ### TOML Beispiel @@ -77,8 +75,6 @@ tesseract_executable = "C:/Program Files/Tesseract-OCR/tesseract.exe" Erweiterte Informationen zu den Elementen finden Sie unter: https://github.com/karkraeg/structmeta/blob/main/toml-elements.md. -> :warning: Wenn OCR durchgeführt werden soll, dürfen nicht gleichzeitig mit `max_dimensions` die JPGs verkleinert werden. (Siehe [Issue](https://github.com/Deutsche-Digitale-Bibliothek/ddblabs-structmeta/issues/2)) - ## Ordnerstrukturen ### Zeitungen @@ -139,8 +135,12 @@ Monographien - Der Zauberlehrling ``` +## Helferfunktionen + ## OCR +> :warning: Wenn OCR durchgeführt werden soll, dürfen nicht gleichzeitig mit `max_dimensions` in der TOML Konfigurationsdatei die Bilder verkleinert werden. (Siehe [Issue](https://github.com/Deutsche-Digitale-Bibliothek/ddblabs-structmeta/issues/2)) + Unter Verwendung einer externen Installation von Tesseract kann für jede Bilddatei eine zugehörige ALTO XML Datei erstellt und in einer `mets:fileGrp@USE=FULLTEXT` referenziert werden. ### Installation von Tesseract diff --git a/structmeta/__init__.py b/structmeta/__init__.py index c889ebb..d673465 100755 --- a/structmeta/__init__.py +++ b/structmeta/__init__.py @@ -46,8 +46,10 @@ def getpictures(folder: Path, max_dimensions, jpg_quality: int, outputfolder): alltiffs -- list of file paths to supplied TIF files """ + alljpgs = [] existingthumbs = [] + for ext in ["jpg", "jpeg"]: for i in folder.glob("*." + ext): if "thumb" not in i.name: @@ -75,6 +77,11 @@ def getpictures(folder: Path, max_dimensions, jpg_quality: int, outputfolder): ] else: # wir hatten JPGs + if max_dimensions: + # Bilder verkleinern? + helpers.reduceJPGs( + alljpgs, logger, max_dimensions, jpg_quality, outputfolder + ) initialpictureformat = alljpgs[0].suffix.replace(".", "") jpgs = alljpgs alltiffs = [] @@ -559,7 +566,7 @@ def processImages( - eine Liste mit Pfaden zu den Bilddateien als JPG im Ausgabe Ordner - eine Liste mit Pfaden zu den Thumbnails als JPG im Ausgabe Ordner """ - + # In der Subfunktion getpictures werden ggf. die Bilder auch komprimiert/kleingerechnet jpgs, existingthumbs, initialpictureformat, alltiffs = getpictures( folder, max_dimensions, jpg_quality, outputfolder ) @@ -577,8 +584,12 @@ def processImages( # wenn nicht umbennant werden soll, schauen ob wir ursprünglich JPGs hatten if initialpictureformat in ["jpg", "jpeg"]: # wenn ja, werden die in den outputerfolder kopiert. Wenn nicht sind die JPGs aus den TIF Dateien ja eh dahin erstellt worden - for j in initialjpgs: - shutil.copy(str(j), str(Path(outputfolder / "binaries" / j.name))) + if max_dimensions: + # wenn max_dimensions vergeben ist, sind die Bilder ja schon verkleinert im Output-Ordner. + pass + else: + for j in initialjpgs: + shutil.copy(str(j), str(Path(outputfolder / "binaries" / j.name))) # -------------------------------------- # Thumbnails # -------------------------------------- diff --git a/structmeta/helpers.py b/structmeta/helpers.py index 3fd88e5..672e323 100644 --- a/structmeta/helpers.py +++ b/structmeta/helpers.py @@ -110,7 +110,9 @@ def zipfiles(inputfolder: Path, outputfolder: Path, logger, logname: str, OCR: b f.unlink(missing_ok=True) logger.info("JPGs gezippt") if OCR == True: - with zipfile.ZipFile(binarieszip, "a", compression=zipfile.ZIP_DEFLATED) as zipObj: + with zipfile.ZipFile( + binarieszip, "a", compression=zipfile.ZIP_DEFLATED + ) as zipObj: for f in list(Path(outputfolder / "binaries").rglob("*.xml")): zipObj.write(f, arcname=f.name) f.unlink(missing_ok=True) @@ -145,12 +147,12 @@ def createJPGfromTIFF( pass else: try: - # als Default keine Skalierung. + # als Default keine Skalierung, nur wenn max_dimensions vergeben wurde if max_dimensions: img.thumbnail((max_dimensions, max_dimensions)) img.save( Path(outputfolder / "binaries" / jpgfilename), - "JPEG", + "jpeg", quality=jpg_quality, ) except Exception as e: @@ -161,6 +163,39 @@ def createJPGfromTIFF( ) +def reduceJPGs( + list_of_images: list, + logger, + max_dimensions: int, + jpg_quality: int, + outputfolder: Path, +): + print(f"Verkleinere {len(list_of_images)} JPGs", flush=True) + logger.info(f"Verkleinere {len(list_of_images)} JPGs") + list_of_images = natsorted(list_of_images) + for j in list_of_images: + filename = j.stem + ".jpg" + try: + img = Image.open(j) + except Exception as e: + logger.error(e) + pass + else: + try: + img.thumbnail((max_dimensions, max_dimensions)) + except Exception as e: + logger.error(e) + else: + img.save( + Path(outputfolder / "binaries" / filename), + "jpeg", + quality=jpg_quality, + ) + logger.debug( + f"JPG verkleinert und in {str(Path(outputfolder / 'binaries' / filename))} geschrieben." + ) + + def generate_thumbails( listofjpgs: list, logger, outputfolder: Path, recordIdentifier: str, rename: bool ): diff --git a/toml-elements.md b/toml-elements.md index d744627..c3790e2 100644 --- a/toml-elements.md +++ b/toml-elements.md @@ -19,6 +19,6 @@ | **objects → sprache** | Leerer String erlaubt | `//mods:language/mods:languageTerm` Der Wert von `sprache` muss ein [iso639-2b](https://wiki.dnb.de/download/attachments/90411323/sprachenCodesDeutsch.pdf) Code sein. | | **images → imagebaseurl** | Optional | Mit der Angabe von `imagebaseurl` kann man den Dateinamen der Bilddatei mit einer URL prefixen, damit bspw. statt `img0001.jpg` dann `https://mein.repo.de/img0001.jpg` in der `mets:fileGrp` eingetragen wird. Wird die DDB die Bilddateien hosten, ist dieser Parameter nicht zu benutzen. | | **images → max_dimensions** | Optional / Integer | Angabe der maximalen Breite/Höhe wenn aus TIFF Dateien JPG erzeugt wird. | -| **images → jpg_quality** | Optional / Integer | Qualität der zu berechnenden JPGs von 0 (extrem kompromiert) bis 100 (nicht komprimiert) | +| **images → jpg_quality** | Optional / Integer | Legt die Qualität der zu berechnenden JPGs von 0 (extrem kompromiert) bis 100 (nicht komprimiert) fest. Wird berücksichtigt, wenn die Ausgangsdateien im TIF Format vorliegen. Wenn JPGs vorliegen, wird dieser Wert nur in Kombination mit max_dimensions berücksichtigt. | | **ocr → tesseract_language** | Optional | Angabe der Sprache für die Texterkennung, muss mit tesseract installiert worden sein | | **ocr → tesseract_executable** | Optional | Pfad zur Ausführbaren Datei von tesseract, wenn nicht im PATH (bspw. `'C:/Program Files/Tesseract-OCR/tesseract.exe'`) |