2017-02-03 6 views
1

내 프로젝트에서 필자는 Type3 글꼴로 렌더링 된 일부 문자가 포함 된 PDF 파일을 구문 분석해야 할 필요가 있습니다. 따라서, 처리를 위해 BufferedImage에 이러한 문자를 렌더링하는 것이 필요합니다. 다음 데이터가 포함되어렌더링 유형 3 글꼴 문자를 PDFBox를 사용하여 이미지로

PDType3Font font = (PDType3Font)textPosition.getFont(); 
PDType3CharProc charProc = font.getCharProc(textPosition.getCharacterCodes()[0]); 

이 절차의 입력 스트림 :

은 내가 올바른 방법으로 찾고 있는지 확실하지 않습니다,하지만 난 그런 문자 PDType3CharProc을 얻으려고

54 0 1 -1 50 43 d1 
q 
49 0 0 44 1.1 -1.1 cm 
BI 
/W 49 
/H 44 
/BPC 1 
/IM true 
ID 
<some binary data here> 
EI 
Q 

하지만 불행히도이 데이터를 사용하여 PDFBox (또는 다른 Java 라이브러리)를 사용하여 이미지에 문자를 렌더링하는 방법을 알 수 없습니다.

올바른 방향으로보고 있는데이 데이터로 무엇을 할 수 있습니까? 그렇지 않은 경우 이러한 문제를 해결할 수있는 다른 도구가 있습니까?

+0

내 대답이 도움이됩니까? 그렇지 않은 경우 유형 3 글꼴에 대한 샘플 PDF 담당자를 공유하십시오. 이미 내 답변에서 언급 한 바와 같이 주석에 @Tilman과 논의한 바와 같이 다르게 처리 할 유형 3 글꼴 변형이있을 수 있습니다 ... – mkl

답변

1

불행히도 PDFBox는 적어도 내가 볼 수있는 한 임의의 XObjects (유형 3 글꼴 char procs와 같은)의 내용을 렌더링하는 클래스를 제공하지 않습니다.

그러나 완전한 PDF 페이지를 렌더링하기위한 클래스를 제공합니다. 따라서, 주어진 타입 3 폰트 글리프를 렌더링하기 위해, 단순히 그 글리프만을 포함하는 페이지를 생성하고이 임시 페이지를 렌더링 할 수있다! 예를 들어, 타입 3 폰트가 PDDocument document의 첫 페이지에 정의 된 이름 F1을 갖고, 가정

는 모든 문자 발동은 다음과 같이 표현 될 수있다 :

PDPage page = document.getPage(0); 
PDResources pageResources = page.getResources(); 
COSName f1Name = COSName.getPDFName("F1"); 
PDType3Font fontF1 = (PDType3Font) pageResources.getFont(f1Name); 
Map<String, Integer> f1NameToCode = fontF1.getEncoding().getNameToCodeMap(); 

COSDictionary charProcsDictionary = fontF1.getCharProcs(); 
for (COSName key : charProcsDictionary.keySet()) 
{ 
    COSStream stream = (COSStream) charProcsDictionary.getDictionaryObject(key); 
    PDType3CharProc charProc = new PDType3CharProc(fontF1, stream); 
    PDRectangle bbox = charProc.getGlyphBBox(); 
    if (bbox == null) 
     bbox = charProc.getBBox(); 
    Integer code = f1NameToCode.get(key.getName()); 

    if (code != null) 
    { 
     PDDocument charDocument = new PDDocument(); 
     PDPage charPage = new PDPage(bbox); 
     charDocument.addPage(charPage); 
     charPage.setResources(pageResources); 
     PDPageContentStream charContentStream = new PDPageContentStream(charDocument, charPage); 
     charContentStream.beginText(); 
     charContentStream.setFont(fontF1, bbox.getHeight()); 
     charContentStream.getOutput().write(String.format("<%2X> Tj\n", code).getBytes()); 
     charContentStream.endText(); 
     charContentStream.close(); 

     File result = new File(RESULT_FOLDER, String.format("4700198773-%s-%s.png", key.getName(), code)); 
     PDFRenderer renderer = new PDFRenderer(charDocument); 
     BufferedImage image = renderer.renderImageWithDPI(0, 96); 
     ImageIO.write(image, "PNG", result); 
     charDocument.close(); 
    } 
} 

(RenderType3Character.java 시험 방법 testRender4700198773)


영업의 코드에서 textPosition 변수를 고려, 텍스트 추출에서 그는 매우 가능성이 시도이 이온 사용 사례. 따라서 그는 위와 같이 비트 맵을 미리 생성하고 이름을 사용하여 해당 비트 맵을 찾거나 자신의 유스 케이스에서 사용 가능한 정보와 일치하도록 코드를 조정해야합니다 (예 : 원래 페이지가 준비되어 있지 않을 수도 있고 글꼴 이 경우 그는 원래 페이지의 자원을 복사 할 수 없지만 대신 새 자원 객체를 만들고 글꼴 객체를 추가 할 수 있습니다.


불행히도 OP는 샘플 PDF를 제공하지 않았습니다. 따라서 다른 스택 오버플로 질문 중 하나 인 4700198773.pdf을 내 테스트 용으로 extract text with custom font result non readble에서 사용했습니다. 분명히 OP 자신의 파일에 문제가 남아있을 수 있습니다.

+0

은 내가 커밋되지 않은 PDFDebugger에 대한 코드를 가지고 있음을 상기시켜줍니다. 동일한 전략 (PDF 작성)을 사용합니다. 너의 것은 하나의 작은 결함이있다. BBox가 아주 작을 때 작동하지 않을 것이다. PDFBOX-2959의 파일에서 T4 글꼴을 참조하십시오. 매우 이상한 파일입니다. –

+0

* "[PDFBOX-2959] (https://issues.apache.org/jira/browse/PDFBOX-2959) "* - 재미있는 동물이지만, 언뜻보기에는 유효합니다. 좋아, 그런 경우에 컨텐트 스트림을 구문 분석하고 위에 사용 된 방법이 퇴화 된 경계 상자를 생성하는 경우 실제 경계 상자를 결정해야합니다. 이것은 실제로'charProc.getGlyphBBox()'에서 파싱과 결합 될 수 있으므로 너무 많은 추가 오버 헤드를 생성하지 않습니다.구현은 독자를위한 연습으로 남아 있습니다 ...;) – mkl

+0

@TilmanHausherr [this (sdnlist.pdf) (https://www.treasury.gov/ofac/downloads/sdnlist.pdf)의 Type3 글꼴은 [this 질문] (http://stackoverflow.com/q/42073700/1729265) 위의 방법도 실패합니다. 오 잘, OP는 일들이 그의 파일들에 대해 괜찮은지 여부를 말해야합니다 ... – mkl