跳至主要內容
全球國際徵信顧問
案件指揮艙全部本機工具
V236 / OPERATING GUIDE

先讀範圍,再決定 PDF 要讀、要轉,還是要遮。

PDF 工坊只在你的瀏覽器內處理檔案:不上傳、不使用瀏覽器儲存空間。本頁說明它做什麼、不做什麼、輸出檔怎麼組成、如何自行驗證,以及最常被誤解的地方。

READ FIRST

先說清楚這不是什麼

這不是加密,不是數位簽章,也不是檔案真偽的鑑定。遮蔽後的檔案沒有密碼,拿到的人都能打開,看見所有沒被框起來的地方。
TEXT / EXTRACT

讀文字

逐頁讀出 PDF 文字層裡的文字,附頁碼,可搜尋、複製與下載。

做什麼
  • 用 pdf.js 一次處理一頁,每頁之間讓出畫面,可隨時取消。單檔上限 100 MiB、500 頁;抽出的文字合計上限 500 萬字,超過時會明確告知,不會悄悄截斷。
  • 逐頁標示「有文字」「文字很少」(少於 10 個非空白字元)「無文字層」「疑似亂碼」,並列出沒有文字層的頁碼。掃描檔沒有文字層,請改用本站的 本機 OCR 工具。
  • 全文搜尋(至多 200 字):顯示命中次數與分布的頁碼,並在內文標出。比對時全形與半形、大小寫視為相同。
  • 複製全部文字、下載 TXT、下載 JSON(含頁碼、每頁字數與判定類型)。
  • 「送到線索推理艙」:只在你的瀏覽器內,把文字傳給本站的另一個分頁,不經過任何伺服器。需要你點按,也需要允許開啟新視窗;送不出去時請改用複製。
不做什麼
  • 不做 OCR,不辨識圖片裡的字。
  • 不還原版面。表格與欄位的順序,以 PDF 內部記錄的文字順序為準,可能和畫面上看到的不同。
  • 不上傳、不聯網、不使用任何瀏覽器儲存空間;關閉或重新整理頁面,畫面上的內容就消失。
規則細節
  • 文字來自 PDF 內嵌的文字層,不是畫面上看到的字。有些 PDF(例如部分瀏覽器列印出來的中文)會把字對應到「康熙部首」等相容區的字元;本工具會把這幾個區段轉成一般字元再顯示與搜尋,仍可能與你看到的不同,這類頁面會被標為疑似亂碼。
  • 搜尋時逐字做 NFKC 正規化並轉小寫,再把命中位置換算回原文,所以全形數字、英文字母也搜得到。
  • 疑似亂碼的判斷:非空白字元中,有超過 20% 是替代字元、私用區字元或控制字元。這只是粗略的提醒,不是辨識準確度。
如何自行驗證
  • 用另一個程式讀同一份檔,抽樣比對,例如:pdftotext -layout 檔名.pdf -。兩者的換行與順序可能不同,字句應該相同。
  • 下載的 JSON 格式為 gib-pdf-text-1,每頁一筆,含 page、kind、chars、text,可用任何程式讀取檢查。
常見誤解
  • 「沒抽到字」不等於「這頁沒有字」:很可能是掃描影像。
  • 「抽到的字」不等於「畫面上看得到的字」:文字層可能是隱藏的(例如 OCR 後的掃描檔),位置也可能與畫面有落差。
  • 匯出的 TXT 與 JSON 含檔名與全部文字,分享前請自行檢查是否含個資。
開啟這項工具
IMAGE / EXPORT

轉成圖片

把選定的頁面畫成 PNG 或 JPEG,逐頁下載,或打包成 ZIP。

做什麼
  • 頁面範圍可寫成 1-3,5,8-10,或輸入「全部」。解析度可選 72、96、150、200 DPI。
  • 單頁超過 1,600 萬像素(或單邊超過 16,384 像素)時,會自動降低解析度,並在每一頁旁標示實際用了多少;降到約 24 DPI 以下仍放不下的頁面會被略過並說明原因。
  • PNG 無損、檔案較大;JPEG 檔案較小,有輕微壓縮。
  • ZIP 是自己寫的「僅封裝、不壓縮」格式(圖片本身已經壓縮),檔名以 UTF-8 儲存,並計算 CRC-32。圖片合計超過 400 MiB 時會停止並告知,請縮小範圍或降低 DPI 後分批轉換。
不做什麼
  • 不遮蔽任何內容;轉出的圖片就是頁面原樣(含表單欄位目前的值)。要遮蔽請用「安全遮蔽」。
  • 不保留文字層、連結、書籤或註解的互動功能。
  • 不上傳、不使用瀏覽器儲存空間。
