Chuyển đổi PDF sang PNG


83

Tôi đang cố chuyển đổi một tệp PDF sang một hình ảnh PNG (ít nhất là trang bìa của một hình ảnh). Tôi đang giải nén thành công trang đầu tiên của PDF bằng pdftk. Tôi đang sử dụng imagemagick để thực hiện chuyển đổi:

convert cover.pdf cover.png

Điều này hoạt động, nhưng rất tiếc, cover.png được hiển thị không chính xác (một số đối tượng alpha trong PDF không được hiển thị đúng cách). Tôi biết ImageMagick sử dụng GhostScript để thực hiện chuyển đổi và nếu tôi thực hiện trực tiếp với gs, tôi có thể nhận được kết quả mong muốn, nhưng tôi muốn sử dụng thư viện chuyển đổi vì nó có các công cụ khác mà tôi muốn tận dụng.

Lệnh này trong GhostScript hoàn thành hình ảnh mong muốn:

gs -sDEVICE=pngalpha -sOutputFile=cover.png -r144 cover.pdf

Tôi tự hỏi có cách nào để chuyển các đối số thông qua chuyển đổi sang GhostScript hay tôi gặp khó khăn với việc gọi GhostScript trực tiếp?


2
Tại sao gọi GhostScript trực tiếp là một vấn đề?
kquinn

Nó thực sự không phải là vấn đề lớn. Tôi muốn chạy một số tham số khác thông qua chuyển đổi cùng một lúc và sẽ thật tuyệt nếu tôi có thể giữ tất cả trong một lệnh. Giữ cho mã của tôi sạch hơn và nhất quán hơn. Nó cũng có nghĩa là một tệp tạm thời ít hơn.
Adam


Sự khác biệt giữa cách bạn gọi gs và cách ImageMagick gọi nó là gì? Có thể đáng để báo cáo điều gì đó ngược dòng lên ImageMagick (lưu ý với những người theo dõi, cập nhật ghostcript cũng có thể hữu ích ...)
rogerdpack

Câu trả lời:


70

Bạn có thể sử dụng một dòng lệnh với hai lệnh ( gs, convert) được kết nối thông qua một đường ống, nếu lệnh đầu tiên có thể ghi đầu ra của nó vào stdout và nếu lệnh thứ hai có thể đọc đầu vào của nó từ stdin.

  1. May mắn thay, gs có thể ghi vào stdout ( ... -o %stdout ...).
  2. May mắn thay, chuyển đổi có thể đọc từ stdin ( convert -background transparent - output.png).

Vấn đề đã được giải quyết:

  • GS được sử dụng cho kênh alpha xử lý một hình ảnh đặc biệt,
  • chuyển đổi được sử dụng để tạo nền trong suốt,
  • được sử dụng để tránh ghi ra tệp tạm thời trên đĩa.

Giải pháp hoàn chỉnh:

gs -sDEVICE=pngalpha       \
   -o %stdout              \
   -r144 cover.pdf         \
   |                       \
convert                    \
   -background transparent \
   -                       \
    cover.png

Cập nhật

Nếu bạn muốn có một PNG riêng biệt trên mỗi trang PDF, bạn có thể sử dụng %dcú pháp:

gs -sDEVICE=pngalpha -o file-%03d.png -r144 cover.pdf

Thao tác này sẽ tạo các tệp PNG có tên page-000.png,, page-001.png... (Lưu ý rằng %d-counting dựa trên 0 - file-000.pngtương ứng với trang 1 của PDF, 001đến trang 2 ...

Hoặc, nếu bạn muốn giữ nền trong suốt của mình, đối với tệp PDF 100 trang, hãy

for i in {1..100}; do        \
                             \
  gs -sDEVICE=pngalpha       \
     -dFirstPage="${i}"      \
     -dLastPage="${i}"       \
     -o %stdout              \
     -r144 input.pdf         \
     |                       \
  convert                    \
     -background transparent \
     -                       \
      page-${i}.png ;        \
                             \
done

7
Điều này chỉ hoạt động đối với tôi nếu tôi thêm -dBATCH -dNOPAUSE -dQUIETvào các tùy chọn gs.
ford

@ford: Có nghĩa là bạn có phiên bản Ghostscript cũ. Các phiên bản gần đây có thể làm -o output.filevà điều này tự động và âm thầm cũng được thiết lập -dBATCH -dNOPAUSE -dQUIETcùng một lúc.
Kurt Pfeifle,

@ford: Tuy nhiên, tôi đã mắc lỗi đánh máy nghiêm trọng ở chỗ khác trong câu trả lời ở trên. Tôi tự hỏi tại sao nó đã 22 upvotes mặc dù điều đó :-)
Kurt Pfeifle

