utf-8 文字 (İ、ğ、ı、アラビア文字など) を含む PDF ファイルがあります。このファイルを解析する方法は?
itext と pdfBox を使用していますが、「çektiği kağıda」ではなく「çekti¤i k夛da」と表示されます。どうすればこれを解決できますか?
4 に答える
サンプルがまだ提供されていないので、私は自分でアラビア語のテスト データを作成し (実際には、itext-questions メーリング リストのいくつかの投稿からテスト データを作成するためのコードを借りました)、それらのデータを解析するテストを作成しました。
package itext.parsing;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.parser.PdfTextExtractor;
import junit.framework.TestCase;
public class TextExtractingArabic extends TestCase
{
public void testExtractArabicChars() throws DocumentException, IOException
{
createTestFile(TEST_FILE);
PdfReader reader = new PdfReader(TEST_FILE.toString());
String text = PdfTextExtractor.getTextFromPage(reader, 1);
for (char c: text.toCharArray())
{
int i = c<0 ? Integer.MAX_VALUE + c : c;
System.out.print("\\u");
System.out.print(Integer.toHexString(i));
}
}
void createTestFile(File file) throws DocumentException, IOException
{
Document document = new Document();
OutputStream os = new FileOutputStream(file);
PdfWriter.getInstance(document, os);
document.open();
BaseFont bfArialUni = BaseFont.createFont("C:\\Windows\\Fonts" + "\\ARIALUNI.TTF",
BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Font fontArialUni = new Font(bfArialUni, 12f);
Phrase myPhrase = new Phrase(LAWRENCE_OF_ARABIA, fontArialUni);
PdfPTable table = new PdfPTable(1);
PdfPCell cell = new PdfPCell(new Paragraph(myPhrase));
cell.setColspan(3);
cell.setPaddingRight(15f);
cell.setBorder(PdfPCell.NO_BORDER);
cell.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
table.addCell(cell);
document.add(table);
document.close();
os.close();
}
final static File TEST_FILE = new File("arabic-test.pdf");
final static String LAWRENCE_OF_ARABIA =
"\u0644\u0648\u0631\u0627\u0646\u0633\u0627\u0644\u0639\u0631\u0628";
}
文字列 LAWRENCE_OF_ARABIA は、アラビアのロレンスに音声的にいくらか近似しています。
テキストの出力は次のとおりです。
\ufe8f\ufeae\ufecc\ufedf\ufe8e\ufeb4\ufee7\ufe8d\ufead\ufeee\ufedf
これは入力と同じではありませんが、Unicode テーブルをざっと見てみると、入力が Unicode 範囲「Arabic」からのものであり、出力が Unicode 範囲「Arabic Presentation Forms-B」からのものであることがわかります。さらに、入力は右から左ですが、出力は左から右です。
私はアラビア語を知らないので、出力がどれほど正確かはわかりませんが、解析された文字は適切な Unicode 範囲からのものであることは間違いありません。
元の投稿者が使用している PDF にアクセスせずにわかる限り、問題は解析ではなく、パーサーの出力の適切な使用にあるようです。
ボブロフスキーが述べているように、それは見栄えがするかもしれませんが、基礎となるエンコーディングは完全には正しくありません。PDFビューアでXのように見えるglyhpは、文字Xとして内部的にエンコードされない場合があります。AdobePDFReaderから文字セットをサポートするテキストエディタにテキストをコピーして貼り付けることで、これを簡単にテストできます。コピーアンドペーストでOKの場合は抽出が可能ですが、そうでない場合はできません(カスタマイズされたマッピングなどの手動による対策を講じない場合)。
PDF は、実際のフォント バイトで指定されたさまざまなエンコーディングと、フォントを記述する PDF 構造で生成されることがあります。
このような場合、テキストは問題なく表示されますが、適切に抽出されない可能性があります。これは西ヨーロッパ言語でよく見られます。
この問題を解決するために、Docotic.Pdf ライブラリは、フォント ファイルのエンコーディングを優先するかどうかを自動的に検出します。
これは、さまざまな PDF テキスト抽出オプションを示す記事です。
免責事項: 私はライブラリのベンダーで働いています。