ส่วนขยายของไลบรารี PDFRW ที่ยอดเยี่ยมที่เพิ่มการจัดการสตรีมเนื้อหา (และวัตถุทั้งหมดที่อ้างอิงในนั้นเช่นรูปภาพแบบอักษร ฯลฯ ) ในขณะที่ทำให้มันง่ายที่สุดเท่าที่จะทำได้
ดังนั้นทำไมขยาย PDFRW เมื่อมีไลบรารี PDF เต็มรูปแบบเช่น PYPDF? ลองคิดดูด้วยวิธีนี้: ไลบรารี PDF ส่วนใหญ่พยายามจัดทำฟังก์ชั่นที่ทำให้งานประมวลผล PDF ทั่วไปง่ายขึ้น ห้องสมุดเหล่านี้ดีมากในสิ่งที่พวกเขาทำ แต่ในขณะที่งานเกิดขึ้นที่ต้องใช้ฟังก์ชั่นใหม่ ตอนนี้หากคุณเป็นนักพัฒนาที่อยู่ในสถานการณ์เช่นนี้คุณต้องเริ่มขุดลงในซอร์สโค้ดจำนวนมากของไลบรารีเหล่านี้
วิธีการของ PDFRW นั้นแตกต่างกัน: ลองแยก PDF ให้มากที่สุดเท่าที่จะเป็นไปได้ในขณะที่ทำให้ผลลัพธ์ง่ายที่สุดเท่าที่จะทำได้ ไม่ใช่ความคิดที่ไม่ดีโดยเฉพาะอย่างยิ่งเนื่องจากข้อเท็จจริงที่ว่าโมเดลวัตถุ PDF (ซึ่งเป็นเพียงพจนานุกรมพจนานุกรมที่มีค่าบางส่วนของพวกเขาที่อ้างอิงถึงพจนานุกรมอื่น ๆ ) เหมาะอย่างยิ่งสำหรับการทำแผนที่กับพจนานุกรม Python มาตรฐาน ยิ่งไปกว่านั้น PDFRW ยังใช้แนวคิดเบื้องหลังแพ็คเกจที่ยอดเยี่ยมอีกชุดหนึ่งเพื่อสร้างวัตถุ PDF ที่ผ่านการสำรวจได้ง่ายขึ้น: การเข้าถึงแบบอักษรหน้าสามารถทำได้เช่นนี้: ตอนนี้สามารถทำได้เช่นนี้:
for fontName , fontDict in page . Resources . Font . items ():
( do something )ขั้นตอนต่อไปคือการพยายามแยกวิเคราะห์สตรีมพจนานุกรม-นี่เป็นรายการพิเศษในพจนานุกรมที่มีสิ่งที่น่าสนใจ: ข้อความรูปภาพกราฟิกเวกเตอร์ ฯลฯ PDFRW ไม่ได้ทำอะไรเลยและมันก็ไม่ได้ทำตามวัตถุประสงค์: ตามปรัชญาที่เหมือน Unix โครงสร้างข้อมูลที่ผลิตเสร็จสมบูรณ์: มี PDF ทั้งหมดเพียงพอสำหรับงานการประมวลผลที่เป็นไปได้ และมันก็ง่ายพอที่ผู้พัฒนาสามารถเริ่มเขียนโค้ดได้ทันทีใช้เวลามากขึ้นเพลิดเพลินกับข้อความในบทประพันธ์ Magnum ของ Adobe และไม่มีใครเรียนรู้ห้องสมุดที่ซับซ้อนอื่น และในความเป็นจริง PDFRW เป็นเครื่องมือที่เหมาะสำหรับการเรียนรู้ไวยากรณ์ PDF โดยเล่นกับมัน!
โอเคถ้าคุณมาถึงจุดนี้แล้วโอกาสที่คุณจะสงสัย: งั้นฉันจะไปจากที่นี่ที่ไหน? โดยเฉพาะ: ฉันจะแยกวิเคราะห์สตรีมพจนานุกรมได้อย่างไร? นี่คือที่ PDFRWX สามารถช่วยได้: สามารถแยกวิเคราะห์พจนานุกรมสตรีมและทำสิ่งที่เป็นประโยชน์อื่น ๆ แต่สิ่งแรกก่อน:
PDFRWX อันดับแรกและสำคัญที่สุดพยายามที่จะรักษาปรัชญาของ PDFRW ที่ระบุไว้ข้างต้น ในการทำเช่นนี้จะเพิ่มการสังเกตว่าในงานประมวลผล PDF หลายครั้งเวลาส่วนใหญ่ใช้ในการพัฒนาโซลูชันซอฟต์แวร์และไม่ได้ใช้งาน สิ่งนี้นำไปสู่ตัวเลือกการออกแบบ:
ตอนนี้เราพร้อมที่จะดูว่า PDFRWX ทำอะไรและประสบความสำเร็จอย่างไร:
นี่คือ ตัวอย่าง/example-pdfstream.py ซึ่งอ่านตัวอย่าง pdf ลบเนื้อหาข้อความทั้งหมดออกจากทุกหน้าและเขียนผลลัพธ์ไปที่ตัวอย่างออก. 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 สามารถมีพจนานุกรมเนื้อหามากกว่าหนึ่งพจนานุกรมซึ่งในกรณีนี้ และฟังก์ชั่น Toarray Lambda ทำให้สถานการณ์ที่มีเนื้อหาของหน้ามีความสม่ำเสมอมากขึ้นโดยการเปลี่ยนหน้าหน้าซึ่งไม่ได้เป็นอาร์เรย์ลงใน PDFarray ด้วยองค์ประกอบเดียว
ต้องมีสิ่งอื่นอีกสองสามอย่างเช่นกัน ก่อนอื่นโปรดทราบว่าในการดำเนินการตามงานรหัสใช้เพียงสองคลาสใหม่จาก PDFRWX : PDFFILTER และ PDFStream โดยมีการเรียกใช้ฟังก์ชันหนึ่ง/สองรายการจากแต่ละฟังก์ชัน ประการที่สองต้นไม้ที่แยกวิเคราะห์ฉันเป็นเพียงรายการงูเหลือมมาตรฐานที่ซ้อนกันของรูปแบบเล็กน้อยต่อไปนี้:
[
['q', []],
['cm', ['1','0','0','1','0','0']],
...
['BT', [], [ /a tree list of text operators/ ]],
...
['Q', []]
]
ดังนั้นแต่ละใบ (องค์ประกอบ) ของรายการต้นไม้จึงเป็นรายการขององค์ประกอบ 2 หรือ 3 องค์ประกอบ: สององค์ประกอบแรกคือคำสั่งและรายการอาร์กิวเมนต์ (รายการว่างถ้าคำสั่งไม่มีอาร์กิวเมนต์) ในขณะที่อาร์กิวเมนต์ตัวเลือกที่สามมีอยู่ในกรณีที่ใบไม้เป็นบล็อกคำสั่ง โดยการออกแบบมีเพียงสองประเภทของบล็อก: บล็อกข้อความ BT/ET ซึ่งใช้ชื่อคำสั่ง 'BT' ในต้นไม้ที่แยกวิเคราะห์และบล็อกอิมเมจ BI/ID/EI แบบอินไลน์ซึ่งใช้ชื่อคำสั่ง 'BI' ในต้นไม้ที่แยกวิเคราะห์ หมายเหตุว่าในสตรีม PDF ดั้งเดิมมีเพียงลำดับของคำสั่ง มันเป็นตัวแยกวิเคราะห์ PDFStream ที่สร้างบล็อกเหล่านี้ในผลลัพธ์เพื่อความสะดวก เพื่อทำความคุ้นเคยกับโครงสร้างของเอาท์พุทของตัวแยกวิเคราะห์สตรีมให้ลองใส่คำสั่งเช่น pprint (treein) ทันทีหลังจากการโทรไปยังตัวแยกวิเคราะห์
โปรดทราบว่าฟังก์ชั่น TOARRAY ยัง ไม่ ได้ใช้งานในโมดูลดังนั้นคุณต้องเขียนโค้ดทุกครั้งที่คุณแยกวิเคราะห์ สิ่งนี้อาจฟังดูแปลก แต่เป็นผลมาจากหลักการออกแบบเดียวกัน: โมดูลเพิ่งแยกวิเคราะห์กระแส; ขึ้นอยู่กับนักพัฒนาซอฟต์แวร์ที่จะเขียนโค้ดทุกอย่างอื่น
PDFStream Parser Class ถูกนำไปใช้ใน Pure Python โดยใช้รหัสประมาณ 300 บรรทัดด้วยความช่วยเหลือของห้องสมุดเครื่องกำเนิดไฟฟ้า Parser Parser ที่ได้รับความนิยม สำหรับคนที่อยากรู้อยากเห็น: ตัวแยกวิเคราะห์ใช้สองตัวแยกวิเคราะห์ (เช่นตัวแยกวิเคราะห์ที่แตกต่างกันสองตัวที่มีไวยากรณ์ที่แตกต่างกันซึ่งสลับระหว่างตัวเองขณะที่พวกเขาทำงาน) หนึ่งสำหรับการแยกวิเคราะห์สตริงตัวอักษร PDF (เช่นสตริงที่อยู่ในวงเล็บ) และอื่น ๆ - สำหรับทุกสิ่งอื่น ๆ อ๋อเพื่อให้สตริงตัวอักษรรองรับการเข้ารหัสวงเล็บซึ่งเป็นส่วนหนึ่งของสตริงรูปแบบของสตริงตัวอักษร PDF นั้นซับซ้อนมากจนต้องใช้ตัวแยกวิเคราะห์แยกต่างหากเพื่อแยกวิเคราะห์เหล่านั้น ดังนั้นถ้าด้วยเหตุผลบางอย่าง (ความเร็ว?) คุณจะต้องใช้ตัวแยกวิเคราะห์สตรีมโดยใช้ไลบรารีเครื่องกำเนิดไฟฟ้าแบบแยกวิเคราะห์อื่นตรวจสอบให้แน่ใจว่าสนับสนุนสแต็กสำหรับสถานะตัวแยกวิเคราะห์
แก้นรกแบบอักษร เอกสารเร็ว ๆ นี้คอยติดตาม
ตัวกรองที่รองรับ:
เบื่อกับข้อบกพร่องของผลิตภัณฑ์ของ Adobe เมื่อพูดถึงความแม่นยำของสีในการส่งออกภาพ? จากนั้นคุณมาถูกที่แล้ว! มุ่งมั่นที่จะเป็นคลาสการจัดการภาพ PDF ที่แม่นยำที่สุดของทั้งหมด เอกสารเร็ว ๆ นี้คอยติดตาม
ตัวแปลงสัญญาณที่รองรับ (ENCODE/DECODE):
ช่องว่างสีที่รองรับ:
บวก:
โมดูลสามารถใช้งานได้อย่างสมบูรณ์แบบในเวลานี้และดำเนินการผ่านการทดสอบจำนวนมากเพื่อให้แน่ใจว่ามันทำในสิ่งที่สัญญาว่าจะทำอย่างถูกต้อง อย่างไรก็ตามมันไม่ได้อยู่ใกล้กับอัลฟ่า: อินเทอร์เฟซยังไม่สรุปอย่างสมบูรณ์ ยิ่งไปกว่านั้นการจัดการข้อผิดพลาดจะเสีย (อาจได้รับการแก้ไขในไม่ช้าและทำคล้ายกับวิธีการจัดการข้อผิดพลาดใน PDFRW ) ดังนั้น, เล่นด้วยความเสี่ยงของคุณเอง ไม่มีความเสี่ยงอย่าคาดหวังว่าจะมีคุณภาพการผลิต