Open Source · Beispiel

Arabischen Text in einer PDF reparieren: ein ausführliches Beispiel

Eine Muster-Urkunde, deren Arabisch am Bildschirm richtig aussieht, sich aber als Kästchen und falsche Buchstaben kopiert, mit einem Befehl von arabic-pdf-repair repariert. Laden Sie beide Dateien, vergleichen Sie, was sich einfügen lässt, und führen Sie denselben Code mit Ihren PDFs aus.

1. Die Musterdateien herunterladen

Beide Dateien sind eine einseitige Urkunde, die für dieses Beispiel erstellt wurde: Namen und Angaben darin sind erfunden. Die Textebene des Originals ist so kaputt, wie alte Windows-Programme sie hinterließen; die reparierte Datei ist das Original nach dem Befehl unten. Die Seiten sehen genau gleich aus.

2. Den Text des Originals kopieren

Das sind seine ersten Zeilen, so wie pdf.js sie ausliest, der PDF-Leser von Firefox und vielen Web-Apps. Jedes □ ist ein Steuerzeichen: unsichtbar oder ein Kästchen, je nachdem, wo Sie es einfügen.

□دة إ □□م دورة
□ □□ ا□□ر□□□□دة □□ر □□□□
□ □ إدارة ا□□□□□ □□ن
□ري
□□□"! ا□□رة □"
'□ أ □% □□$□ح دورة

3. Mit einem Befehl reparieren

Mit Node.js 20 oder neuer, ohne Installation. Der Befehl nennt jede reparierte Schrift und schreibt die reparierte Kopie neben das Original, das er nie verändert:

$ npx arabic-pdf-repair certificate.pdf
fixed CertArabic: 65 codes
wrote certificate.repaired.pdf

4. Den Text erneut kopieren

Dieselben Zeilen, aus certificate.repaired.pdf kopiert:

شهادة إتمام دورة
مركز ريادة للتدريب المهني
تشهد إدارة المركز بأن
سارة يوسف المنصوري
قد أتمت بنجاح دورة
أساسيات تحرير المستندات الرقمية

Auch die Suche funktioniert: Das Wort التعلم kommt im Original nicht vor und in der reparierten Datei einmal.

5. Dieselbe Reparatur im eigenen Code

In Node.js installieren Sie das Paket (npm install arabic-pdf-repair) und übergeben die Bytes der Datei an repairTextLayer. Es gibt die reparierte Datei und die reparierten Schriften zurück, oder null, wenn nichts zu reparieren ist:

import { readFile, writeFile } from "node:fs/promises";
import { repairTextLayer } from "arabic-pdf-repair";

const input = new Uint8Array(await readFile("certificate.pdf"));
const result = await repairTextLayer(input);
if (result) {
  await writeFile("certificate.repaired.pdf", result.bytes);
  console.log(result.fonts); // [{ name: "CertArabic", codes: 65 }]
}

Die Bibliothek nutzt keine Node.js-APIs und läuft daher auch im Browser oder in einem Web Worker, mit einer Datei, die der Nutzer auswählt, ohne sie hochzuladen:

import { repairTextLayer } from "arabic-pdf-repair";

const picker = document.querySelector("input[type=file]");
picker.addEventListener("change", async () => {
  const file = picker.files[0];
  const result = await repairTextLayer(new Uint8Array(await file.arrayBuffer()));
  if (!result) return; // nothing to repair
  const url = URL.createObjectURL(new Blob([result.bytes], { type: "application/pdf" }));
  window.open(url); // the repaired copy; the file never left the browser
});

Warum das Original als Zeichensalat kopiert wird

  • Eine PDF zeichnet jeden Buchstaben als Form (Glyphe) aus einer Schrift. Zum Kopieren braucht ein Leseprogramm eine Tabelle in der Datei, ToUnicode genannt, die sagt, für welchen Buchstaben jede Form steht.
  • Der Schrift des Originals fehlt diese Tabelle. Ihre Glyphen tragen nur Microsofts arabische Glyphennamen (ab afii62753), die Leseprogramme nicht als Buchstaben erkennen, also liefert das Kopieren Steuerzeichen und falsche Buchstaben.
  • arabic-pdf-repair liest diese Namen, schreibt die fehlende Tabelle und ändert sonst nichts: dieselben Glyphen an denselben Stellen, also dieselbe Seite.

Wie es weitergeht