規則細節
  • 像素尺寸 = 頁面可見範圍(已考慮 CropBox、旋轉與 UserUnit)的點數 × DPI ÷ 72,四捨五入。
  • pdf.js 以列印模式畫在白色底上,所以透明背景會變成白色。
如何自行驗證
  • 用 unzip -t 檔名_圖片.zip(或任何解壓縮程式)檢查 ZIP,應該全部 OK。
  • 用任何看圖程式開啟,並與原 PDF 在閱讀器中的樣子比對。不同閱讀器的字型與色彩處理略有差異是正常的。
常見誤解
  • DPI 越高不代表越好:檔案與記憶體用量會隨之快速增加,手機上請從 96 或 150 開始。
  • 轉成圖片後文字就無法複製,但不代表資料已被去識別化;圖片裡的內容仍然看得見。
開啟這項工具
REDACT / RASTERIZE

安全遮蔽並影像化

在頁面上框出要遮住的地方,輸出一份每頁只有一張影像的新 PDF,並在本機立即自我檢查。

做什麼
  • 用滑鼠或手指在頁面上拖曳畫框;框可以拖動、用四角調整大小,也可以用鍵盤移動與刪除。可復原、清除本頁的框,或把某個框的位置套用到所有頁。
  • 可先掃描文字層裡的電話、Email、身分證樣式與長數字,在頁面上用橘色虛線標出;每一處都由你決定遮或不遮,不會自動套用。
  • 每頁最多 200 個框、全檔最多 5,000 個框;DPI 可選 72、96、150、200;影像格式可選 JPEG 或 PNG(Flate 壓縮)。
  • 輸出檔名建議為「原檔名_遮蔽版.pdf」,只是建議,可自行修改。
  • 輸出後做 9 項自我檢查,並計算 SHA-256 與大小;全部通過才提供下載,任何一項沒過就不提供下載並說明原因。檢查通過後,可在頁面內逐頁檢視輸出檔,並顯示已檢視幾頁。
不做什麼
  • 不加密、不簽章、不加浮水印、不產生任何密碼;輸出檔沒有文字層,無法搜尋或複製,通常比原檔大。
  • 不修改原檔,也不覆蓋原檔:輸出一律是新檔案。
  • 不自動決定要遮什麼。自動掃描只標記,不套用;掃描不到圖片、表單欄位與註解裡的字。
  • 不輸出解密後的副本;不繞過密碼或使用限制。檔案若宣告了「不允許複製或列印」之類的限制,要先由你勾選確認有權處理,才會繼續。
  • 不保留原檔的書籤、連結、註解、附件、表單、JavaScript、標題、作者、XMP 等任何中繼資料。
規則細節:最小 PDF 是怎麼組成的
  • 座標:框以頁面「顯示方向」的比例(0 到 1,左上角為原點)記錄,所以放大縮小、換 DPI 都不會跑掉。輸出時換算成輸出影像的像素,向外取整,並再往外多留約 0.75 倍縮放比例(至少 1 像素)的邊,避免字的邊緣露出一圈。
  • 繪製順序:先用 pdf.js 把整頁畫到畫布(含表單欄位目前的值),再直接把框內的像素改成純黑,然後才編碼成 JPEG 或 PNG。框內被蓋掉的內容在編碼前就已不存在,不是「蓋在上面」;JPEG 壓縮只會讓框的邊緣有輕微暈開。
  • 檔案結構:由本頁自行撰寫的最小寫出器產生,不使用任何 PDF 函式庫:
    %PDF-1.4  + 一行二進位註解
    1 0 obj  目錄(Catalog)          → /Pages 2 0 R
    2 0 obj  頁面樹(Pages)          → /Kids [4 0 R 7 0 R …] /Count n
    3 0 obj  資訊字典(Info)         → 只有 /Producer 與 /CreationDate
    每一頁固定 3 個物件(第 i 頁為 4+3i、5+3i、6+3i):
      頁面    /MediaBox [0 0 寬 高]  /Resources << /XObject << /Im0 … >> >>  /Contents …
      內容串流  q 寬 0 0 高 0 0 cm /Im0 Do Q
      影像    /Subtype /Image  /ColorSpace /DeviceRGB  /BitsPerComponent 8
              JPEG:/Filter /DCTDecode(直接存放編碼後的 JPEG)
              PNG 選項:/Filter /FlateDecode  /DecodeParms << /Predictor 15 … >>
    xref 傳統交叉參照表(每筆 20 位元組)
    trailer << /Size n /Root 1 0 R /Info 3 0 R >>   startxref   %%EOF
    沒有字型、沒有文字運算子、沒有註解、附件、JavaScript、表單、動作、物件串流、增量更新、加密或 XMP;頁面也沒有 /Rotate。
  • 頁面尺寸:等於原頁的可見範圍:已考慮 CropBox、頁面旋轉(輸出為旋轉後看到的方向,不再帶 /Rotate)與 UserUnit。自我檢查會用 pdf.js 把輸出檔每頁的尺寸與原頁逐頁比對(誤差小於 0.01 pt)。
  • 自我檢查的 9 項:① xref 偏移全部吻合,檔案內每個位元組都屬於標頭、物件、xref 或 trailer;② 物件字典中沒有 /JS、/JavaScript、/EmbeddedFile、/Annots、/OpenAction、/AcroForm;③ 所有名稱都在允許清單內;④ 每頁只有一個影像物件與一段「畫影像」的內容串流;⑤ pdf.js 重新開啟成功,頁數相同;⑥ 逐頁呼叫 getTextContent(),文字項目為 0;⑦ 註解、附件、表單欄位、JavaScript 都沒有;⑧ 頁面尺寸與原頁相同;⑨ 重新畫出輸出檔,取樣框內像素,確認是黑色。
