컨텐츠 스트림 처리 (및 여기에 참조 된 모든 객체, 예를 들어 이미지, 글꼴 등)를 추가하는 멋진 PDFRW 라이브러리의 확장은 가능한 한 간단하게 유지합니다.
그렇다면 PYPDF와 같은 본격적인 PDF 라이브러리가있을 때 왜 PDFRW를 확장합니까? 이런 식으로 생각하십시오. 대부분의 PDF 라이브러리는 일반적인 PDF 처리 작업을 단순화하는 기능을 제공하려고합니다. 이 라이브러리는 그들이하는 일에 매우 능숙하지만 가끔씩 새로운 기능이 필요한 작업이 나타납니다. 이제 그러한 상황에 처한 개발자라면 이러한 라이브러리의 다량의 소스 코드를 파기 시작해야합니다.
PDFRW 의 접근 방식은 다릅니다. 가능한 한 간단하게 유지하면서 PDF를 가능한 한 많이 구문 분석하겠습니다. 나쁜 생각은 아닙니다. 특히 PDF 객체 모델 (일부 값이 다른 사전에 대한 값 중 일부를 가진 사전이라는 사실)이 표준 Python 사전에 매핑하는 데 매우 적합하다는 사실을 감안할 때 나쁜 생각은 아닙니다. 또한 PDFRW는 PDF 객체를 가로 지르는 또 다른 훌륭한 패키지 어트래의 아이디어를 구현하여 PDF 객체를 더 간단하게 만들 수 있습니다. 예를 들어 페이지 글꼴 액세스는 다음과 같이 수행 할 수 있습니다.
for fontName , fontDict in page . Resources . Font . items ():
( do something )다음 단계는 사전 스트림을 구문 분석하는 것입니다. 텍스트, 이미지, 벡터 그래픽 등 흥미로운 물건을 포함하는 사전의 특수 항목입니다. 생성되는 데이터 구조는 완전합니다. 가능한 모든 처리 작업에 충분한 모든 PDF를 포함합니다. 또한 개발자가 즉시 코딩을 시작하여 Adobe의 Magnum Opus에서 구절을 즐기는 데 더 많은 시간을 보내고 다른 복잡한 도서관을 배우지 못할 정도로 간단합니다. 실제로 PDFRW는 PDF 구문을 배우는 데 도움이되는 이상적인 도구입니다!
좋아,이 시점에 도달했다면, 당신은 궁금해 할 것입니다 : 그래서 여기서 어디로 가야합니까? 구체적으로 : 사전 스트림을 어떻게 구문 분석합니까? This is where pdfrwx can help: it can parse dictionary streams and do other useful things. 그러나 먼저 먼저 :
PDFRWX는 먼저 위에서 설명한 PDFRW 의 철학을 유지하려고합니다. 이에는 많은 PDF 처리 작업에서 대부분의 시간이 소프트웨어 솔루션을 개발하는 데 사용되지만 실행이 아닌 소프트웨어 솔루션을 개발하는 데 사용된다는 관찰이 추가됩니다. 이것은 디자인 선택으로 이어집니다.
이제 우리는 PDFRWX가 무엇을하고 어떻게 달성하는지 확인할 준비가되었습니다.
examples/pdfstream.py 는 example.pdf를 읽고 모든 페이지에서 모든 텍스트 내용을 제거하고 결과를 example-out.pdf에 씁니다.
from pdfrw import PdfReader , PdfWriter , PdfArray
from pdfrwx . pdffilter import PdfFilter
from pdfrwx . pdfstreamparser import PdfStream
toArray = lambda obj : obj if isinstance ( obj , PdfArray )
else PdfArray ([ obj ]) if obj != None else PdfArray ()
pdfIn = PdfReader ( 'example.pdf' )
pdfOut = PdfWriter ( 'example-out.pdf' )
for page in pdfIn . pages :
contentsArray = toArray ( page . Contents )
for contents in contentsArray :
stream = PdfFilter . uncompress ( contents ). stream
treeIn = PdfStream . stream_to_tree ( stream )
treeOut = []
for leaf in treeIn :
cmd , args = leaf [: 2 ]
if cmd != 'BT' : treeOut . append ( leaf )
contents . stream = PdfStream . tree_to_stream ( treeOut )
contents . Filter = None
pdfOut . addPage ( page )
pdfOut . write ()보시다시피, 코드는 페이지를 통해 실행 된 다음 모든 페이지의 내용으로 실행 된 다음 내용을 압축 할 수 있으므로 내용을 압축 한 다음 내용 스트림을 트리로 구문 분석하고 BT/ET 텍스트 블록을 제거한 다음 결과 트리를 다시 구문으로 구문으로 구문을줍니다. 위의 각 코드 라인의 의미는 아마도 Toarray Lambda 함수와는 별도로 명확해야합니다. PDF의 페이지에는 둘 이상의 내용 사전을 가질 수 있기 때문에 PDFARRAY. 따라서 ToArray Lambda 기능은 Page를 전환하여 페이지 내용의 상황을보다 균일하게 만듭니다.
다른 것들도 주목해야합니다. First, note that in order to acomplish the task the code uses just two new classes from pdfrwx : PdfFilter and PdfStream, with one/two function calls from each. 둘째, 구문 분석 된 트리 I 단지 중첩 된 표준 파이썬 목록 : 다음 사소한 형식 :
[
['q', []],
['cm', ['1','0','0','1','0','0']],
...
['BT', [], [ /a tree list of text operators/ ]],
...
['Q', []]
]
따라서 트리 목록의 각 잎 (요소)은 2 또는 3 요소의 목록입니다. 첫 번째 두 요소는 명령과 인수 목록 (명령에 인수가없는 경우 빈 목록)이며, 세 번째 선택적 인수는 잎이 명령 블록 인 경우에 블록을 구성하는 명령의 트리 목록입니다. 설계별로, 구문 분석 트리의 명령 이름 'bt'를 사용하는 Bt/et 텍스트 블록과 구문 분석 된 트리의 명령 이름 'BI'를 사용하는 BI/ID/EI 인라인 이미지 블록의 두 가지 유형의 블록이 있습니다. 원래 PDF 스트림에는 일련의 명령이 있습니다. 편의를 위해 출력에 이러한 블록을 생성하는 것은 PDFStream 파서입니다. 스트림 파서의 출력 구조에 익숙해 지려면 파서로 호출 한 직후 Pprint (Treein)와 같은 명령을 삽입하십시오.
Note also that the toArray function, however useful, has not been implemented in the module, and so you have to code it every time you do the parsing. 이것은 이상하게 들릴지 모르지만 동일한 디자인 원칙의 결과입니다. 모듈은 단지 스트림을 구문 분석합니다. 다른 모든 것을 코딩하는 개발자에게 달려 있습니다.
PDFStream Parser 클래스는 David Beazley의 인기있는 (그리고 순수한 파이썬!) Sly Parser Generator Library의 도움으로 약 300 줄의 코드를 사용하여 순수한 파이썬으로 구현됩니다. YT에 대한 강의를 확인하십시오. 그는 훌륭합니다! 호기심을 위해 : 파서는 두 개의 파서 상태를 사용합니다 (즉, 작동 할 때 자체적으로 전환하는 문법이 다른 두 개의 다른 파서), 하나는 PDF 문자 문자열 (즉 괄호 안에있는 문자열) 및 다른 모든 것에 대해 사용합니다. 그렇습니다. 문자 그대로 문자열이 문자열의 일부로 인코딩 괄호를 지원하기 위해 PDF 문자 그대로 문자열의 형식은 복잡 해져서 그것들을 구문 분석하기 위해서는 별도의 파서가 필요했습니다. 따라서 어떤 이유로 (속도?) 다른 파서 생성기 라이브러리를 사용하여 스트림 파서를 구현하려면 파서 상태의 스택을 지원하십시오.
글꼴을 해결합니다. 문서가 곧 나오면 계속 지켜봐 주시기 바랍니다.
지원 필터 :
이미지 수출의 색상 정확도에있어 Adobe의 자체 제품 버그에 지쳤습니까? 그런 다음 당신은 올바른 장소에 왔습니다! 가장 정확한 PDF 이미지 조작 클래스가되는 것을 목표로합니다. 문서가 곧 나오면 계속 지켜봐 주시기 바랍니다.
지원되는 코덱 (Encode/Decode) :
지원되는 색상 공간 :
을 더한:
이 모듈은 현재 완벽하게 사용할 수 있으며, 수많은 테스트를 통해 실행되어 올바르게 약속하는 작업을 수행 할 수 있습니다. 그러나 그것은 알파 근처에 있지 않습니다. 인터페이스는 아직 완전히 마무리되지 않았습니다. 또한 오류 처리가 끊어졌습니다 (아마도 곧 수정되어 PDFRW 에서 오류가 처리되는 방식과 유사하게 만들어집니다). 그래서 자신의 위험에 따라 놀아요 위험이 없지만 아직 생산 품질이 될 것으로 기대하지 마십시오.