เกิดอะไรขึ้นจริง ๆ เมื่อคุณบีบอัด PDF
PDF123 Compress ใช้ qpdf บีบอัดสตรีมซ้ำและแพ็กออบเจกต์เป็น object stream โดยไม่ลดความละเอียดภาพ ไม่เข้ารหัส bitmap ใหม่เป็น JPEG คุณภาพต่ำลง และไม่ตัดฟอนต์ ส่วน linearization แทบไม่เปลี่ยนขนาดไฟล์

PDF สองไฟล์อาจดูเหมือนกันบนหน้าจอ แต่ขนาดต่างกันได้ถึงสามอันดับขนาด: 50 KB กับ 50 MB ช่องว่างนี้แทบไม่เคยอยู่ที่ตัวดำเนินการข้อความ ในสัญญา 20 หน้า ตัวดำเนินการเหล่านี้มักมีเพียงไม่กี่สิบกิโลไบต์ ส่วนที่เหลือคือตัวอย่างภาพ ไฟล์ฟอนต์ที่ฝังมาทั้งชุด และความแน่นของการแพ็กสตรีมกับออบเจกต์
ผลที่ตามมาจึงควรพูดไว้ตั้งแต่ต้น: "การบีบอัด PDF" ไม่ใช่การกระทำเดียว แต่เป็นสี่อย่างที่ต่างกัน แต่ละอย่างย่อสิ่งที่ต่างกันและมีราคาต่างกัน พอเอามารวมเป็นเรื่องเดียว ประสบการณ์ที่ได้จึงขัดกันเอง: ไฟล์ถูกบีบอัดแล้วแต่ไม่เล็กลง หรือเล็กลงจริงแต่หน้าเสียความคม
ขนาดที่เพิ่มขึ้นมาจากไหน
กรณี "ทำไม PDF ไฟล์นี้ถึงใหญ่จัง" ส่วนใหญ่เริ่มจากไฟล์สแกนหรือภาพถ่ายความละเอียดสูงที่ยังฝังอยู่ในขนาดที่ถ่ายมา ลองคิดเลขสักครั้ง: กระดาษ Letter 8.5 × 11 นิ้ว สแกนที่ 300 DPI ได้ราว 2550 × 3300 พิกเซล และที่สามไบต์ต่อพิกเซล นั่นคือราว 25 MB เมื่อยังไม่บีบอัด ยี่สิบหน้าแบบนี้มักแตะ 60 ถึง 80 MB ก่อนที่ใครจะแตะการบีบอัดเสียอีก
แหล่งที่สองคือฟอนต์ PDF สามารถฝังโปรแกรมฟอนต์ทั้งชุดเพื่อให้เครื่องใดก็ตามแสดงข้อความได้เหมือนกัน และราคาของมันคิดตามขนาดตาราง glyph ไม่ได้คิดตามปริมาณข้อความที่ถูกอ่านจริง นี่คือเหตุผลที่การตัดฟอนต์ให้เหลือเฉพาะที่ใช้เป็นคันโยกขนาดอีกตัวที่แยกออกไป
แหล่งที่สามคือการแพ็กเอง เนื้อหาเดียวกันอาจถูกเก็บด้วยการตั้งค่าบีบอัดที่สิ้นเปลือง หรือออบเจกต์ของมันอาจกระจัดกระจายอยู่ทั่วไฟล์ แต่ละตัวมีค่าใช้จ่ายในการทำบัญชีของตัวเอง สิ่งเหล่านี้ไม่เปลี่ยนแม้แต่พิกเซลหรือ glyph เดียว และนี่คือส่วนที่การบีบอัดสตรีมซ้ำเอื้อมถึงพอดี
"Compress" คือสี่สิ่งที่ต่างกัน
ขนาดมีคันโยกสี่ตัว แต่ละตัวทำงานคนละชั้น และราคาของมันแทบไม่ทับซ้อนกัน การเลือกคันโยกผิดคือสาเหตุที่พบบ่อยที่สุดที่ทำให้การบีบอัดดูเหมือนไม่ได้ทำอะไรเลย
| คันโยก | สิ่งที่แตะ | ผลต่อขนาด | ราคา |
|---|---|---|---|
| การบีบอัดสตรีมซ้ำและ object stream | วิธีบีบอัด content stream และวิธีเก็บกับแพ็กออบเจกต์ | ขึ้นกับว่าไฟล์ต้นฉบับหลวมแค่ไหน | รูปลักษณ์หน้าจึงไม่เปลี่ยน |
| การลดความละเอียดภาพ | จำนวนพิกเซล หรือก็คือความละเอียด | มาก | ความละเอียดลดลงอย่างถาวร |
| การเข้ารหัสภาพใหม่แบบสูญเสีย | การแทนค่าบิตของ bitmap | มาก | คุณภาพภาพลดลง |
| การตัดฟอนต์ให้เหลือ glyph ที่ใช้ | ตาราง glyph ที่ฝังอยู่ | ปานกลาง | glyph ที่ไม่ได้ใช้แก้ไขไม่ได้อีก |
| Linearization | ลำดับของออบเจกต์ | เกือบศูนย์ | แลกมาเป็นเวลาโหลดหน้าแรก |
สี่แถวแรกมักถูกเรียกรวม ๆ ว่า "การบีบอัด" แต่มีเพียงแถวแรกที่ไม่แตะเนื้อหา และเป็นแถวที่ประเมินผลตอบแทนผิดได้ง่ายที่สุดด้วย: ไฟล์สแกนที่ขนาดส่วนใหญ่มาจากตัวอย่างภาพดิบเหลือความซ้ำซ้อนให้กำจัดน้อยมาก และคันโยกที่จะย่อมันได้จริงคือการลดความละเอียดกับการเข้ารหัสใหม่แบบสูญเสีย โดยแลกกับการสูญเสียความละเอียดและคุณภาพนั้นไปตลอด
ในสี่อย่างนี้ PDF123 Compress ทำอย่างไหน
บีบอัด PDF (POST /api/v1/misc/compress-pdf) ทำเฉพาะแถวแรก โดยเรียก qpdf ให้บีบอัดสตรีมที่ยังไม่ถูกบีบอัด (--compress-streams=y) ผ่านสตรีมที่บีบอัดด้วย Flate อยู่แล้วอีกรอบ (--recompress-flate) และแพ็กออบเจกต์เข้า object stream (--object-streams=generate)
มันไม่ลดความละเอียดภาพ ไม่เข้ารหัส bitmap ใหม่เป็น JPEG คุณภาพต่ำลง และไม่ตัดฟอนต์ หน้าจึงควรดูเหมือนเดิม และส่วนที่ประหยัดได้มาจากการบีบอัด Flate ซ้ำและการแพ็ก object stream
เงื่อนไขที่ทำให้ไม่ได้ผลก็ควรพูดให้ชัดเท่ากัน เมื่อขนาดของไฟล์ส่วนใหญ่เป็นข้อมูลภาพที่บีบอัดเป็น JPEG อยู่แล้ว Flate ไม่เหลืออะไรให้บีบ เพราะไบต์ของภาพเหล่านั้นอยู่นอกเหนือสิ่งที่สวิตช์สามตัวข้างบนแตะถึง นี่คือเหตุผลที่แพ็กสแกนอาจกลับมาเล็กลงเพียงไม่กี่เปอร์เซ็นต์ ขณะที่ PDF ที่เน้นข้อความขนาดใกล้เคียงกันได้ผลมากกว่าอย่างเห็นได้ชัด
เส้นทางย้อนกลับคือ แตกไฟล์ PDF ซึ่งขยายสตรีมเพื่อตรวจดู (--qdf และปิด object stream) และก็ไม่เปลี่ยนรูปลักษณ์ของหน้าเช่นกัน
เมื่อไรเส้นทางอื่นคือคำตอบที่ถูก
| สิ่งที่คุณต้องการ | เส้นทางที่ควรใช้ |
|---|---|
| รูปลักษณ์เหมือนเดิม แค่เอา overhead ของการแพ็กออก | บีบอัด |
| แพ็กสแกนที่ใหญ่เกินไปจริง ๆ และยอมรับการสูญเสียคุณภาพได้ | ลดความละเอียดหรือเข้ารหัสใหม่แบบสูญเสีย ไม่ใช่ Compress นี้ |
| ยังแก้ไขได้ แต่ตัวอักษรตัวถัดไปพิมพ์ไม่ออก | ตั้งค่าส่งออกหรือไฟล์ต้นทางอื่น ดูการตัดฟอนต์ |
| อยากให้เบราว์เซอร์เห็นหน้าแรกเร็วขึ้น | Linearization แก้การวาดหน้าแรก ไม่ได้แก้ขนาด |
| ไฟล์เปิดไม่ขึ้นเลย | ซ่อมไฟล์ นั่นเป็นปัญหาโครงสร้าง ไม่ใช่ปัญหาขนาด |
มีกับดักอยู่ในแถวสุดท้าย: Linearize PDF ไม่ใช่การติดตั้งแยกต่างหาก แต่เป็นชื่อเรียกอีกชื่อของ Compress ทั้งคู่ชี้ไปที่การดำเนินการเดียวกัน โดย id มาตรฐานคือ misc/compress-pdf และ linearize-pdf เป็นเพียง alias พอร์ทัลส่ง linearize=true และ optimizeLevel=1 เสมอสำหรับเครื่องมือนี้ เซิร์ฟเวอร์ไม่อ่านทั้งสองฟิลด์ และ qpdf ไม่เคยได้รับ --linearize ส่วนการดำเนินการที่ linearize ไฟล์จริง ๆ คือ Protect ตอนที่มันเข้ารหัส
ดังนั้นถ้าต้องการรูปลักษณ์เดิมในไฟล์ที่เล็กลง บีบอัด คือคำตอบทั้งหมด ถ้าต้องการย่อภาพแบบสูญเสียหรือตัดฟอนต์ เส้นทางนี้เป็นคันโยกที่ผิด ไฟล์จะกลับมาถึงคุณทันทีโดยไม่ต้องมีบัญชี หากอยากเห็นว่าออบเจกต์ สตรีม และตาราง cross-reference อยู่ตรงไหนจริง ๆ อ่านต่อที่ข้างใน PDF มีอะไร