如何自行驗證
  • 用你信任的另一組工具,不依賴本站任何程式。先確認檔案與工具顯示的 SHA-256 一致,再確認沒有文字、沒有主動內容:
    # 1. 檢查碼與結構
    sha256sum 檔名_遮蔽版.pdf          # 與頁面上顯示的 SHA-256 比對
    qpdf --check 檔名_遮蔽版.pdf
    
    # 2. 沒有文字:預期只剩換頁字元(每頁 1 個)
    pdftotext 檔名_遮蔽版.pdf - | wc -c
    
    # 3. 物件結構裡沒有 JavaScript、附件、註解等(--json 不含串流資料,不會被影像的位元組誤判)
    qpdf --json --json-key=qpdf 檔名_遮蔽版.pdf | grep -c -E '"/(JS|JavaScript|EmbeddedFile|Annots|OpenAction|AcroForm|Font)"'
    # 預期輸出 0
  • 用 Python(pikepdf 與 pypdf)逐頁檢查:
    import pikepdf
    from pypdf import PdfReader
    path = "檔名_遮蔽版.pdf"
    pdf = pikepdf.open(path)
    print("資訊字典:", {k: str(v) for k, v in pdf.docinfo.items()})   # 只有 /Producer 與 /CreationDate
    for k in ("/Names", "/AcroForm", "/OpenAction", "/AA", "/Metadata", "/Outlines"):
        assert k not in pdf.Root, k
    for n, page in enumerate(pdf.pages, 1):
        res = page.Resources
        assert "/Font" not in res and "/Annots" not in page, n
        imgs = list(res.get("/XObject", {}).values())
        assert len(imgs) == 1 and imgs[0].Subtype == "/Image", n
        print(n, [float(x) for x in page.MediaBox], imgs[0].Width, imgs[0].Height, imgs[0].Filter)
    r = PdfReader(path)
    assert sum(len(p.extract_text() or "") for p in r.pages) == 0
    print("沒有文字層,共", len(r.pages), "頁")
  • 把你遮蔽的原文(例如電話號碼)拿去搜尋輸出檔:grep -a -c "0912" 檔名_遮蔽版.pdf 預期為 0;也可以用任何 PDF 閱讀器的搜尋功能,預期找不到。這只能證明「文字不在檔案裡」,不能證明「影像裡沒有露出」,後者要靠你的眼睛。
  • 把輸出檔轉成圖片,與你標的框逐頁比對;最後再用不同的閱讀器開啟看一次。
常見誤解
  • 「黑色方塊蓋上去就是刪掉了。」不是。蓋在上面的方塊底下仍有原文,複製貼上、搜尋、解壓縮內容串流都可能讀回來。本工具改為把框內的像素改成黑色,再輸出沒有文字層的影像版,原文不會留在檔案裡。
  • 「輸出是影像,所以一定安全。」不是。沒被框到的字都還在影像裡;框偏了、框小了、漏了某一頁,字就會露出來。頁首頁尾、浮水印、圖章、手寫字、縮小的附註也常被漏掉。
  • 「9 項檢查通過就可以放心分享。」檢查只能證明檔案「乾淨」,不能證明你「框對」。請用頁面內的逐頁檢視,把每一頁都看過。
  • 「OCR 可以還原被遮住的字。」被框住的像素已經是純黑,OCR 無從還原;但沒被框住的字,OCR 可以讀出,輸出檔也可能被別人再 OCR 成可搜尋的文字。
  • 「檔名有 _遮蔽版 就代表處理過。」檔名只是建議;是否處理過,以檔案內容與你自己的檢查為準。
  • 「輸出檔會比較小。」通常相反:每頁是一張影像,比原本的文字與向量圖大,而且無法搜尋、複製。
  • 「SHA-256 相同就代表內容沒被動過。」只代表位元組相同,與內容是否真實無關。
