使用 Convert 將 .png 批次轉換為 .pdf 時出現問題

使用 Convert 將 .png 批次轉換為 .pdf 時出現問題
convert /home/bill/TempScan/*.png  myfile.pdf

給出錯誤訊息:

convert-im6.q16: not authorized `myfile.pdf' @ error/constitute.c/WriteImage/1037.

任何幫助,將不勝感激!

答案1

convert是一個強大的圖形轉換命令列工具。它對 PDF 的支援由 Ghostscript 提供。因為一個重大的Ghostscript 中的安全漏洞convert在版本 9.24 之前,作為權宜之計,已阻止使用PDF 文件。自 Ghostscript 9.24 版本以來,該問題已修復。雖然 Ghostscript 版本已更新為所有受支援的 Ubuntu 版本中的安全版本(目前從 Ubuntu 16.04 開始),但使用限制可能仍然存在。

策略文件是/etc/ImageMagick-6/policy.xml.您可以以 root 使用者身分編輯該檔案來變更策略。

消除所有使用限制

對於不運行網頁伺服器的桌面用戶來說,簡單地消除這些限制可能就足夠了。為此,可以刪除該文件,但更好的做法是透過重命名「將文件移出」。使用此命令,您將重新命名該檔案。因此,所有政策均被取消,但您仍可根據需要恢復:

sudo mv /etc/ImageMagick-6/policy.xml /etc/ImageMagick-6/policy.xmlout

要恢復原來的情況,只需重新命名原來的名稱即可:

sudo mv /etc/ImageMagick-6/policy.xmlout /etc/ImageMagick-6/policy.xml

請注意,移出策略檔案會降低系統安全性。

僅消除合併為 PDF 的限制

對於您的具體情況,gene_wood 在評論中指出可以透過註解一行來選擇性地放寬處理 PDF 文件的策略:

<policy domain="coder" rights="none" pattern="PDF" />

編輯文件,並在該行周圍放置註釋標記以停用此規則:

<!-- <policy domain="coder" rights="none" pattern="PDF" /> -->

如果您不想消除所有安全性策略,則可以這樣做。

答案2

作為釩張貼,您必須變更 ImageMagick 策略。

sudo vim /etc/ImageMagick-6/policy.xml

並更換線路

<policy domain="coder" rights="none" pattern="PDF" />

<policy domain="coder" rights="read|write" pattern="PDF" />

如果您只想允許寫入而不允許讀取,您也可以刪除read|上面一行中的部分。


順便說一句,對於那些對 ImageMagick 漏洞感興趣的人,這裡有 2 個資訊連結:

答案3

我不想重新放鬆 ImageMagick 的安全限制,而是使用圖像2pdf

它是專為此類用例而設計的。

如果您的優先順序是(按此順序),您應該使用 img2pdf:

  • 始終無損:PDF 中嵌入的圖像的每個像素始終具有與輸入完全相同的顏色訊息
  • 小的:如果可能,輸入影像和輸出 PDF 之間的檔案大小差異將僅是 PDF 容器本身的開銷
  • 快速地:如果可能,輸入影像將按原樣貼上到 PDF 文件中,無需對像素資料進行任何佔用 CPU 資源的重新編碼

傳統的轉換軟體(如 ImageMagick)將:

  1. 不是無損的,因為有損重新編碼為 JPEG
  2. 不小,因為對原始像素資料使用浪費的平面編碼
  3. 速度不快,因為輸入資料會被重新編碼

不必重新編碼輸入(在大多數常見情況下)的另一個優點是,img2pdf 能夠處理比其他軟體大得多的輸入,因為原始像素資料永遠不需要載入到記憶體中。

這應該是等效的命令:

img2pdf --out myfile.pdf /home/bill/TempScan/*.png 

如果由於某種原因,您無法做到這一點(例如,無法安裝新軟體包),則無損轉換的另一個潛在途徑是將convert圖像轉換為多頁 TIFF 文件,然後tiff2pdf從 libtiff 工具中使用。

答案4

這是一種更方便的方法,可以自動取得policy.xml 檔案的位置並對所有檔案執行搜尋/取代:

for file in `convert -list policy | grep "Path:" | grep -v built | sed 's/Path: \(.*\)/\1/g'`; do sed -i 's/domain="coder" rights="none" pattern="PDF"/domain="coder" rights="read|write" pattern="PDF"/g' $file; done

相關內容