Tìm việc cho tôi nhưng tôi muốn tự động chuyển đổi pdf nhiều trang thành image_1.png, image_2.png ... Tôi có dễ dàng giải nén từng trang từ tệp pdf trước không?
Tarass

Ok, tôi đã tách các hình ảnh. Nhưng tôi muốn "-transparence trắng" làm tham số 'chuyển đổi' trong quá trình chuyển đổi. Tôi đã có thể làm điều đó với đường ống, nhưng không có?
Tarass

29

Trong số tất cả các lựa chọn thay thế có sẵn, tôi thấy Inkscape tạo ra kết quả chính xác nhất khi chuyển đổi PDF sang PNG. Đặc biệt là khi tệp nguồn có các lớp trong suốt, Inkscape đã thành công khi Imagemagick và các công cụ khác không thành công.

Đây là lệnh tôi sử dụng:

inkscape "$pdf" -z --export-dpi=600 --export-area-drawing --export-png="$pngfile"

Và ở đây nó được triển khai trong một tập lệnh:

#!/bin/bash

while [ $# -gt 0 ]; do

pdf=$1
echo "Converting "$pdf" ..."
pngfile=`echo "$pdf" | sed 's/\.\w*$/.png/'`
inkscape "$pdf" -z --export-dpi=600 --export-area-drawing --export-png="$pngfile"
echo "Converted to "$pngfile""
shift

done

echo "All jobs done. Exiting."

21

Để chuyển đổi pdf sang tệp hình ảnh, hãy sử dụng các lệnh sau:

Đối với PNG gs -sDEVICE=png16m -dTextAlphaBits=4 -r300 -o a.png a.pdf

Đối với JPG gs -sDEVICE=jpeg -dTextAlphaBits=4 -r300 -o a.jpg a.pdf

Nếu bạn có nhiều trang, hãy thêm vào tên % 03d gs -o a%03d.jpg a.pdf

Ý nghĩa của mỗi tùy chọn:

  • sDEVICE = {jpeg, pngalpha, png16m ...} - filetype
  • -o - tệp đầu ra (% stdout thành stdout)
  • -dTextAlphaBits = 4 - khử răng cưa phông chữ.
  • -r300 - 300 dpi

9

Người ta cũng có thể sử dụng các tiện ích dòng lệnh có trong poppler-utilsgói:

sudo apt-get install poppler-utils
pdftoppm --help
pdftocairo --help

Thí dụ:

pdftocairo -png mypage.pdf mypage.png

1
Nó rất tốt. Nếu tệp PDF có nhiều trang thì sẽ có nhiều tệp PNG.
Tomasz Gandor

5

Không thể nhận được câu trả lời được chấp nhận để hoạt động. Sau đó, phát hiện ra rằng thực sự giải pháp đơn giản hơn nhiều vì Ghostscript không chỉ hỗ trợ PNG nguyên bản mà thậm chí còn có nhiều "mã hóa" khác nhau :

  • png256
  • png16
  • pnggray
  • pngmono
  • ...

Lệnh shell phù hợp với tôi là:

gs -dNOPAUSE -q -sDEVICE=pnggray -r500 -dBATCH -dFirstPage=2 -dLastPage=2 -sOutputFile=test.png test.pdf

Nó sẽ lưu trang 2 của test.pdf thành test.png bằng cách sử dụng pnggraymã hóa và 500 DPI.


2

Đây là một cuộc thảo luận bằng tiếng Đức về một vấn đề như thế này đối với tệp SVG, nơi nó được giải quyết bằng cách sử dụng

convert -background transparent

Có lẽ điều này cũng phù hợp với bạn.


Đáng buồn thay, điều đó không giải quyết được vấn đề của tôi. Nó thực sự là một hình ảnh trong PDF có kênh alpha nằm trên đầu mọi thứ.
Adam

2

Tôi sẽ thêm giải pháp của mình, thậm chí nghĩ rằng chủ đề của anh ấy đã cũ. Có lẽ điều này sẽ giúp ích cho ai đó.

Đầu tiên, tôi cần tạo tệp PDF. Tôi sử dụng XeLaTeX cho việc đó:

xelatex test.tex

Bây giờ, ImageMagickGraphicMagic đều phân tích cú pháp các tham số từ trái sang phải, vì vậy tham số ngoài cùng bên trái sẽ được thực thi đầu tiên. Tôi đã sử dụng trình tự này để xử lý tối ưu:

gm convert -trim -transparent white -background transparent -density 1200x1200 -resize 25% test.pdf test.png

Nó cho đồ họa đẹp trên nền trong suốt, được cắt tỉa theo những gì thực sự có trên trang. Các -density-resizethông số, cung cấp độ chi tiết tốt hơn và tăng độ phân giải tổng thể.

Tôi khuyên bạn nên kiểm tra xem có thể giảm mật độ cho bạn hay không. Nó sẽ cắt giảm thời gian chuyển đổi.


2

Đối với một tệp PDF mà ImageMagick đưa ra màu sắc không chính xác, tôi thấy rằng GraphicsMagick đã làm tốt hơn:

$ gm convert -quality 100 -thumbnail x300 -flatten journal.pdf\[0\] cover.jpg

Không có đủ thông tin để chắc chắn, nhưng điều này có thể là do không gian màu không được xác định chính xác. Kiểm tra tùy chọn IM-không gian màu.
rivimey

2

Vì trang này cũng liệt kê các công cụ thay thế, tôi sẽ đề cập đến xpdf có các công cụ dòng lệnh được biên dịch sẵn sàng cho Linux / Windows / Mac. Hỗ trợ tính minh bạch. Miễn phí cho mục đích sử dụng thương mại - trái ngược với Ghostscript có giá thực sự thái quá .

Trong một thử nghiệm trên một tệp PDF khổng lồ, nó nhanh hơn 7,5% so với Ghostscript.

(Nó cũng có trình chuyển đổi PDF sang văn bản và HTML)


Bây giờ tôi đã sử dụng cái này một thời gian và nó hoạt động tốt. Nói chung, nó chậm hơn một chút so với Ghostscript mặc dù ở độ phân giải cao hơn. Nhưng hình ảnh trông đẹp hơn nhiều (mặc dù tối hơn một chút) và tính năng khử răng cưa mà tôi có thể làm trong Ghostscript hoạt động tuyệt vời trong xpdf!
TheStoryCoder

2

Cố gắng trích xuất một trang duy nhất.

$ page = 4

gs -sDEVICE=pngalpha -dFirstPage="$page" -dLastPage="$page" -o thumb.png -r144 input.pdf

1

Giải pháp của tôi đơn giản và trực tiếp hơn nhiều. Ít nhất thì nó hoạt động theo cách đó trên PC của tôi (với các thông số kỹ thuật sau):

me@home: my.folder$ uname -a
Linux home 3.2.0-54-generic-pae #82-Ubuntu SMP Tue Sep 10 20:29:22 UTC 2013 i686 i686 i386 GNU/Linux

với

me@home: my.folder$ convert --version
Version: ImageMagick 6.6.9-7 2012-08-17 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2011 ImageMagick Studio LLC
Features: OpenMP

Vì vậy, đây là những gì tôi chạy trên file.pdf:

me@home: my.folder$ convert -density 300 -quality 100 file.pdf file.png

Vâng đây là những gì OP cố gắng ban đầu nhưng không thể có được một cái gì đó khác để err bên dưới làm việc khi ImageMagick cuộc gọi thông qua để GhostScript ... nhưng nếu nó hoạt động đi cho nó :)
rogerdpack

0

Bạn có thể sử dụng ImageMagick mà không cần tách trang đầu tiên của PDF bằng các công cụ khác. Cứ làm đi

convert -density 288 cover.pdf[0] -resize 25% cover.png


Ở đây tôi tăng mật độ danh nghĩa lên 400% (72 * 4 = 288) và sau đó thay đổi kích thước bằng 1/4 (25%). Điều này mang lại chất lượng tốt hơn nhiều cho png kết quả.

Tuy nhiên, nếu PDF là CMYK, PNG không hỗ trợ điều đó. Nó sẽ cần được chuyển đổi thành sRGB, đặc biệt nếu nó có độ trong suốt, vì Ghostscript không thể xử lý CMYK với alpha.

convert -density 288 -colorspace sRGB -resize 25% cover.pdf[0] cover.png
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.