開啟這項工具
MEASURED / SMALL SAMPLE

實測參考(本機沙箱小樣本)

下列數字是在開發用的沙箱環境,以 Chromium 小量樣本實測得到,只說明這個工具在該環境的表現,不代表你的裝置;不是規格,也不是承諾。

項目條件結果
開檔+文字層檢查3 頁中文檔0.61 秒
開檔+文字層檢查100 頁1.2 秒
開檔+文字層檢查500 頁(簡單文字頁)1.2 秒
讀文字100 頁0.17 秒
轉成圖片100 頁、72 DPI、JPEG2.6 秒
轉成圖片100 頁、72 DPI、PNG2.6 秒
安全遮蔽輸出(含自我檢查)100 頁、200 個框、JPEG 150 DPI9.2 秒,輸出 12.0 MiB
安全遮蔽輸出(含自我檢查)100 頁、200 個框、PNG 96 DPI9.2 秒,輸出 5.93 MiB
安全遮蔽輸出(含自我檢查)100 頁、200 個框、JPEG 200 DPI13.6 秒,輸出 18.3 MiB
記憶體上列 JPEG 150 DPI 的輸出期間JavaScript 堆積 17 → 尖峰 20 MB;瀏覽器全部程序合計 637 → 尖峰 1,119 MB
取消輸出到 24 / 100 頁時按「取消」0.10 秒內停止,畫面顯示「已取消,沒有產生檔案。」
主執行緒長任務一般頁面的全部步驟超過 100 毫秒的有 0 個(最長 82 毫秒)
極大頁面A0 尺寸頁(需自動降低解析度)輸出 1.0 秒;主執行緒出現 113、107 毫秒的長任務(已知限制)
超過單頁上限14400 × 14400 pt 的頁面直接拒絕並說明原因,不產生檔案
CPU 降為 1/4 速度開檔+文字層檢查,3 頁 / 100 頁1.1 秒 / 3.6 秒
CPU 降為 1/4 速度掃描可疑文字,100 頁2.1 秒
CPU 降為 1/4 速度3 頁遮蔽輸出,JPEG / PNG 150 DPI1.3 秒 / 2.1 秒
CPU 降為 1/4 速度20 頁、40 個框、JPEG 150 DPI8.3 秒,輸出 2.39 MiB
CPU 降為 1/4 速度上列 20 頁輸出的記憶體JavaScript 堆積 19 → 尖峰 20 MB;瀏覽器全部程序合計 586 → 尖峰 760 MB
CPU 降為 1/4 速度主執行緒長任務最長 132 毫秒(出現在「開檔」步驟),其餘步驟最長 81 毫秒

環境:2 核心、Chromium 141(無頭模式);測試時機器上可能同時有其他工作(開始時的 1 分鐘負載平均:一般速度 1.84、降速 1.46)。「降為 1/4 速度」是用瀏覽器的開發者工具協定模擬,不等於真實的低階手機。每項只量一到數次,不具統計意義;記憶體數字含瀏覽器本身,會隨作業系統與瀏覽器版本而不同。長任務指主執行緒連續忙碌超過 50 毫秒的片段;超過 100 毫秒時,畫面可能短暫停頓。

建議的使用流程

  1. 保留原檔,不要覆蓋;輸出一律另存新檔。
  2. 先到「讀文字」看這份 PDF 有沒有文字層;掃描檔沒有文字層,自動掃描對它無效,要自己畫框。
  3. 到「安全遮蔽」,先按「掃描可疑文字」,逐一決定遮或不遮;再逐頁自己看一遍,補上掃描找不到的地方(圖片、手寫、圖章、頁首頁尾、浮水印)。
  4. 輸出設定先用 150 DPI 的 JPEG;手機記憶體有限時降到 96 或 72,或分段輸出頁面範圍。
  5. 等 9 項自我檢查跑完,再用頁面內的檢視逐頁看過輸出檔,確認每個該遮的地方都是黑的。
  6. 用上面的指令或 Python,自己再驗證一次;把遮蔽版與原檔分開存放,只分享遮蔽版。
  7. 是否適合對外提供、是否符合法令或契約,請諮詢律師或專業人員。

已知限制與不確定處